In eclipse, with JUnit 4, you can right click a project or package and click Run as JUnit Test, and it will run all the JUnit tests within that grouping. Is there a way to do this same thing from within the code?
You can use packages in junit such as JUnitCore like this:
public static void main(String[] args){
List tests = new ArrayList();
tests.add(TestOne.class);
tests.add(TestTwo.class);
for (Class test : tests){
runTests(test);
}
}
private static void runTests(Class test){
Result result = JUnitCore.runClasses(test);
for (Failure failure : result.getFailures()){
System.out.println(failure.toString());
}
}
Use JUnit Suite:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
// Put your Test Case Class here
#Suite.SuiteClasses({
JunitTest1.class,
JunitTest2.class,
JunitTest3.class
})
public class JunitTestSuite {}
Then create a main method to run it.
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class JunitTestSuiteRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure fail : result.getFailures()) {
System.out.println(fail.toString());
}
if (result.wasSuccessful()) {
System.out.println("All tests finished successfully...");
}
}}
JUnit provides the test Suite. Give that a try.
[...]
public class TestCaseA {
#Test
public void testA1() {
// omitted
}
}
[...]
public class TestCaseB {
#Test
public void testB1() {
// omitted
}
}
[...]
#RunWith(value=Suite.class)
#SuiteClasses(value = {TestCaseA.class})
public class TestSuiteA {
}
[...]
#RunWith(value=Suite.class)
#SuiteClasses(value = {TestCaseB.class})
public class TestSuiteB {
}
[...]
#RunWith(value = Suite.class )
#SuiteClasses(value = {TestSuiteA.class, TestSuiteB.class})
public class MasterTestSuite{
}
Related
I have got a requirement to get the list of all the scenarios that are to be executed based on the tag I provided in cucumber Test runner. However I have to get this list before tests start execution.
I know there is a tag called "#BeforeClass" but I am not sure if I can use to get the list of all the scenarios that are going to be run. For example something like this
#BeforeClass
public void intialize(Scenario[] scenario) throws Exception { }
Below is the code for me test runner class
package com.automation.cucumber;
import com.automation.Utils;
import io.cucumber.java.Scenario;
import io.cucumber.testng.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import java.io.File;
#CucumberOptions(features = "features/amazon"
,glue="com.automation.cucumber"
,tags = "#tt"
,dryRun = true
, plugin = {"json:target/cucumber-reports/cucumber.json"})
public class CucumberTestRunner extends AbstractTestNGCucumberTests {
static String resultFolder;
#DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
#BeforeClass
public void intialize() throws Exception {
resultFolder = Utils.createTestReportFolder();
if(resultFolder==null)
{
throw new Exception("Unable to create a result folder");
}
System.out.println();
}
}
You may have to implement EventListener class to get that information and do dryRun = true in your Runner class in #CucumberOptions
Quoting from a question that can help you achieve what you need
public class DryRunPlugin implements EventListener {
#Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestCaseStarted.class, this::handleCaseStarted);
}
private void handleCaseStarted(TestCaseStarted event) {
System.out.println(event.getTestCase().getUri());
System.out.println(event.getTestCase().getName());
System.out.println(event.getTestCase().getScenarioDesignation());
event.getTestCase().getTags().stream().forEach(t ->
System.out.println(t.getName()));
}
}
I implemented a JUnit 4 TestRule (extending an ExternalResource), and injected it as a #ClassRule in my test class: I want to initialize a resource once for all in every test of this class, and tear it down eventually.
My issue is that my #Before and #After rule-methods are not called at all before/after my #Test method: any idea why this is happening?
Minimal compilable example:
package com.acme.test;
import static org.junit.Assert.assertNull;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
class Coffee {
public void throwAway() {}
}
class CoffeeMachine extends ExternalResource {
Coffee whatElse;
#Override protected void before() throws Throwable {
whatElse = new Coffee();
}
#Override protected void after() {
whatElse.throwAway();
}
public Coffee gimmieCoffee() { return whatElse; }
}
public class CoffeeTester {
#ClassRule public static CoffeeMachine CM = new CoffeeMachine();
#Test public void drinkACoffee() {
Coffee c = CM.gimmieCoffee();
assertNull(c); // ---> Coffee is null!! (fuuuuuuuuuu...)
}
}
Is there something I am misunderstanding here? Note that the same happens with a non-static #Rule.
I am using JUnit 4.11.
Thank you very much for any hint.
I think this is a problem with your test runner. Maybe some plugin has installed a custom runner which is used when you run your tests from Ecilpse?
Check the run configuration for your test and make sure that the standard JUnit 4 test runner is used:
I see no issue here, but just a misunderstanding. First of all, let's read assert as it must be and change your code a bit (it is obvious your test says c must not be null which gives us: assertNotNull(c);
I've also added some output in order to show you what is going on. Please try to run it.
package com.acme.test;
import static org.junit.Assert.assertNotNull;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
class Coffee {
public void throwAway() {}
}
class CoffeeMachine extends ExternalResource {
Coffee whatElse;
#Override protected void before() throws Throwable {
whatElse = new Coffee();
System.out.println(" ### executing before: " + whatElse);
}
#Override protected void after() {
whatElse.throwAway();
}
public Coffee gimmieCoffee() { return whatElse; }
}
public class CoffeeTester {
#ClassRule public static CoffeeMachine CM = new CoffeeMachine();
#Test public void drinkACoffee() {
Coffee c = CM.gimmieCoffee();
System.out.println(" ### executing test: " + c);
assertNotNull(c);
}
}
For me it gives the following:
### executing before: com.acme.test.Coffee#28f67ac7
[VerboseTestNG] INVOKING: "com.acme.test.CoffeeTester" - com.acme.test.CoffeeTester.drinkACoffee()
### executing test: com.acme.test.Coffee#28f67ac7
[VerboseTestNG] PASSED: "com.acme.test.CoffeeTester" - com.acme.test.CoffeeTester.drinkACoffee() finished in 4 ms
[VerboseTestNG]
[VerboseTestNG] ===============================================
[VerboseTestNG] com.acme.test.CoffeeTester
[VerboseTestNG] Tests run: 1, Failures: 0, Skips: 0
[VerboseTestNG] ===============================================
So c is not null as you expect it to be.
I'm developing custom runner of JUnit for internal purposes and, for instance, I've introduced custom annotation for test methods which on applying should make my runner to run method with this annotation after all other test methods without this annotation.
I want to write junit test to verify behavior of my custom runner.
Test class:
public class TestClass {
#Test
#CustomAnnotation
public void test1() {
System.out.println("test1");
}
#Test
public void test2() {
System.out.println("test2");
}
}
An abstract code that will test my runner:
public class MyCustomRunnerTest {
#Test
public void order() throws InitializationError {
// Arrange
// Some code of mocking library might be placed here
// Act
MyCustomRunner runner = new MyCustomRunner(TestClass.class);
runner.run(new RunNotifier());
// Assert
// Here I want to verify that method test1() has been called
// after method test2()
}
}
Is there any mocking libraries that will allow me to perform such verification? Or may be is there any other way to check that?
Why do you not extract the logic that determines the run order of test methods into a separate class or method? This method should return a list of test method names (or other descriptors) in order in which they will run. Then your testing will come down to passing it the test class and asserting that the output is { "test2", "test1" }. No mocking required.
A Better Solution
Use RunListener to log test methods as they are being run by your runner. You of course will have your own MyCustomRunner class, but the rest of the code can stay as in the example below:
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
#RunWith(BlockJUnit4ClassRunner.class)
public class RunnerTest {
// dummy "custom" test runner
public static class MyCustomRunner extends BlockJUnit4ClassRunner {
public MyCustomRunner(Class<?> klass) throws InitializationError {
super(klass);
}
}
public static class TestClass {
#Test
public void test1() {}
#Test
public void test2() {}
}
#Test
public void myCustomRunnerExecutesTestsInOrder() throws InitializationError {
RunNotifier notifier = new RunNotifier();
Collection<String> runTestMethods = new ArrayList<>();
notifier.addListener(new RunListener() {
#Override
public void testStarted(Description description) throws Exception {
runTestMethods.add(description.getMethodName());
}
});
new MyCustomRunner(TestClass.class).run(notifier);
// assert that the collection contains methods names in the specified order
assertThat(runTestMethods, contains("test1", "test2"));
}
}
The code is posted at link
now when i am trying to write the junit for
first case i am getting the error
"need to replay the class B ".
but same junit is working for the second case.
my junit is
#RunWith(PowerMockRunner.class)
public class TestClass {
#Test
public void testDoSomeThing() {
B b = createMock(B.class)
expectNew(b.CallMe()).andReturns(xxx)
A a=new A();
replayAll();
a.doSomething();
verifyAll();
}
}
Here's a solution using EasyMock with PowerMock :
TestClass.java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest({ A.class, B.class })
public class TestClass {
#Test
public void testDoSomeThing() throws Exception {
/* Setup */
B bMock = PowerMock.createMock(B.class);
/* Mocks */
PowerMock.expectNew(B.class).andReturn(bMock).atLeastOnce();
bMock.callMe();
/* Activate */
PowerMock.replayAll();
/* Test */
A cut = new A();
cut.doSomething();
/* Asserts */
PowerMock.verifyAll();
}
}
A.java
public class A {
B b = new B();
public void doSomething() {
b.callMe();
}
}
B.java
public class B {
public void callMe() {
}
}
You forgot to add
#PrepareForTest({A.class, B.class})
This annotation must have the classes you are mocking and the classes that will use these mocks.
I would like to create a junit test suite using JUnit 4 where the names of the test classes to be included are not known until the test suite is run.
In JUnit 3 I could do this:
public final class MasterTester extends TestCase
{
/**
* Used by junit to specify what TestCases to run.
*
* #return a suite containing what TestCases to run
*/
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for(Class<?> klass : gatherTestClasses()) {
suite.addTestSuite(klass);
}
return suite;
}
}
and let the gatherTestClasses() method deal with figuring out what test classes to run.
In JUnit 4, the documentation says to use an annotation: #SuiteClasses({TestClass1.class, TestClass2.class...}) to build up my test suite. There are numerous SO answers showing how to do this. Unfortunately the examples I see do not seem to allow for passing a dynamically generated list of TestClasses.
This SO answer suggested I would have to subclass BlockJUnit4ClassRunner which I do not want to do.
Dynamically specified test suites seem like something that must be in JUnit 4 somewhere. Does anyone know where?
To create a dynamic test suite, you need to use the #RunWith annotation. There are two common ways to use it:
#RunWith(Suite.class)
This allows you to specify, which classes compose the test suite in question. This is equivalent to the JUnit 3 style:
import junit.framework.TestSuite;
import junit.framework.TestCase;
public final class MasterTester extends TestCase {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(TestClass1.class);
suite.addTestSuite(TestClass2.class);
// etc...
return suite;
}
}
The equivalent JUnit 4 class will be:
import org.junit.runners.Suite;
#RunWith(Suite.class)
#SuiteClasses({TestClass1.class, TestClass2.class})
public final class MasterTester {
}
#RunWith(AllTests.class)
This allows you to dynamically specify the tests, which compose the test suite. If your tests are not known until runtime, you cannot specify them in the annotations. You can use this construction instead. So, if the JUnit 3 code is:
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.framework.Test;
public final class MasterTester extends TestCase {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for (Test test : findAllTestCasesRuntime()) {
suite.addTest(test);
}
return suite;
}
}
The equivalent JUnit 4 code will be:
import org.junit.runners.AllTests;
import junit.framework.TestSuite;
import junit.framework.Test;
#RunWith(AllTests.class)
public final class MasterTester {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
for (Test test : findAllTestCasesRuntime()) {
suite.addTest(test);
}
return suite;
}
}
I've tried this using JUnit 4.8 and it works:
#RunWith(AllTests.class)
public class SomeTests
{
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(Test1.class));
suite.addTest(new JUnit4TestAdapter(Test2.class));
return suite;
}
}
I found Classpath suite quite useful when used with a naming convention on my test classes.
https://github.com/takari/takari-cpsuite
Here is an example:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
#RunWith(ClasspathSuite.class)
#ClassnameFilters({".*UnitTest"})
public class MySuite {
}
I'm not sure what gatherTestClasses() does, but let's say it returns some tests when the OS is Linux and different tests when the OS is Windows. You can replicate that in JUnit 4.4 with assumptions:
#Test
public void onlyOnLinux() {
assumeThat(getOS(), is(OperatingSystem.LINUX));
// rest of test
}
#Test
public void onlyOnWindows() {
assumeThat(getOS(), is(OperatingSystem.WINDOWS));
// rest of test
}
#Test
public void anyOperatingSystem() {
// just don't call assumeThat(..)
}
The implementation of getOS() and OperatingSystem being your custom code.
Here is a Complete example how to implement that. it combines of two testCase classes and one suite.
ExampleInstrumentedTest:
import android.support.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
#RunWith(JUnit4.class)
public class ExampleInstrumentedTest {
#Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
#Test
public void checkInputs() throws Exception {
}
}
ExampleInstrumentedTest2:
import android.support.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
#RunWith(JUnit4.class)
public class ExampleInstrumentedTest2 {
#Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
#Test
public void checkInputs() throws Exception {
}
}
ExampleInstrumentedSuite:
import junit.framework.TestSuite;
import org.junit.runner.RunWith;
import org.junit.runners.AllTests;
#RunWith(AllTests.class)
public class ExampleInstrumentedSuite {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest.class));
suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest2.class));
return suite;
}
}
Note that you should use #RunWith(JUnit4.class) instead of default #RunWith(AndroidJUnit4.class) in testCase Class
public class MyTestCase extends TestCase {
#Override
public void runTest() {
// define assertion here <===
assertEquals("yes", "yes");
}
}
#RunWith(AllTests.class)
public class DynamicTestSuite {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
// dynamically create your test case here <====
suite.addTest(new MyTestCase());
return suite;
}
}
Expanding on #kissLife's answer, here's a something you can paste and run that creates multiple tests on the fly:
import junit.framework.TestCase;
import junit.framework.TestSuite;
public final class TestJunit4DynamicConstruction {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
suite.addTest(new CompareInts(1, 1));
suite.addTest(new CompareInts(2, 2));
suite.addTest(new CompareInts(2, 1)); // huh, for some reason, 2 != 1
suite.addTest(new CompareInts(1, 1));
return suite;
}
static public class CompareInts extends TestCase {
private final int got;
private final int expected;
CompareInts(int got, int expected) {
super(Integer.toString(got) + ":" + Integer.toString(expected));
this.got = got;
this.expected = expected;
}
#Override
public void runTest() {
assertEquals(got, expected);
}
}
}
You'll run these tests:
TestJunit4DynamicConstruction$CompareInts.1:1
TestJunit4DynamicConstruction$CompareInts.2:2
TestJunit4DynamicConstruction$CompareInts.2:1
TestJunit4DynamicConstruction$CompareInts.1:1
TestJunit4DynamicConstruction$CompareInts
and get this error:
junit.framework.AssertionFailedError:
Expected :2
Actual :1
...
TestJunit4DynamicConstruction$CompareInts.runTest(TestJunit4DynamicConstruction.java:26)
...
Process finished with exit code 255