Cucumber 4: Implement Global Hooks - java

I'm new to Cucumber BDD testing v4.1.
Questions:
How to impelement before(setup) method in Cucumber 4 (DAO, Spring)?
Please help. Thanks.

Cucumber Hooks – Where to use #Before
#Before, in its most basic usage, allows you to run a block of code before every scenario. Normally in Cucumber, we tend to do the initialization related things – such as object initialization, data setup etc in the Given statement. Because of this a lot of people don’t see the need of using Cucumber’s #Before. But you can use #Before to make in an entry in your reporting that a new scenario is being executed. Since #Before always runs before every scenario, you can use this in your reports to clearly depict when a scenario starts executing.
It’s not necessary that you add #Before in each feature file. Just add it in any one feature file and let Cucumber do its job. Cucumber will figure out where you have saved #Before and then it will use it before all the scenarios. To make your reporting bit more useful and easy to understand, you can actually write the scenario name as well in the report. The Java code for this is given below –
#Before
public void before(Scenario scenario) {
System.out.println("------------------------------");
System.out.println("Starting - " + scenario.getName());
System.out.println("------------------------------");
}
Cucumber API provides an Interface called Scenario, using which you can get can instance of this class. In the above code, we have just used the getName() method of this interface to print the scenario name in our log.
Test Hooks with Single Scenario (Example):
Feature File
Feature: Test Hooks
Scenario: This scenario is to test hooks functionality
Given this is the first step
When this is the second step
Then this is the third step
Step Definitions:
package stepDefinition;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class Hooks_Steps {
#Given("^this is the first step$")
public void This_Is_The_First_Step(){
System.out.println("This is the first step");
}
#When("^this is the second step$")
public void This_Is_The_Second_Step(){
System.out.println("This is the second step");
}
#Then("^this is the third step$")
public void This_Is_The_Third_Step(){
System.out.println("This is the third step");
}
}
Hooks
package utilities;
import cucumber.api.java.After;
import cucumber.api.java.Before;
public class Hooks {
#Before
public void beforeScenario(){
System.out.println("This will run before the Scenario");
}
#After
public void afterScenario(){
System.out.println("This will run after the Scenario");
}
}
EDIT:
Workaround mentioned in Issue #515 and elsewhere is to use JUnit‘s #BeforeClass and #AfterClass annotations in the runner class, like this:
#RunWith(Cucumber.class)
#Cucumber.Options(format = {
"html:target/cucumber-html-report",
"json-pretty:target/cucumber-json-report.json"})
public class HooksTest {
#BeforeClass
public static void setup() {
System.out.println("Ran the before");
}
#AfterClass
public static void teardown() {
System.out.println("Ran the after");
}
}
Note: While #BeforeClass and #AfterClass may look like the cleanest solution at first, they are not very practical to use. They work only when Cucumber-JVM is set to use the JUnit runner. Other runners, like TestNG, the command line runner, and special IDE runners, won’t pick up these hooks. Their methods must also be are static and would need static variables or singletons to share data anyway.
to run JUnit test cases from the command line

I got the answers already which is implement ConcurrentEventListener.

Related

Java code is not printing from start to end [duplicate]

I want to execute test methods which are annotated by #Test in specific order.
For example:
public class MyTest {
#Test public void test1(){}
#Test public void test2(){}
}
I want to ensure to run test1() before test2() each time I run MyTest, but I couldn't find annotation like #Test(order=xx).
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
I'm not sure there is a clean way to do this with JUnit, to my knowledge JUnit assumes that all tests can be performed in an arbitrary order. From the FAQ:
How do I use a test fixture?
(...) The ordering of test-method invocations is not guaranteed, so testOneItemCollection() might be executed before testEmptyCollection(). (...)
Why is it so? Well, I believe that making tests order dependent is a practice that the authors don't want to promote. Tests should be independent, they shouldn't be coupled and violating this will make things harder to maintain, will break the ability to run tests individually (obviously), etc.
That being said, if you really want to go in this direction, consider using TestNG since it supports running tests methods in any arbitrary order natively (and things like specifying that methods depends on groups of methods). Cedric Beust explains how to do this in order of execution of tests in testng.
If you get rid of your existing instance of Junit, and download JUnit 4.11 or greater in the build path, the following code will execute the test methods in the order of their names, sorted in ascending order:
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
#Test
public void testAcreate() {
System.out.println("first");
}
#Test
public void testBupdate() {
System.out.println("second");
}
#Test
public void testCdelete() {
System.out.println("third");
}
}
Migration to TestNG seems the best way, but I see no clear solution here for jUnit. Here is most readable solution / formatting I found for jUnit:
#FixMethodOrder( MethodSorters.NAME_ASCENDING ) // force name ordering
public class SampleTest {
#Test
void stage1_prepareAndTest(){};
#Test
void stage2_checkSomething(){};
#Test
void stage2_checkSomethingElse(){};
#Test
void stage3_thisDependsOnStage2(){};
#Test
void callTimeDoesntMatter(){}
}
This ensures stage2 methods are called after stage1 ones and before stage3 ones.
P.S. I feel this approach is better that jUnit 5.5 #Order annotation because it provides better notation for reader.
If the order is important, you should make the order yourself.
#Test public void test1() { ... }
#Test public void test2() { test1(); ... }
In particular, you should list some or all possible order permutations to test, if necessary.
For example,
void test1();
void test2();
void test3();
#Test
public void testOrder1() { test1(); test3(); }
#Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }
#Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }
Or, a full test of all permutations:
#Test
public void testAllOrders() {
for (Object[] sample: permute(1, 2, 3)) {
for (Object index: sample) {
switch (((Integer) index).intValue()) {
case 1: test1(); break;
case 2: test2(); break;
case 3: test3(); break;
}
}
}
}
Here, permute() is a simple function which iterates all possible permuations into a Collection of array.
JUnit since 5.5 allows #TestMethodOrder(OrderAnnotation.class) on class and #Order(1) on test-methods.
JUnit old versions allow test methods run ordering using class annotations:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#FixMethodOrder(MethodSorters.JVM)
#FixMethodOrder(MethodSorters.DEFAULT)
By default test methods are run in alphabetical order. So, to set specific methods order you can name them like:
a_TestWorkUnit_WithCertainState_ShouldDoSomething
b_TestWorkUnit_WithCertainState_ShouldDoSomething
c_TestWorkUnit_WithCertainState_ShouldDoSomething
Or
_1_TestWorkUnit_WithCertainState_ShouldDoSomething
_2_TestWorkUnit_WithCertainState_ShouldDoSomething
_3_TestWorkUnit_WithCertainState_ShouldDoSomething
You can find examples here.
Its one of the main issue which I faced when I worked on Junit and I came up with following solution which works fine for me:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
Collections.sort(copy, new Comparator<FrameworkMethod>() {
#Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return -1;
}
return o1.order() - o2.order();
}
});
return copy;
}
}
also create a interface like below:
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD})
public #interface Order {
public int order();
}
Now suppose you have class A where you have written several test cases like below:
(#runWith=OrderRunner.class)
Class A{
#Test
#Order(order = 1)
void method(){
//do something
}
}
So execution will start from method named "method()".
Thanks!
JUnit 5 update (and my opinion)
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
By default, unit testing libraries don't try to execute tests in the order that occurs in the source file.
JUnit 5 as JUnit 4 work in that way. Why? Because if the order matters it means that some tests are coupled between them and that is undesirable for unit tests.
So the #Nested feature introduced by JUnit 5 follows the same default approach.
But for integration tests, the order of the test method may matter since a test method may change the state of the application in a way expected by another test method.
For example when you write an integration test for a e-shop checkout processing, the first test method to be executed is registering a client, the second is adding items in the basket and the last one is doing the checkout. If the test runner doesn't respect that order, the test scenario is flawed and will fail.
So in JUnit 5 (from the 5.4 version) you have all the same the possibility to set the execution order by annotating the test class with #TestMethodOrder(OrderAnnotation.class) and by specifying the order with #Order(numericOrderValue) for the methods which the order matters.
For example :
#TestMethodOrder(OrderAnnotation.class)
class FooTest {
#Order(3)
#Test
void checkoutOrder() {
System.out.println("checkoutOrder");
}
#Order(2)
#Test
void addItemsInBasket() {
System.out.println("addItemsInBasket");
}
#Order(1)
#Test
void createUserAndLogin() {
System.out.println("createUserAndLogin");
}
}
Output :
createUserAndLogin
addItemsInBasket
checkoutOrder
By the way, specifying #TestMethodOrder(OrderAnnotation.class) looks like not needed (at least in the 5.4.0 version I tested).
Side note
About the question: is JUnit 5 the best choice to write integration tests? I don't think that it should be the first tool to consider (Cucumber and co may often bring more specific value and features for integration tests) but in some integration test cases, the JUnit framework is enough. So that is a good news that the feature exists.
The (as yet unreleased) change https://github.com/junit-team/junit/pull/386 introduces a #SortMethodsWith. https://github.com/junit-team/junit/pull/293 at least made the order predictable without that (in Java 7 it can be quite random).
Look at a JUnit report. JUnit is already organized by package. Each package has (or can have) TestSuite classes, each of which in turn run multiple TestCases. Each TestCase can have multiple test methods of the form public void test*(), each of which will actually become an instance of the TestCase class to which they belong. Each test method (TestCase instance) has a name and a pass/fail criteria.
What my management requires is the concept of individual TestStep items, each of which reports their own pass/fail criteria. Failure of any test step must not prevent the execution of subsequent test steps.
In the past, test developers in my position organized TestCase classes into packages that correspond to the part(s) of the product under test, created a TestCase class for each test, and made each test method a separate "step" in the test, complete with its own pass/fail criteria in the JUnit output. Each TestCase is a standalone "test", but the individual methods, or test "steps" within the TestCase, must occur in a specific order.
The TestCase methods were the steps of the TestCase, and test designers got a separate pass/fail criterion per test step. Now the test steps are jumbled, and the tests (of course) fail.
For example:
Class testStateChanges extends TestCase
public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()
Each test method asserts and reports its own separate pass/fail criteria.
Collapsing this into "one big test method" for the sake of ordering loses the pass/fail criteria granularity of each "step" in the JUnit summary report. ...and that upsets my managers. They are currently demanding another alternative.
Can anyone explain how a JUnit with scrambled test method ordering would support separate pass/fail criteria of each sequential test step, as exemplified above and required by my management?
Regardless of the documentation, I see this as a serious regression in the JUnit framework that is making life difficult for lots of test developers.
Not sure I agree, If I want to test 'File Upload' and then test 'Data Inserted by File Upload' why would I not want these to be independent from each other? Perfectly reasonable I think to be able to run them separately rather than having both in a Goliath test case.
What you want is perfectly reasonable when test cases are being run as a suite.
Unfortunately no time to give a complete solution right now, but have a look at class:
org.junit.runners.Suite
Which allows you to call test cases (from any test class) in a specific order.
These might be used to create functional, integration or system tests.
This leaves your unit tests as they are without specific order (as recommended), whether you run them like that or not, and then re-use the tests as part of a bigger picture.
We re-use/inherit the same code for unit, integration and system tests, sometimes data driven, sometimes commit driven, and sometimes run as a suite.
JUnit 4 update
As of JUnit 4.13 #OrderWith, it is possible to reproduce the JUnit 5 #Order annotation. This solution better integrates with JUnit 4 than #RunWith a custom BlockJUnit4ClassRunner implementation.
Here's how I could replace method name ordering (#FixMethodOrder(MethodSorters.NAME_ASCENDING)) with an ordering by annotation.
#OrderWith(OrderAnnotation.class)
public class MyTest {
#Test
#Order(-1)
public void runBeforeNotAnnotatedTests() {}
#Test
public void notAnnotatedTestHasPriority0() {}
#Test
#Order(1)
public void thisTestHasPriority1() {}
#Test
#Order(2)
public void thisTestHasPriority2() {}
}
/**
* JUnit 4 equivalent of JUnit 5's {#code org.junit.jupiter.api.Order}
*/
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD })
public #interface Order {
/**
* Default order value for elements not explicitly annotated with {#code #Order}.
*
* #see Order#value
*/
int DEFAULT = 0;
/**
* The order value for the annotated element.
* <p>Elements are ordered based on priority where a lower value has greater
* priority than a higher value. For example, {#link Integer#MAX_VALUE} has
* the lowest priority.
*
* #see #DEFAULT
*/
int value();
}
import org.junit.runner.Description;
import org.junit.runner.manipulation.Ordering;
import org.junit.runner.manipulation.Sorter;
/**
* Order test methods by their {#link Order} annotation. The lower value has the highest priority.
* The tests that are not annotated get the default value {#link Order#DEFAULT}.
*/
public class OrderAnnotation extends Sorter implements Ordering.Factory {
public OrderAnnotation() {
super(COMPARATOR);
}
#Override
public Ordering create(Context context) {
return this;
}
private static final Comparator<Description> COMPARATOR = Comparator.comparingInt(
description -> Optional.ofNullable(description.getAnnotation(Order.class))
.map(Order::value)
.orElse(Order.DEFAULT));
}
The not annotated tests get a default priority of 0. The order of tests with the same priority is undetermined.
Gist: https://gist.github.com/jcarsique/df98e0bad9e88e8258c4ab34dad3c863
Inspired by:
Aman Goel's answer
Test execution order Wiki by JUnit team
JUnit 5 source code
See my solution here:
"Junit and java 7."
In this article I describe how to run junit tests in order - "just as in your source code".
Tests will be run, in order as your test methods appears in class file.
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
But as Pascal Thivent said, this is not a good practise.
As others have stated, tests should be ideally be independent of execution order. This makes tests less fragile, and allows them to be run independently (many IDEs allow you to select a test method and execute it independently of other tests).
That being said, for integration tests, some people prefer to rely on method ordering.
Starting with JUnit 4.13 you can define your own class to reorder tests by extending Ordering. See the JUnit wiki for more details. Here's an example using the built-in Alphanumeric class to order the tests alphanumerically using the test method name:
import org.junit.Test;
import org.junit.runner.OrderWith;
import org.junit.runner.manipulation.Alphanumeric;
#OrderWith(Alphanumeric.class)
public class TestMethodOrder {
#Test
public void testA() {
System.out.println("first");
}
#Test
public void testB() {
System.out.println("second");
}
#Test
public void testC() {
System.out.println("third");
}
}
For JUnit 4, putting this annotation on the test class solved the problem.
#FixMethodOrder(MethodSorters.JVM)
With JUnit 5.4, you can specify the order :
#Test
#Order(2)
public void sendEmailTestGmail() throws MessagingException {
you just need to annotate your class
#TestMethodOrder(OrderAnnotation.class)
https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-execution-order
i'm using this in my project and it works very well !
You can use one of these piece of codes:
#FixMethodOrder(MethodSorters.JVM) OR #FixMethodOrder(MethodSorters.DEFAULT) OR #FixMethodOrder(MethodSorters.NAME_ASCENDING)
Before your test class like this:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest {...}
It's time to move to Junit5.
Here is a sample of what we could get:
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderedTests {
#Test
#Order(1)
void nullValues() {}
#Test
#Order(2)
void emptyValues() {}
#Test
#Order(3)
void validValues() {}
}
For Junit4, copy the logic that you have in several tests in one test method.
I've read a few answers and agree its not best practice, but the easiest way to order your tests - and the way that JUnit runs tests by default is by alphabetic name ascending.
So just name your tests in the alphabetic order that you want. Also note the test name must begin
with the word test. Just watch out for numbers
test12 will run before test2
so:
testA_MyFirstTest
testC_ThirdTest
testB_ATestThatRunsSecond
Please check out this one: https://github.com/TransparentMarket/junit. It runs the test in the order they are specified (defined within the compiled class file). Also it features a AllTests suite to run tests defined by sub package first. Using the AllTests implementation one can extend the solution in also filtering for properties (we used to use #Fast annotations but those were not published yet).
Here is an extension to JUnit that can produce the desired behavior: https://github.com/aafuks/aaf-junit
I know that this is against the authors of JUnit philosophy, but when using JUnit in environments that are not strict unit testing (as practiced in Java) this can be very helpful.
I ended up here thinking that my tests weren't run in order, but the truth is that the mess was in my async jobs. When working with concurrency you need to perform concurrency checks between your tests as well.
In my case, jobs and tests share a semaphore, so next tests hang until the running job releases the lock.
I know this is not fully related to this question, but maybe could help targeting the correct issue
If you want to run test methods in a specific order in JUnit 5, you can use the below code.
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MyClassTest {
#Test
#Order(1)
public void test1() {}
#Test
#Order(2)
public void test2() {}
}

How to reuse method and test in JUnit?

I've tried to avoid duplicate code in JUnit test, but I'm kind of stuck.
This is my first test, for the second one it has exactly the same methods but different service (different input). instead of the TestCaseResourceTest1 I have TestCaseResourceTest2. Now what could be the proper way to test both? I want to have a separate file for test number 2, how should I avoid the duplicate code? (ex. use the beforeFileTest() method)
public class TestCaseResourceTest1 {
#Mock
private TestService testService;
#Mock
private AreaService areaService;
private TestCaseService1 testCaseService1; // is changed in test2
#Before
public void before() throws Exception{
testCaseService1 = mock(TestCaseService1.class); // is changed in test2
MockitoAnnotations.initMocks(this);
beforeFileTest();
}
private void beforeFileTest() throws Exception{
doReturn(true).when(areaService).chechExists(any(String.class), eq(false));
}
#Test
public void verifyFileExists() throws Exception{
verifyOtherArea(testCaseService1); // is changed in test2
doReturn(false).when(areaService).chechExists(any(String.class), eq(false));
}
}
just lines with comment is changed in test2 are differences.
Tnx
Given this excerpt from your question:
… instead of the TestCaseResourceTest1 I have TestCaseResourceTest2 … I want to have a separate file for test number 2
… the standard ways of sharing code between test cases are:
Create a Test Suite and include the shared code in the test suite (typically in #BeforeClass and #AfterClass methods). This allows you to (1) run setup code once (per suite invocation); (2) encapsulate shared setup/teardown code and (3) easily add more tests cases later. For example:
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestCaseResourceTest1.class,
TestCaseResourceTest2.class
)}
public class TestSuiteClass {
#BeforeClass
public void setup() {
beforeFileTest();
}
private void beforeFileTest() throws Exception {
// ...
}
}
Create an abstract class which parents TestCaseResourceTest1 and TestCaseResourceTest2 and let those test cases call the shared code in the parent (typically via super() calls). With this approach you can declare default shared code in the parent while still allowing sub classes to (1) have their own behaviour and (2) selectively override the parent/default behaviour
Create a custom JUnit runner, define the shared behaviour in this runner and then annotate the relevant test cases with #RunWith(YourCustomRunner.class). More details on this approach here
Just to reiterate what some of the other posters have said; this is not a common first step so you may prefer to start simple and only move to suites or abstract classes or custom runners if your usage provides a compelling reason to do so.
I had the such situation and it was a sign about wrong implementation design. We are talking about pure unit tests where we test exactly what is implemented in the production classes. If we need duplicated tests it means we probably have duplication in implementation.
How did I resolve it in my project?
Extracted common logic into parent service class and implemented unit tests for it.
For child services I implemented tests only for particular implemented code there. No more.
Implemented an integration tests on real environment were both services were involved and tested completely.
Assuming you want to have the exact same test run for 2 different classes (and not mocking it as in your example code), you can create an abstract test class, that has abstract method that returns an instance of the class to be tested.
Something in the vein of:
public abstract class TestCaseResourceTest {
protected abstract TestCaseService1 getServiceToTest();
#Before
public void before() throws Exception {
testCaseService1 = getServiceToTest();
MockitoAnnotations.initMocks(this);
beforeFileTest();
}
#Test
public void test() {
// do your test here
}
}
public class ConcreteTest extends TestCaseResourceTest {
protected TestCaseService1 getServiceToTest() {
return new TestCaseService();
}
}
public class ConcreteTest2 extends TestCaseResourceTest {
protected TestCaseService1 getServiceToTest() {
return new DifferentService();
}
}
Have you considered using JUnit 5 with its http://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests ?
It allows you to re-use your tests with different input. This is an example from the documentation which illustrates what you can do now with JUnit 5:
#ParameterizedTest
#ValueSource(strings = { "Hello", "World" })
void testWithStringParameter(String argument) {
assertNotNull(argument);
}
But you can also create your methods which return the input data:
#ParameterizedTest
#MethodSource("stringProvider")
void testWithSimpleMethodSource(String argument) {
assertNotNull(argument);
}
static Stream<String> stringProvider() {
return Stream.of("foo", "bar");
}
Here I am using just strings, but you can really use any objects.
If you are using Maven, you can add these dependencies to start using JUnit 5:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.0.0-RC2</version>
<scope>test</scope>
</dependency>
The only annoying thing about JUnit 5 is that it is not released yet.
When going from one test to two tests, you don't know what will be duplicate code, so I find it useful to put everything into one test method. In this case, start by putting the contents of the #Before and beforeFileTest methods inline in the test.
Then you can see that it is just te service that needs changing, so you can extract everything except that into a helper method that is called from two tests.
Also, after you have two tests that are calling the same helper method and are happy with that test coverage, you could look into writing parameterized tests. For example with JunitParams: https://github.com/Pragmatists/junitparams/wiki/Quickstart

Can I avoid running junit tests twice in eclipse when using a TestSuite?

I need to do some per-suite initialisation (starting a web-server). It is working fine except that when I run all tests in my project in eclipse my tests run twice. My test suite looks a bit like this:
#RunWith(Suite.class)
#Suite.SuiteClasses({
SubtestOne.class,
SubtestTwo.class
})
public class TestSuite
{
[...]
}
public class SubtestOne
{
#Test public void testOne() { [...] }
}
public class SubtestTwo
{
#Test public void testTwo() { [...] }
}
When I run all test in project in eclipse this causes the junit plugin to run the tests twice like this:
SubtestOne
SubtestTwo
TestSuite
SubtestOne
SubtestTwo
Is it possible to make "run all test in project" not run the sub-tests twice? I want my sub tests to be only ever run as part of the suite.
No, the test class will always be started directly and then through the "link" in the suite. This is as expected.
One workaround might to set in the run configuration to only run tests from the package which contains your suites. Open the run configuration and select Run all tests in the selected project, package or source folder then click Search... and select the package.
I realize that this has been asked over 5 years ago, but as quite a few folks up-voted the question I thought I'd still chime in with a solution. Skip right to the end if you just want the solution; read the whole text if you also want to understand it ;-)
First of all, it is indeed possible to ensure that a particular JUnit test class gets only run inside a test suite. Also, it is irrelevant whether you want to run that test suite inside Eclipse (as asked here) or any other tool or environment; this is really a pure JUnit issue for the most part.
Before I sketch out the solution, it might be a good idea to revisit what the exact problem is here. All JUnit tests need to be visible and instantiable to be picked up by the JUnit framework and its various runners. This also applies to test suites and the individual tests that are part of a test suite. As a consequence, if JUnit picks up the test suite it will also pick up the individual tests, and all tests in the suite will be executed twice, once individually and once as part of the suite.
So, the trick, if you will, is to prevent JUnit from picking up the individual tests while still being able to instantiate and execute them as part of the suite.
One thing that comes to mind is to make the test classes static inner classes nested inside the test suite. However, the nested classes still need to be public (otherwise they can't be run in the suite either), and if they are public classes they will also be picked up individually, despite being nested inside the suite's public class. JUnit will not try to run test classes that are not considered visible, though. So, nesting the test classes inside a non-public class would presumably be sufficient to hide them, but we can't make the suite class non-public because then JUnit would not execute it. What we can do, however, is to nest the individual tests inside another non-public class that's nested inside the test suite, which leads us to the solution of this conundrum:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({AllTests.InSuiteOnly.Test1.class, AllTests.InSuiteOnly.Test2.class})
public class AllTests
{
static class InSuiteOnly
{
public static class Test1
{
#Test
public void test1()
{
//...
}
}
public static class Test2
{
#Test
public void test2()
{
//...
}
}
}
}
A lot of folks will probably object to all tests needing to be inside a single source file now. What if I want to maintain separate JUnit test classes that don't get executed by themselves but still get executed inside the test suite? A simple solution is to make the individual test classes abstract (public/non-public doesn't matter) so that JUnit won't execute them, and inside the test suite we simply use concrete subclasses of the original abstract test classes:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({AllTests.InSuiteOnly.SuiteTest1.class, AllTests.InSuiteOnly.SuiteTest2.class})
public class AllTests
{
static class InSuiteOnly
{
public static class SuiteTest1 extends Test1 {}
public static class SuiteTest2 extends Test2 {}
}
}
abstract class Test1
{
#Test
public void test1()
{
//...
}
}
abstract class Test2
{
#Test
public void test2()
{
//...
}
}
This scheme works with Maven, Eclipse, and all other environments that either directly leverage JUnit's runners or implement their own runners that closely follow JUnit's original behavior and semantics.
I have an idea for you. Actually you do not want to run these test case as stand-alone test cases. You can do the following.
Mark the test cases with annotation #RunWith(DoNothingRunner.class)
Implment DoNothingRunner as following:
public class DoNothingRunner extends Runner {
public Description getDescription() {
return "do nothing";
}
public void run(RunNotifier notifier) {
// indeed do nothing
}
}
I have not tried this personally but I hope this will work.
do you need the suite in the first place ? depending on when you click for run all (class, package, or src/test/java), all underlying tests will be executed. So what's the point of having a suite ?
There is a solution, it's a bit tricky, but it may easily resolve your problem: create one suite class, and include all your suite classes in it. Then you can use this suite class to run all your tests.
#RunWith(Suite.class)
#Suite.SuiteClasses({
AXXSuite.class,
BXXSuite.class,
CXXSuite.class
})
public class AllSuites {
}

Cleanup after all junit tests

In my project I have to do some repository setup before all tests. This is done using some tricky static rules. However I've got no clue how to do clean up after all the tests. I don't want to keep some magic static number referring the number of all test methods, which I should maintain all the time.
The most appreciated way is to add some listener which would be invoked after all the tests. Is there any interface for it already in JUnit4?
edit: this has nothing to do with #BeforeClass and #AfterClass, cause I have to know if method annotated with #AfterClass is invoked for the last time.
I'm using JUnit 4.9. Will this help?:
import junit.framework.TestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({First.class,Second.class,Third.class})
public class RunTestSuite extends TestCase {
#BeforeClass
public static void doYourOneTimeSetup() {
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
}
Edit: I am quite positive (unless I misunderstand your question) that my solution is what you are looking for. i.e. one teardown method after all your tests have ran. No listener required, JUnit has this facility. Thanks.
I recommend to use org.junit.runner.notification.RunListener, example:
public class TestListener extends RunListener {
#Override
public void testRunStarted(Description description) throws Exception {
// Called before any tests have been run.
}
#Override
public void testRunFinished(Result result) throws Exception {
// Called when all tests have finished
}
}
Read more directly in JUnit java doc.
You can use that even with Maven's surefire (unit tests) plugin or failsafe plugin (integration tests) by adding following code into plugin configuration:
<properties>
<property>
<name>listener</name>
<value>com.innovatrics.afismq.it.TestListener</value>
</property>
</properties>
Just encountered the same problem.
My solution:
For a global set up: use (lazy) singleton to access something global that requires instantiation before the tests. The first test that accesses this singleton will trigger the global set up process.
For a global tear down: use a Java shutdown hook: Runtime.getRuntime().addShutdownHook(new Thread(() -> do_your_global_cleanup())));
You can always write your custom TestRunner. However, before you do that you need to evaluate the need for the same. It is better to use #BeforeClass and #AfterClass. Another example I can point to is, the fashion in which hibernate allows users to do unit testing using 'import.sql'.
No need to use suite, just add #BeforeClass, and #AfterClass as static
public class Tests {
#BeforeClass
public static void doYourOneTimeSetup()
{
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
#Test
public void testYourTestcase()
{
...
}
}

How to run test methods in specific order in JUnit4?

I want to execute test methods which are annotated by #Test in specific order.
For example:
public class MyTest {
#Test public void test1(){}
#Test public void test2(){}
}
I want to ensure to run test1() before test2() each time I run MyTest, but I couldn't find annotation like #Test(order=xx).
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
I'm not sure there is a clean way to do this with JUnit, to my knowledge JUnit assumes that all tests can be performed in an arbitrary order. From the FAQ:
How do I use a test fixture?
(...) The ordering of test-method invocations is not guaranteed, so testOneItemCollection() might be executed before testEmptyCollection(). (...)
Why is it so? Well, I believe that making tests order dependent is a practice that the authors don't want to promote. Tests should be independent, they shouldn't be coupled and violating this will make things harder to maintain, will break the ability to run tests individually (obviously), etc.
That being said, if you really want to go in this direction, consider using TestNG since it supports running tests methods in any arbitrary order natively (and things like specifying that methods depends on groups of methods). Cedric Beust explains how to do this in order of execution of tests in testng.
If you get rid of your existing instance of Junit, and download JUnit 4.11 or greater in the build path, the following code will execute the test methods in the order of their names, sorted in ascending order:
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
#Test
public void testAcreate() {
System.out.println("first");
}
#Test
public void testBupdate() {
System.out.println("second");
}
#Test
public void testCdelete() {
System.out.println("third");
}
}
Migration to TestNG seems the best way, but I see no clear solution here for jUnit. Here is most readable solution / formatting I found for jUnit:
#FixMethodOrder( MethodSorters.NAME_ASCENDING ) // force name ordering
public class SampleTest {
#Test
void stage1_prepareAndTest(){};
#Test
void stage2_checkSomething(){};
#Test
void stage2_checkSomethingElse(){};
#Test
void stage3_thisDependsOnStage2(){};
#Test
void callTimeDoesntMatter(){}
}
This ensures stage2 methods are called after stage1 ones and before stage3 ones.
P.S. I feel this approach is better that jUnit 5.5 #Order annotation because it provides better notation for reader.
If the order is important, you should make the order yourself.
#Test public void test1() { ... }
#Test public void test2() { test1(); ... }
In particular, you should list some or all possible order permutations to test, if necessary.
For example,
void test1();
void test2();
void test3();
#Test
public void testOrder1() { test1(); test3(); }
#Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }
#Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }
Or, a full test of all permutations:
#Test
public void testAllOrders() {
for (Object[] sample: permute(1, 2, 3)) {
for (Object index: sample) {
switch (((Integer) index).intValue()) {
case 1: test1(); break;
case 2: test2(); break;
case 3: test3(); break;
}
}
}
}
Here, permute() is a simple function which iterates all possible permuations into a Collection of array.
JUnit since 5.5 allows #TestMethodOrder(OrderAnnotation.class) on class and #Order(1) on test-methods.
JUnit old versions allow test methods run ordering using class annotations:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#FixMethodOrder(MethodSorters.JVM)
#FixMethodOrder(MethodSorters.DEFAULT)
By default test methods are run in alphabetical order. So, to set specific methods order you can name them like:
a_TestWorkUnit_WithCertainState_ShouldDoSomething
b_TestWorkUnit_WithCertainState_ShouldDoSomething
c_TestWorkUnit_WithCertainState_ShouldDoSomething
Or
_1_TestWorkUnit_WithCertainState_ShouldDoSomething
_2_TestWorkUnit_WithCertainState_ShouldDoSomething
_3_TestWorkUnit_WithCertainState_ShouldDoSomething
You can find examples here.
Its one of the main issue which I faced when I worked on Junit and I came up with following solution which works fine for me:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
Collections.sort(copy, new Comparator<FrameworkMethod>() {
#Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return -1;
}
return o1.order() - o2.order();
}
});
return copy;
}
}
also create a interface like below:
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD})
public #interface Order {
public int order();
}
Now suppose you have class A where you have written several test cases like below:
(#runWith=OrderRunner.class)
Class A{
#Test
#Order(order = 1)
void method(){
//do something
}
}
So execution will start from method named "method()".
Thanks!
JUnit 5 update (and my opinion)
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
By default, unit testing libraries don't try to execute tests in the order that occurs in the source file.
JUnit 5 as JUnit 4 work in that way. Why? Because if the order matters it means that some tests are coupled between them and that is undesirable for unit tests.
So the #Nested feature introduced by JUnit 5 follows the same default approach.
But for integration tests, the order of the test method may matter since a test method may change the state of the application in a way expected by another test method.
For example when you write an integration test for a e-shop checkout processing, the first test method to be executed is registering a client, the second is adding items in the basket and the last one is doing the checkout. If the test runner doesn't respect that order, the test scenario is flawed and will fail.
So in JUnit 5 (from the 5.4 version) you have all the same the possibility to set the execution order by annotating the test class with #TestMethodOrder(OrderAnnotation.class) and by specifying the order with #Order(numericOrderValue) for the methods which the order matters.
For example :
#TestMethodOrder(OrderAnnotation.class)
class FooTest {
#Order(3)
#Test
void checkoutOrder() {
System.out.println("checkoutOrder");
}
#Order(2)
#Test
void addItemsInBasket() {
System.out.println("addItemsInBasket");
}
#Order(1)
#Test
void createUserAndLogin() {
System.out.println("createUserAndLogin");
}
}
Output :
createUserAndLogin
addItemsInBasket
checkoutOrder
By the way, specifying #TestMethodOrder(OrderAnnotation.class) looks like not needed (at least in the 5.4.0 version I tested).
Side note
About the question: is JUnit 5 the best choice to write integration tests? I don't think that it should be the first tool to consider (Cucumber and co may often bring more specific value and features for integration tests) but in some integration test cases, the JUnit framework is enough. So that is a good news that the feature exists.
The (as yet unreleased) change https://github.com/junit-team/junit/pull/386 introduces a #SortMethodsWith. https://github.com/junit-team/junit/pull/293 at least made the order predictable without that (in Java 7 it can be quite random).
Look at a JUnit report. JUnit is already organized by package. Each package has (or can have) TestSuite classes, each of which in turn run multiple TestCases. Each TestCase can have multiple test methods of the form public void test*(), each of which will actually become an instance of the TestCase class to which they belong. Each test method (TestCase instance) has a name and a pass/fail criteria.
What my management requires is the concept of individual TestStep items, each of which reports their own pass/fail criteria. Failure of any test step must not prevent the execution of subsequent test steps.
In the past, test developers in my position organized TestCase classes into packages that correspond to the part(s) of the product under test, created a TestCase class for each test, and made each test method a separate "step" in the test, complete with its own pass/fail criteria in the JUnit output. Each TestCase is a standalone "test", but the individual methods, or test "steps" within the TestCase, must occur in a specific order.
The TestCase methods were the steps of the TestCase, and test designers got a separate pass/fail criterion per test step. Now the test steps are jumbled, and the tests (of course) fail.
For example:
Class testStateChanges extends TestCase
public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()
Each test method asserts and reports its own separate pass/fail criteria.
Collapsing this into "one big test method" for the sake of ordering loses the pass/fail criteria granularity of each "step" in the JUnit summary report. ...and that upsets my managers. They are currently demanding another alternative.
Can anyone explain how a JUnit with scrambled test method ordering would support separate pass/fail criteria of each sequential test step, as exemplified above and required by my management?
Regardless of the documentation, I see this as a serious regression in the JUnit framework that is making life difficult for lots of test developers.
Not sure I agree, If I want to test 'File Upload' and then test 'Data Inserted by File Upload' why would I not want these to be independent from each other? Perfectly reasonable I think to be able to run them separately rather than having both in a Goliath test case.
What you want is perfectly reasonable when test cases are being run as a suite.
Unfortunately no time to give a complete solution right now, but have a look at class:
org.junit.runners.Suite
Which allows you to call test cases (from any test class) in a specific order.
These might be used to create functional, integration or system tests.
This leaves your unit tests as they are without specific order (as recommended), whether you run them like that or not, and then re-use the tests as part of a bigger picture.
We re-use/inherit the same code for unit, integration and system tests, sometimes data driven, sometimes commit driven, and sometimes run as a suite.
JUnit 4 update
As of JUnit 4.13 #OrderWith, it is possible to reproduce the JUnit 5 #Order annotation. This solution better integrates with JUnit 4 than #RunWith a custom BlockJUnit4ClassRunner implementation.
Here's how I could replace method name ordering (#FixMethodOrder(MethodSorters.NAME_ASCENDING)) with an ordering by annotation.
#OrderWith(OrderAnnotation.class)
public class MyTest {
#Test
#Order(-1)
public void runBeforeNotAnnotatedTests() {}
#Test
public void notAnnotatedTestHasPriority0() {}
#Test
#Order(1)
public void thisTestHasPriority1() {}
#Test
#Order(2)
public void thisTestHasPriority2() {}
}
/**
* JUnit 4 equivalent of JUnit 5's {#code org.junit.jupiter.api.Order}
*/
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD })
public #interface Order {
/**
* Default order value for elements not explicitly annotated with {#code #Order}.
*
* #see Order#value
*/
int DEFAULT = 0;
/**
* The order value for the annotated element.
* <p>Elements are ordered based on priority where a lower value has greater
* priority than a higher value. For example, {#link Integer#MAX_VALUE} has
* the lowest priority.
*
* #see #DEFAULT
*/
int value();
}
import org.junit.runner.Description;
import org.junit.runner.manipulation.Ordering;
import org.junit.runner.manipulation.Sorter;
/**
* Order test methods by their {#link Order} annotation. The lower value has the highest priority.
* The tests that are not annotated get the default value {#link Order#DEFAULT}.
*/
public class OrderAnnotation extends Sorter implements Ordering.Factory {
public OrderAnnotation() {
super(COMPARATOR);
}
#Override
public Ordering create(Context context) {
return this;
}
private static final Comparator<Description> COMPARATOR = Comparator.comparingInt(
description -> Optional.ofNullable(description.getAnnotation(Order.class))
.map(Order::value)
.orElse(Order.DEFAULT));
}
The not annotated tests get a default priority of 0. The order of tests with the same priority is undetermined.
Gist: https://gist.github.com/jcarsique/df98e0bad9e88e8258c4ab34dad3c863
Inspired by:
Aman Goel's answer
Test execution order Wiki by JUnit team
JUnit 5 source code
See my solution here:
"Junit and java 7."
In this article I describe how to run junit tests in order - "just as in your source code".
Tests will be run, in order as your test methods appears in class file.
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
But as Pascal Thivent said, this is not a good practise.
As others have stated, tests should be ideally be independent of execution order. This makes tests less fragile, and allows them to be run independently (many IDEs allow you to select a test method and execute it independently of other tests).
That being said, for integration tests, some people prefer to rely on method ordering.
Starting with JUnit 4.13 you can define your own class to reorder tests by extending Ordering. See the JUnit wiki for more details. Here's an example using the built-in Alphanumeric class to order the tests alphanumerically using the test method name:
import org.junit.Test;
import org.junit.runner.OrderWith;
import org.junit.runner.manipulation.Alphanumeric;
#OrderWith(Alphanumeric.class)
public class TestMethodOrder {
#Test
public void testA() {
System.out.println("first");
}
#Test
public void testB() {
System.out.println("second");
}
#Test
public void testC() {
System.out.println("third");
}
}
For JUnit 4, putting this annotation on the test class solved the problem.
#FixMethodOrder(MethodSorters.JVM)
With JUnit 5.4, you can specify the order :
#Test
#Order(2)
public void sendEmailTestGmail() throws MessagingException {
you just need to annotate your class
#TestMethodOrder(OrderAnnotation.class)
https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-execution-order
i'm using this in my project and it works very well !
You can use one of these piece of codes:
#FixMethodOrder(MethodSorters.JVM) OR #FixMethodOrder(MethodSorters.DEFAULT) OR #FixMethodOrder(MethodSorters.NAME_ASCENDING)
Before your test class like this:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest {...}
It's time to move to Junit5.
Here is a sample of what we could get:
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderedTests {
#Test
#Order(1)
void nullValues() {}
#Test
#Order(2)
void emptyValues() {}
#Test
#Order(3)
void validValues() {}
}
For Junit4, copy the logic that you have in several tests in one test method.
I've read a few answers and agree its not best practice, but the easiest way to order your tests - and the way that JUnit runs tests by default is by alphabetic name ascending.
So just name your tests in the alphabetic order that you want. Also note the test name must begin
with the word test. Just watch out for numbers
test12 will run before test2
so:
testA_MyFirstTest
testC_ThirdTest
testB_ATestThatRunsSecond
Please check out this one: https://github.com/TransparentMarket/junit. It runs the test in the order they are specified (defined within the compiled class file). Also it features a AllTests suite to run tests defined by sub package first. Using the AllTests implementation one can extend the solution in also filtering for properties (we used to use #Fast annotations but those were not published yet).
Here is an extension to JUnit that can produce the desired behavior: https://github.com/aafuks/aaf-junit
I know that this is against the authors of JUnit philosophy, but when using JUnit in environments that are not strict unit testing (as practiced in Java) this can be very helpful.
I ended up here thinking that my tests weren't run in order, but the truth is that the mess was in my async jobs. When working with concurrency you need to perform concurrency checks between your tests as well.
In my case, jobs and tests share a semaphore, so next tests hang until the running job releases the lock.
I know this is not fully related to this question, but maybe could help targeting the correct issue
If you want to run test methods in a specific order in JUnit 5, you can use the below code.
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MyClassTest {
#Test
#Order(1)
public void test1() {}
#Test
#Order(2)
public void test2() {}
}

Categories