JUnit is an open-source testing framework to help Java & Kotlin professionals to write and execute different varieties of tests in different levels of Software Testing phases, such as unit testing, integration testing, system testing, and acceptance testing in STLC.
There are different versions of JUnit. However, we shall explore the features of JUnit 5 in this article. Every experienced developer and an automation test professional would have used JUnit at least once in their life, because of its popularity, simplicity, ease of use, flexibility, and effectiveness in running tests accurately and elegantly.
With the addition of new features in the latest versions of JUnit, its usage of it looks more attractive in several test frameworks in the software development & testing world.
How to write the first JUnit test?
JUnit is popularly used in combination with Selenium WebDriver while writing UI tests for the automation browser testing of websites and web apps.
Let us use Eclipse IDE to start writing our first JUnit test in Java:
Create a new Java project in Eclipse by navigating to Eclipse Menu:
- Go to ‘File’ menu -> Click on ‘New’ -> Select “Java Project” as guided in the image below
- Provide a Project name such as “DemoProject” -> Choose a JRE environment such as “JavaSE-14” / choose the most latest available JavaSE version -> Click on “Finish” button in the bottom of the displayed pop-up window
- If the below module-info window is displayed, select “Don’t create” button
- When a new Java project is successfully created, right click on the ‘src’ folder and select the following options: New -> JUnit Test Case
Enter a required package name in ‘Package’ field,
JUnit Test Class name in ‘Name’ field
Uncheck all the method stubs as shown below and then click on ‘Finish’ button
(unchecking is optional, if you wish to keep them checked, it’s good too.
- The newly generated structure of JUnit test class is generated now and shall look as similar to the snapshot attached below:
- We can also observe that the newly created JUnit test class is now under the previous defined package in the navigation pane on the left hand side of Eclipse
- Now, let us modify the test a bit for a demo run and modify the generated line 11 with System.out.println(“Testing…”);
- Once the above change is done in line 11, let us prepare ourselves to execute our first JUnit test.
How to execute the first JUnit test?
- Run the JUnit test class by right-clicking on the test class in the navigation pane and selecting Run As option and then choosing the JUnit Test option.
Example:
Our first test case:
package JUnit5;
import org.JUnit.jupiter.api.Test;
class DemoTest {
@Test
void test1() {
System.out.print(“Testing…”);
}
}
After following the above step religiously, now we should be able to see that the selected test is executed successfully and the test result is displayed in the JUnit tab with green status denoting that the test has passed successfully.
How to write JUnit Test Cases?
Let us add 2 more tests and see how the JUnit test runner works for multiple tests
Note that each test method is written after @Test annotations, denoted in Grey colour in the test class, as in the screenshot below
Example:
Let us try running the below sample test code now and observe the test result:
package JUnit5;
import static org.JUnit.Assert.assertEquals;
import org.JUnit.jupiter.api.Test;
class DemoTest {
@Test
void test1() {
System.out.print(“Testing…”);
}
@Test
void test2() {
assertEquals(5, 3+2);
}
@Test
void test3() {
assertEquals(“Hello”, “hola”);
}
}
In theory, note that in the above test2() test method, a valid assertion method is passed, where the test is verifying that the expected numeric test data – ‘3+2’ is equal to 5 in actual result post execution or not.
Also, note that in the test3() test method, an incorrect assertion check is passed, to purposefully fail the test post execution, as the expected string “Hello” is not equal to actual result “hola”.
Let us run the test again and observe the executed test result
As expected, test2() has passed and test3() has failed.
Let us analyse the failed test case by looking at the Failure Trace tab, which is available just below the above displayed test result in Eclipse
Let us understand the failure trace in detail by either clicking on the blue-highlighted line as arrow-marked in the image above or the pointed icon as marked using the second arrow to compare between the actual and expected test result.
With the display of the difference in the expected and actual result as observed in the Result comparison window above, our analysis of failed tests is complete and probably, we now know the root cause of a possible bug (if it was a real case scenario).
Let me modify the test a bit and see if the test still passes, if one word is wrong in an entire verified correct sentence?
Example:
<script src=”https://gist.github.com/suparna-khamaru/41c886c287cf9835e56bd3f313a15e9c.js”></script>
On test execution, the Result Comparison display the below highlighting the unmatched section of the test result in red colour in both expected and actual result:
Is it not so simple to find out why our JUnit test failed so quickly? This is why JUnit is so widely used and popular in the Java community.
Let us now rerun all tests with valid test data and see how our tests pass successfully.
Let us redesign and explore the JUnit test class further and make our tests look elegant as well.
What are the most common widely used JUnit5 Annotations?
Once we know that our basic tests are working fine. Let us explore the various annotations of JUnit 5 which can help us in enhancing & optimizing our test framework further.
@Test
Any method starting with @Test annotation shall be considered and identified as a test method by JUnit on runtime.
Example:
<script src=”https://gist.github.com/suparna-khamaru/da055cf4beb505b4bb33933db4260b0e.js“></script>
@BeforeEach
@BeforeEach annotations are generally used to run generic steps before each of the test methods.
Example:
<script src=”https://gist.github.com/suparna-khamaru/7d332aa4486b9bd5a19bc1c97166a754.js”></script>
Where, we can observe that the ‘expected’ variable is set to ‘10’ before running each of the tests in the test class each time.
@AfterEach
Similarly, @AfterEach annotation is run after each of the tests are run on runtime. Usually the common test steps after running each test are mentioned here.
@BeforeAll
@BeforeAll annotation’s test method is static in nature and hence, the variables mentioned here are to be static in nature. It is mostly used in cases where we want to run a setUp method only once in a class before all the tests are even initiated for test run. That means, @BeforeAll is invoked even before @BeforeEach is invoked.
Example:
<script src=”https://gist.github.com/suparna-khamaru/74338c8d468f0f988f92e81ac4b30ea8.js“></script>
In the above example, we can observe that, even when @BeforeAll annotation is set for setUp method with ‘expected’ variable value of 10, the second test still considers the expected value to be zero, instead of 10, because of @AfterEach annotated value of the same in tearDown() method where the value resets to zero from ten.
@AfterAll
@AfterAll annotation also needs to have its method & variables to be static in nature. It is very similar to @BeforeAll Annotation, however the only difference between the two where it differs is that @AfterAll is used as a tearDown method and is used after all the tests in the class are run successfully.
Example:
@AfterAll
static void tearDownAll() {
// Add code that runs after all test are completely run
}
@Disabled
The usage of @Disabled annotation is to disable running of particular tests in a test suite. We can disable tests in JUnit5 in two ways:
- Test method level
- Test class level
Disabling in Test method level
When a test method is disabled, and the test class is run, the test result is as shown in the below figure:
Disabling in Test class level
When a test class is disabled, all the tests in the test class are also disabled and no tests in the test class are run when the user tries to run the tests in the test class.
Example:
<script src=”https://gist.github.com/suparna-khamaru/59f798ea1a2a713e99d5150f1bbb908e.js“></script>
As a result of which, all the tests in the disabled test class are not found to be running when run and are found disabled with greyed icons beside each test, as can be observed from the figure below in the JUnit test runner result area.
@DisplayName
We can display customized display names to our
- test methods and
- test classes
for our convenience, understanding, and ease of reading test reports, test results, and test logs.
Thus, we can use @DisplayName annotation before any test class name and/or before any test method name and when run by the test runner, we can observe that the tests are run and results are displayed as per values provided in @DisplayName annotation, as can be observed from the figure below:
@Nested
@Nested annotation provides more flexibility to execute tests in any order and in any hierarchy as per testing need.
As can be observed from the figure below,
- class Parent is nested inside class GrandParent and
- class Child is nested inside class Parent
<script src=”https://gist.github.com/suparna-khamaru/6068c7e7f9ea64a3a72f406db39aef6b.js”></script>
Thus, during test execution, all the tests are run in the same nested order as written in the test.
@ParameterizedTest
There are different ways to parametrize test data in JUnit5, let us go through one of the easiest & simplest ways of parameterizing.
This annotation provides us a way to run a single test multiple times with different varieties of parameters, thus improving optimization of test is achieved with more test coverage with minimum lines of code.
Here, instead of using @Test, we need to use @ParameterizedTest before a test method, and also provide a valid source for passing the arguments using @ValueSource annotation, as in the example below:
<script src=”https://gist.github.com/suparna-khamaru/a8b68bad3df83ab785086d019269e306.js”></script>
As a result of which, on running the above parameterised test, we shall observe the test result in the below manner:
@RepeatedTest
Using @RepeatedTest, we can also run the same test multiple times, to check the performance & output of the test each time for various reasons.
Example:
package JUnit5;
import static org.JUnit.Assert.assertEquals;
import org.JUnit.jupiter.api.DisplayName;
import org.JUnit.jupiter.api.RepeatedTest;
@DisplayName(value = “Hello”)
class hello {
@RepeatedTest(value = 5)
void testMultipleTimes() {
assertEquals(5, 3+2);
}
}
For which the test result post running shall be as follows:
What are the most common Assertions in JUnit 5?
What are Assertions?
Assertions are usually verification test steps where the test makes sure that
- Test passes as the expected test data matches with actual data &
- The test fails as the expected test data mismatches with the actual data found during running the test on runtime
As per the official documentation of JUnit5, Assertion is a collection of utility methods that support asserting conditions in tests.
Let us walkthrough some of the different varieties of assertions available in JUnit5:
<script src=”https://gist.github.com/suparna-khamaru/3b09c40b98a55e330b95ba7a49941b40.js”></script>
Running JUnit Scripts with Selenium on LambdaTest
Once you are done with writing JUnit test cases, you can test them on the LambdaTest platform. LambdaTest is a cross browser testing cloud that enables you to test websites and web apps across an online browser farm of 3000+ browsers and operating systems on a cloud-based Selenium grid.
When you run the below test script,
<script src=”https://gist.github.com/suparna-khamaru/e569d5127f0ae81b95bba2307daa0989.js”></script>
The test status is found executed in LambdaTest dashboard with required test artifacts, logs, and video recording, as well as the same, is reflected with accurate test status in Eclipse locally as well.
Running JUnit Scripts in Parallel
LambdaTest offers parallel testing to cut short your test execution cycle. As can be observed in the figure below, the same test suite is found running and passing successfully in the LambdaTest dashboard on 3 different desktop environments which were configured in the test framework effortlessly.
Configurations passed via test framework is:
env.add(new String[]{“WIN10”, “chrome”, “70.0”});
env.add(new String[]{“macos 10.12”,“firefox”,“62.0”});
env.add(new String[]{“WIN8”,“internet explorer”,“10”});
Thanks for reading this article! Leave a comment below if you have any questions. Be sure to leave an appreciation message if my writing helped you.
Follow Technoroll for more!
Editorial Staff of the TechnoRoll, are a bunch of Tech Writers, who are writing on the trending topics related to technology news and gadgets reviews.