TestNG

JUnit and TestNG are two major Java testing frameworks. You already wrote tests with JUnit in the previous chapter and, hopefully, got a good understanding of how it works. How about TestNG? It was born out of a desire to make JUnit better. Indeed, it contains some functionalities that JUnit doesn't have.

The following subchapters summarize some of the differences between the two of them. We'll try not only to provide an explanation of differences, but also their evaluation in the context of unit testing with TDD.

The @Test annotation

Both JUnit and TestNG use the @Test annotation to specify which method is considered to be a test. Unlike JUnit, which requires every method to be annotated with @Test, TestNG allows us to use this annotation on a class level, as well. When used in this way, all public methods are considered tests unless specified otherwise:

@Test
public class DirectionSpec {

    public void whenGetFromShortNameNThenReturnDirectionN() {
        Direction direction = Direction.getFromShortName('N'),
        assertEquals(direction, Direction.NORTH);
    }

    public void whenGetFromShortNameWThenReturnDirectionW() {
        Direction direction = Direction.getFromShortName('W'),
        assertEquals(direction, Direction.WEST);
    }

}

In this example, we put the @Test annotation above the DirectionSpec class. As a result, both the whenGetFromShortNameNThenReturnDirectionN and whenGetFromShortNameWThenReturnDirectionW methods are considered tests. If that code was written using JUnit, both the methods would need to have the @Test annotation.

The @BeforeSuite, @BeforeTest, @BeforeGroups, @AfterGroups, @AfterTest, and @AfterSuite annotations

Those four annotations do not have their equivalents in JUnit. TestNG can group tests into suites, using XML configuration. Methods annotated with @BeforeSuite and @AfterSuite are run before and after all the tests in the specified suite have run. Similarly, the @BeforeTest and @AfterTest annotated methods are run before any test method belonging to the test classes has run. Finally, TestNG tests can be organized into groups. The @BeforeGroups and @AfterGroups annotations allows us to run methods before the first test and after the last test, in specified groups, is run.

While those annotations can be very useful when tests are written after the implementation code, they do not provide much usage in the context of TDD. Unlike traditional testing, which is often planned and written as a separate project, TDD teaches us to write one test at a time and keep everything simple. Most importantly, unit tests are supposed to run fast so there is no need to group them into suites or groups. When tests are fast, running anything less than everything is a waste. If, for example, all tests are run in less than 15 seconds, there is no need to run only a part of them. On the other hand, when tests are slow, it is often a sign that external dependencies are not isolated. No matter what the reason is behind slow tests, the solution is not to run only a part of them, but to fix the problem.

Moreover, functional and integration tests do tend to be slower and require us to have some kind of separation. However, it is better to separate them in, for example, build.gradle so that each type of test is run as a separate task.

The @BeforeClass and @AfterClass annotations

These annotations have the same function in both JUnit and TestNG. Annotated methods will be run before the first test and after the last test, in a current class, are run. The only difference is that TestNG does not require those methods to be static. The reason behind this can be found in the different approaches those two frameworks take when running test methods. JUnit isolates each test into its own instance of the test class, forcing us to have those methods defined as static and, therefore, reusable across all test runs. TestNG, on the other hand, executes all test methods in the context of a single test class instance eliminating the need for those methods to be static.

The @BeforeMethod and @AfterMethod annotations

The @Before and @After annotations are equivalent to JUnit. Annotated methods are run before and after each test method.

The @Test(enable = false) annotation argument

Both JUnit and TestNG can disable tests. While JUnit uses a separate @Ignore annotation, TestNG uses the @Test annotation Boolean argument enable. Functionally, both work in the same way and the difference is only in the way we write them.

The @Test(expectedExceptions = SomeClass.class) annotation argument

This is the case where JUnit has the advantage. While both provide the same way to specify the expected exception (in the case of JUnit, argument is called simply expected), JUnit introduces rules that are a more elegant way to test exceptions (we already worked with them in Chapter 2, Tools, Frameworks, and Environment).

TestNG vs JUnit summary

There are many other differences between those two frameworks. For brevity, we did not cover all of them in this book. Consult their documentation for further information.

Note

More information about JUnit and TestNG can be found at http://junit.org/ and http://testng.org/.

TestNG provides more features and is more advanced than JUnit. We'll work with TestNG throughout this chapter, and you'll get to know it better. One thing that you'll notice is that we won't use any of those advanced features. The reason is that, with TDD, we rarely need them when working with unit tests. Functional and Integration tests are of a different kind and would serve as a better demonstration of TestNG's superiority. However, there are tools that are more suited for those types of tests, as you'll see in the following chapters.

Which one should you use? I'll leave that choice up to you. By the time you finish this chapter, you'll have hands-on knowledge of both JUnit and TestNG.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.159.223