Transcripted Summary

So far, we have created a few tests using the @Test and @ParameterizedTest annotations.

In some cases, we want our test methods from a class to run in a certain order.

We don't want the default order that JUnit is using when running the test methods.

The good thing is that we have some options to have our test methods run in the order we want them, and I will go over these during this chapter, and we will see some examples.

In order to demonstrate the features of this chapter, I will just copy and paste the first test class that we created (FirstTestClass), because I don't want to change this one.

I want this one to remain here for reference.

So I will copy the entire class, and I will change the name to OrderedTestClass1, because I will create a separate one afterwards.

As you remember, here, we just have the before and after methods and we also have two test methods.

The first one is called firstMethod, and the second one is called secondMethod.

One of the options that we have to order our test methods is to use the method names, so to order the tests alphanumerically based on the method name.

In order to do that, I will have to go on the test class level and add a new annotation here - namely, the @TestMethodOrder.

Now, the MethodOrderer has several options.



As you can see, we have the OrderAnnotation option, MethodName, DisplayName, Random, and one which is crossed out - so that is currently deprecated; it will be removed in a future version.

For the purpose of this particular example, I will choose the MethodName out of the list, and I will say .class.

This annotation tells JUnit that the tests in this class will run in alphanumeric order based on their method names - that is, except the lifecycle methods, because, of course, the beforeAll, beforeEach, afterAll, and afterEach methods will run just as before.

So this is the only thing we need to do to make our test methods run in alphanumerical order based on their method names.


package junit5tests;

import org.junit.jupiter.api.*;

@TestMethodOrder(MethodOrderer.MethodName.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class OrderedTestClass1 {

    @BeforeAll
    void beforeAll() {
        System.out.println("--This is the before All method");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("----This is the before Each method");
    }

    @AfterAll
    void afterAll() {
        System.out.println("--This is the after All method");
    }

    @AfterEach
    void afterEach() {
        System.out.println("----This is the after Each method");
    }

    @Test
    void firstMethod() {
        System.out.println("This is the first test method");
    }

    @Test
    @DisplayName("US1234 - TC12 - this method is the second one")
    void secondMethod() {
        System.out.println("This is the second test method");
    }

}

So we can see if that is the case by running the entire test class.

In the console output, we will see that the firstMethod ran and that we have a display name here, instead of the name of the method, because that is how the test was created.



But you can see that the first method that ran has the name firstMethod, and the second method does have the name secondMethod.

So it's clear that the order has been properly preserved.

Let's create a third one just to make sure.

So I'm just going to say @Test void thirdTest, and here, just a System.out that says, "This is the third test method."


package junit5tests;

import org.junit.jupiter.api.*;

@TestMethodOrder(MethodOrderer.MethodName.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class OrderedTestClass1 {

    @BeforeAll
    void beforeAll() {
        System.out.println("--This is the before All method");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("----This is the before Each method");
    }

    @AfterAll
    void afterAll() {
        System.out.println("--This is the after All method");
    }

    @AfterEach
    void afterEach() {
        System.out.println("----This is the after Each method");
    }

    @Test
    void firstMethod() {
        System.out.println("This is the first test method");
    }

    @Test
    @DisplayName("US1234 - TC12 - this method is the second one")
    void secondMethod() {
        System.out.println("This is the second test method");
    }

    @Test
    void thirdTest() {
        System.out.println("This is the third test method");
    }
}

And I will, again, run the test and let's see the display.

So now, when the tests will run, we will see three method runs.

Again, first method is first. Second method is second. And third one is the third test.

Let's add a display name to the last test, also.

So let's just say that, here, the display name for this method is "A display name."

And let's say that we want the order of the tests to be based on their display name, so we want the alphanumerical sorting based on the display name.

I will now show how the order changes when we are going to use the display name order option instead of the MethodName.

So here, in the test method order annotation, I will just say DisplayName.


package junit5tests;

import org.junit.jupiter.api.*;

@TestMethodOrder(MethodOrderer.DisplayName.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class OrderedTestClass1 {

    @BeforeAll
    void beforeAll() {
        System.out.println("--This is the before All method");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("----This is the before Each method");
    }

    @AfterAll
    void afterAll() {
        System.out.println("--This is the after All method");
    }

    @AfterEach
    void afterEach() {
        System.out.println("----This is the after Each method");
    }

    @Test
    void firstMethod() {
        System.out.println("This is the first test method");
    }

    @Test
    @DisplayName("US1234 - TC12 - this method is the second one")
    void secondMethod() {
        System.out.println("This is the second test method");
    }

    @Test
    @DisplayName("A display name")
    void thirdTest() {
        System.out.println("This is the third test method");
    }
}

Now, you have noticed that we have three methods, out of which only two have a display name.

No problem - all three will still run, but you will see what is the difference here. I will run the test.



And when we're looking at the console on the left-hand side, we will see that the method with the display name starting with "A" ran first, then the method whose display name starts with "U" ran second, and then the method without any display name ran last.

So in this case, when we have a combined set of methods - some with and some without display name - the first tests that will run will be those with a display name.

They will run in the alphanumeric order given by their display names.

Again, if I change the DisplayName order to MethodName, it will go back to what we had initially - namely, the order will be firstMethod, secondMethod, and thirdTest method, as you can see.



Now, how about the situation where we want an explicit order?

So we don't care about the method name to be alphanumerically sorted, and we don't care about the display name.

We just want a certain order.

I will go back to the project pane, and I will copy, again, the same FirstTestClass.

I will paste it again, and I will say OrderedTestClass2.

So I have, again, two methods here - two test methods - the first one and the second one.

I will, again, create a third one.

And again, just a System.out, and we'll say, "This is the third test method."

Now let's say that we want to use the ordering option.

So again, we will have to say @TestMethodOrder, so we need to specify this annotation, and then we need to choose the MethodOrder.OrderAnnotation.class option.

In this case, when we're using the OrderAnnotation, we need to give an order to our test methods.

So let's say that we want the third test to be the first that runs.

We will need to add an additional annotation - namely, the @Order.

And then, between the (), we need to specify an int value, so I will specify the value 1.

This means that I want the first test that runs to be this one.

Now, because order takes an int value as a parameter, of course, we can use all of the int values, starting with Integer.MIN_VALUE and up to Integer.MAX_VALUE.

But here we will just use some values that are greater than zero.

So this is the first test that I want to run.

And let's say that I want the second test that runs to be firstMethod - so here I will say @Order(2).

I will leave the method secondMethod, without any @Order annotation set on it, and I will run the test.


package junit5tests;

import org.junit.jupiter.api.*;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class OrderedTestClass2 {

    @BeforeAll
    void beforeAll() {
        System.out.println("--This is the before All method");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("----This is the before Each method");
    }

    @AfterAll
    void afterAll() {
        System.out.println("--This is the after All method");
    }

    @AfterEach
    void afterEach() {
        System.out.println("----This is the after Each method");
    }

    @Test
    @Order(2)
    void firstMethod() {
        System.out.println("This is the first test method");
    }

    @Test
    @DisplayName("US1234 - TC12 - this method is the second one")
    void secondMethod() {
        System.out.println("This is the second test method");
    }

    @Test
    @Order(1)
    void thirdTest() {
        System.out.println("This is the third test method");
    }
}

We will see the new order in which these tests will run - namely, the thirdTest ran first because it had an @Order of 1.



Then if we go to firstMethod, this was the one that we wanted to run as the second method - actually, as the second test method in our tests to run.

And then, the only method that didn't have an @Order ran last.

This is because there is a default when we are using orders.

More precisely, when we want to order the test class, we are using the MethodOrderer.OrderAnnotation, but we don't specify some orders for some methods.

In this case, if we have a method without an order annotation assigned to it, by default, it will take the value Integer.MAX_VALUE divided by two - so it will be quite a large number.

The smaller the number, the higher priority in the run order, so low numbers run first.

So this concludes it for this chapter. We have seen how to set the order in which tests run in three ways.

There is another one, the Random one, but this is something that you might not really need, so we don't really want tests to run in a random order.

If we would want that, we would just leave the tests as they were before we added the @TestMethodOrder annotation, so we don't need to specify that one if we are not interested for our tests to run in a specific order.



Resources



© 2022 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR