I am in need of running some of the selected test cases from my test suite. Test cases are available in different test classes. Is it possible to create some custom annotation and configure junit to run only test cases with that annotation?
Please let me know if you have suggestions. Thanks
A TestSuite is a Composite of Tests. It runs a collection of test cases. Here is an example using the dynamic test definition.
TestSuite suite= new TestSuite();
suite.addTest(new MathTest("testAdd"));
suite.addTest(new MathTest("testDivideByZero"));
Alternatively, a TestSuite can extract the tests to be run automatically. To do so you pass the class of your TestCase class to the TestSuite constructor.
TestSuite suite= new TestSuite(MathTest.class);
This constructor creates a suite with all the methods starting with "test" that take no arguments.
A final option is to do the same for a large array of test classes.
Class[] testClasses = { MathTest.class, AnotherTest.class }
TestSuite suite= new TestSuite(testClasses);
Source: http://www.junit.org/apidocs/junit/framework/TestSuite.html
Related
I am developing a NiFi controller service, and this controller service has a property of another controller service which is dbcpservice.
Accoding to the source code in github.com/apache/nifi, controller service test depends on processor test too, that means define a TestProcessor which has a property of self-defined controller service, and then operate the the controller service through this processor.
But in my case, my controller service's property is another controller service(dbcpservice), I do not know how to write a junit test to set the controller service.
You can create a simple processor via anonymous inner classes (or named classes) in your test in order to exercise the behavior of your controller service. For example, DBCPServiceTest does this by defining TestProcessor alongside the test class. All that test processor needs is a property descriptor which accepts a controller service of the same type as the system under test (SUT) -- in this case, your custom controller service.
If you're asking how to configure your custom service (CustomService from here on), you pass parameters to the TestRunner instance, like so:
final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class);
final CustomService service = new CustomService();
service.setNestedService(new NestedService());
final Map<String, String> properties = new HashMap<String, String>();
runner.addControllerService("custom-service-id", service, properties);
In addition to Andy's answer - you could also create a test processor with Mockito:
AbstractProcessor processor = new Mockito().spy(AbstractProcessor.class);
TestRunner testRunner = TestRunners.newTestRunner(processor);
I need to execute some code before the #Before method of each unit test is executed. The problem is that I also need to know which test (the name is sufficient) will be executed afterwards.
I can either use AspectJ or Java Agents with bytecode manipulation to achieve this. Also the solution should work for tests where there is no #Before annotation present.
Any ideas?
EDIT: I can't modify the unit tests themselves, as I'm developing a framework for executing tests of other projects
You might want to look into the TestName rule in JUnit:
http://junit.org/junit4/javadoc/4.12/org/junit/rules/TestName.html
About the ordering, a solution could be to define a super class for your tests and put a #Before in there, as #Before methods in super classes are run before those in sub classes.
If you want to write a Java agent and you are not bound to Javassist or AspectJ, have a look at Byte Buddy for doing so. You can add the code in the MyAdvice class to any method annotated with #Test given that the type name ends with Test (as an example) by:
public class MyAgent {
public static void premain(String arg, Instrumentation inst) {
new AgentBuilder.Default()
.type(nameEndsWith("Test"))
.transform((type, cl, builder) -> builder.visit(Advice
.to(MyAdvice.class)
.on(isAnnotatedWith(Test.class)))
.installOn(instrumentation);
}
}
class MyAdvice {
#Advice.OnMethodEnter
static void enter() {
System.out.println("foo");
}
}
Just bundle the above code to a Javaagent with the proper manifest code and register it before running. If you are running on a JDK, you can also attach the agent programmatically using the byte-buddy-agent project.
I want to add a JUnit 4 test to a legacy project which uses JUnit 3 test suites ("AllTests") to organize the tests.
The tests are already executed with JUnit 4, so I know that JUnit 4 tests work in principle. I just forgot how to add the JUnit 4 test class to the junit.framework.TestSuite instance. Anyone with the code snippet?
It's as easy as this:
public static Test suite() {
TestSuite suite = new TestSuite("suite name");
suite.addTestSuite(JUnit3Test.class);
suite.addTest(new JUnit4TestAdapter(JUnit4Test.class)); // <--
return suite;
}
I know in Junit, the class extend TestCase cannot support #Before and #After. But it still allow to use #Test?
I know without #Test, if we want to run this class, we could override the runTest method and define the method to be invoked. This is not convenient. Because if we mark the #Test in method of this class., it could run directly. Can anyone tell me the mechanism about how to invoke the method with #Test about this class?
By the way, If I want put a lot of tests into a TestSuite, Should I choose a class extend TestCase or define a arbitrary class with #Test as the Single Test Class ?
The TestCase class is from Junit 3 and should not be used in Junit 4 + classes.
If you extend TestCase, and use the Junit 3 Test runners then your test method names need to start with the word "test". (Junit 3 test runners use Java reflection to find and invoke all methods that start with the word "test")
Relying on TestClass hindered test class designs because you were forced to extend that class which made somethings hard to test. There also wasn't anything equivalent to Junit4's #BeforeClass or #AfterClass which meant you had to do all the more complicated multi-test fixture set up and tear down yourself.
To run many Junit4 test classes at once as a Test Suite, you can create a new empty class with the #RunWith and #SuiteClasses annotations as shown below:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses(
{
TestClassA.class,
TestClassB.class
}
)
public class MyTestSuite{
}
I have a test suite and a number of test in there own class files. These are selenium webdriver tests. Each test needs to start the webdriver before they start. How should this be done?
I can have the suite start the webdriver fine from its #BeforeClass. But when i try to run a single test from eclipse the webdriver doesnt start. The tests dont know that they are part of the suite and should run the suites #BeforeClass.
The single Tests would only run the #BeforeClass of the suite if their class extends the suite.
Due to the fact that that's a senseless relationship I think the solution for your Problem is either to define a BeforeClass in something like a TestFunctions.java file as Superclass for all Testclasses or create BeforeClasses for every single Testclass.
Keep in mind that the #BeforeClass and #Before Annotations of the superclass are executed before the #Before(Class) of the subclass but can be overridden.