How to create JUnit Test Suite? (with Examples)
By Hamid Akhtar, Community Contributor - May 12, 2023
The “first test, then code” philosophy that the JUnit test suite advocates for emphasizes preparing test data before writing any actual code. Methods such as these can be thought of as “test a little, code a little, test a little, code a little.” The programmer’s workload is lightened, and debugging time is shortened due to increased productivity and code reliability.
What is a suite in Automation Testing?
- A test case is the smallest possible testing unit in developing automated tests.
- A test suite is a collection of related test cases that can be managed and run as a single unit. You’ll examine test case examples in both manual and automated software testing.
What exactly is a test case in the context of automated testing?
It depends on the type of testing you’re discussing. For example, a test case could refer to a single testing session captured by a record-and-playback tool in end-to-end testing.
What if you’re talking about unit tests?
A single test method could be considered a test case in this situation.
Depending on your needs, you can arrange several test cases into a suite and perform them in parallel or sequentially. For example, if a series of test cases requires sequential operations, such as retrieving data from one process and passing it to another, you can organize their execution. If a set of test cases is unrelated to one another, they can be run in parallel.
Automation Testing allows you to incorporate test cases into a suite in any combination. You can combine test cases from the same module or sub-module or other modules.
- What is a JUnit Test Suite?
- How to run JUnit Test Suite?
- 1. Creating a Test Suite for an Existing Project
- 2. Creating a Test Suite for a New Project
- 3. Creating a Test Suite for Different Test Types
What is a JUnit Test Suite?
Many different scenarios need to be tested in large-scale projects. To have your testers execute each group of tests according to your specifications, you will likely wish to organize them into groups. Some tests may take significantly longer to execute than others, and some may even use an API call. These tests are unnecessary for every test case run and should be skipped. To keep these tests distinct from others, you can use test suites.
The JUnit test suite facilitates the grouping and execution of test cases from multiple classes. Using JUnit test suites, multiple tests can be run simultaneously. In most circumstances, testing each possible class individually is not preferable. The use of test suites is crucial in reaching this categorization goal.
Junit 4 and Junit 5
Let us begin with the older version, JUnit 4, which has several obvious limitations:
- The complete framework is contained in a single jar library. Even if you just need one functionality, you must import the entire library. You have more granularity in JUnit 5 and can import only what is required.
- In JUnit 4, only one test runner (e.g., SpringJUnit4ClassRunner or Parameterized) can run tests simultaneously. JUnit 5 allows many runners to run at the same time.
- JUnit 4 never expanded beyond Java 7, because it lacked many of the features in Java 8. JUnit 5 makes effective use of Java 8 features.
- JUnit 5 was designed to entirely redesign JUnit 4 to eliminate most of these problems.
Follow-Up Read: How to run JUnit 4 test cases in JUnit 5
How to run JUnit Test Suite?
1. Creating a Test Suite for an Existing Project
Follow these steps to develop a test suite in Eclipse:
- Navigate to the project where you want to create the test suite in Eclipse.
- In the package explorer pane, right-click on the project and choose “New” from the context menu.
- Select “JUnit” from the list of available options in the new window, followed by “JUnit Test Suite” from the sub-menu.
- To move to the next step, use the “Next” button.
- The name and location of the test suite can be specified in the following box. Make sure to choose a location.
- To complete the test suite, click the “Finish” button.
- After you’ve created the test suite, you can add individual test cases by right-clicking on it in the Package Explorer pane and selecting “Add New Test” from the context menu.
- In the next window, you can give the new test case a name and a location. Make certain that you choose a location within the test suite’s package.
- To complete the test scenario, click the “Finish” button.
- Repeat the preceding steps to add more test cases to the test suite.
- Once you’ve added all of the test cases to the test suite, you can run it by right-clicking on it in the Package Explorer pane and selecting “Run As” for “JUnit Test” from the context menu.
- This will run all test cases in the test suite and show the results in the JUnit view.
2. Creating a Test Suite for a New Project
The procedures below can be used to construct a test suite in Eclipse:
- Navigate to the project where you want to build the test suite in Eclipse.
- Right-click the project in the package explorer pane and choose “New” from the context menu.
- Pick “JUnit” from the drop-down menu in the new window, then pick “JUnit Test Suite” from the sub-menu.
- To move on to the next phase, click “Next”.
- You can specify the test suite’s name and location in the following window. Choose a site that is located in the project’s source folder.
- To finish building the test suite, click “Finish”.
- Individual test cases can be added to a test suite after it has been created by right-clicking the test suite in the Package Explorer pane and choosing “Add New Test” from the context menu.
- The name and location of the new test case can be entered in the following window. Select a location from the test suite’s package carefully.
- To finish creating the test case, click “Finish”.
- Follow the same procedure to add more test cases to the test suite.
- The test suite can be performed entirely when all test cases have been created by right-clicking on the test suite in the Package Explorer pane and choosing “Run As” for “JUnit Test” from the context menu.
3. Creating a Test Suite for Different Test Types
A test suite is a collection of test cases that is used to execute tests and track their progress. It is a term that is widely used in the creation of software applications. It enables you to organize many test cases according to your needs for test planning or analysis.
A test suite for product purchasing could contain the following test cases:
- Test Case 1: Login.
- Test Case 2: Adding Products.
- Test Case 3: Checkout.
- Test Case 4: Logout.
The testing team and the business stand to gain in several ways from this. Among the most crucial features are:
- A set makes them of tests.
- It has a battery of tests and test cases to ensure proper operation.
- It describes the reasons for creating the test cases.
- Included are test criteria such as software, operating system, and version.
- You can make one of these based on the length and frequency of your tests.
- It encompasses a wide range of tests, from functional to non-functional.
- It allows for rapid application testing and evaluation.
Test suite categories; are split into two groups with distinct purposes, namely:
- Abstract test suite: It is a model-based testing component consisting of a set of abstract test cases taken from a high-level model of the system under test. The software team cannot use these directly because they are always at a high level and do not provide detailed information about the software application and test environment.
- Executable test suite: It is built from abstract test cases and can be run. It provides the most fundamental, low-level information for a program to function. It has fine-grained control and can interact with the application under test in meaningful ways.
The basic objective is to find the loopholes in a test such that each test case can be completed successfully before moving on to the next.
In sequential mode, you can halt the entire suite of tests if a single test fails. When one test case’s predicted result is contingent on the outcomes of other tests, pausing the test run could prove useful.
Creating a Basic JUnit Test Suite
Let’s understand a JUnit test suite example by Setting up a Sample Project
- A test suite groups and runs several unit test cases at once. The suite tests in JUnit are executed using both the @RunWith and @Suite annotations. This section uses TestJunit1 and TestJunit2 as two test classes running simultaneously using the Test Suite.
- Make a test Java class under C:\>JUNIT_WORKSPACE, such as MessageUtil.java.
/* * This class prints the given message on console. */ public class MessageUtil { private String message; //Constructor public MessageUtil(String message){ this.message = message; } // prints the message public String printMessage(){ System.out.println(message); return message; } public String salutationMessage(){ message = "Hello!" + message; System.out.println(message); return message; } }
Creating Test Classes
- In C:\>JUNIT_WORKSPACE, create a Java class file called TestJunit1.java.
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals; public class TestJunit1 { String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); assertEquals(message, messageUtil.printMessage()); } }
- In C:\>JUNIT_WORKSPACE, create a Java class file called TestJunit2.java.
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals; public class TestJunit2 { String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hello!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } }
Creating a Test Suite
- Construct a Java class.
- Add the annotation @RunWith(Suite.class) to the class.
- Making use of the @Suite.SuiteClasses annotation, add references to JUnit test classes.
- To run the test case(s), create a Java class file called TestSuite.java in C:\>JUNIT_WORKSPACE.
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ TestJunit1.class, TestJunit2.class }) public class JunitTestSuite { }
- Create Test Runner Class
- To execute the test case(s), create a java class file named TestRunner.java in C:\>JUNIT_WORKSPACE.
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(JunitTestSuite.class); for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); } System.out.println(result.wasSuccessful()); } }
Running the Test Suite
- Compile all of the Java classes with javac.
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit1.java TestJunit2.java JunitTestSuite.java TestRunner.java
Execute the Test Runner, which will execute the test case defined in the specified Test Case class.
C:\JUNIT_WORKSPACE>java TestRunner
Check the output.
Inside testPrintMessage() Robert Inside testSalutationMessage() Hello Robert true
Grouping Tests using JUnit Test Suite
You want your unit tests to execute as fast as possible and provide you with as much information as possible at the beginning of a well-organized build process. Having the option to organize your tests into distinct groups is a helpful instrument for this.
- This can help you tell the difference between quick-running unit tests and longer-running integration, performance, load, or acceptance tests, for instance.
- Using JUnit Categories, you can organize your tests into logical groups and run them independently of one another. For instance, you can differentiate between fast and slow tests.
- Annotations allow you to choose which classes to include or dismiss. The @Category annotation is available for labeling test cases and methods with one of these groups.
Grouping Tests using JUnit Categories
You need to establish your categories first: FastTests and SlowTests.
FastTests.java
public interface FastTests { /* category marker */ }
SlowTests.java
public interface SlowTests { /* category marker */ }
A class or an interface can both be considered categories. Method b() of class A is annotated with the @category keyword in the code below.
Indicating that method b() falls under the SlowTests category. By doing this, you were able to mark each test method separately in addition to the entire class.
import org.junit.Test; import org.junit.experimental.categories.Category; public class A { @Test public void a() { System.out.println("a() method of class A has been run...\n"); } @Category(SlowTests.class) @Test public void b() { System.out.println("b() method of class A has been run...\n"); } }
Class B is marked with the @Category annotation in the code below. As a result, this category includes all of the test methods for this test class.
You can see that a test class or test method can be categorized under multiple categories.
import org.junit.Test; import org.junit.experimental.categories.Category; @Category({SlowTests.class, FastTests.class}) public class B { @Test public void c() { System.out.println("c() method of class B has been run...\n"); } }
Running Test Groups
- You can see that the name of your test suite is SlowTestFirstSuite in the code below.
- A test suite can also be categorized. Which categories will be executed are indicated by the annotation @IncludeCategory.
- The SlowTest category is present in the example below and will be used.
- As a result, the test methods b() of class A and c() of class B will be run.
SlowTestFirstSuite.java import org.junit.experimental.categories.Categories; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Categories.class) @Categories.IncludeCategory(SlowTests.class) @Suite.SuiteClasses({ A.class, B.class }) // Note that Categories is a kind of Suite public class SlowTestsFirstSuite { // b() method of class A has been run... // c() method of class B has been run... }
- The code below has an annotation called @ExcludeCategory that specifies which categories will not be executed.
- The test method b() of class A will be run in the code sample below, but methods a() and c() of class A and class B won’t be run because they are excluded from execution by the @ExcluedeCategory annotation.
- Because it is not in any category, the test method a() of class A will not be run in either scenario.
import org.junit.experimental.categories.Categories; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Categories.class) @Categories.IncludeCategory(SlowTests.class) @Categories.ExcludeCategory(FastTests.class) @Suite.SuiteClasses({ A.class, B.class }) // Note that Categories is a kind of Suite public class SlowTestsSecondSuite { //b() method of class A has been run... }
Advanced JUnit Test Suite Techniques
In a test class, JUnit enables developers to use parameters.
- Using the annotation, the test class can be identified as a parameterized test: @RunWith(Parameterized.class)
- A static method with the @Parameters annotation that create
- s and returns a Collection of Arrays must be present in the test class. Each object in this collection is one of the test method’s parameters.
- When a parameterized test class is run, instances of the test methods and the test data components are produced for the cross-product (binary operation of two arrays).
- Each test’s values will be stored in the public constructor. The number of elements in each array that is supplied by the method with the @Parameters annotation must match the number of elements in the constructor of the class. The constructor passes each parameter’s class and test values to the class.
- In JUnit 5, the Assumptions class allows you to use static methods to set conditions for test execution. These conditions will be based on your assumptions; if one fails, the test will be aborted (rather than failing, as with assertions). They allow you to programmatically determine whether to continue running tests, saving you a significant amount of time and perhaps computing bandwidth during testing.
- It can be useful to temporarily disregard some test scenarios. You can use the @Disabled annotation to prevent those tests (individual test methods or entire test classes) from running. In the test report, any @Disabled test method will be noted as disabled. @Disabled allows you to indicate a rationale for deactivating the test as a parameter.
- Nested test classes can be used to organize tests that should be together logically.
- Using the @Timeout annotation allows you to specify a maximum time for the execution of a test method. If the test takes longer to execute than the duration you selected (which is by default defined in seconds), @timeout will simply fail the test.
Using JUnit Rules
- A rule changes how a test method or methods are conducted or reported.
- The @Rule annotation indicates that the class implements the TestRule interface.
- The @ClassRule annotation corresponds to the TestRule class.
- Rules allow you to write code to inspect a test before it is run, change how and whether it is run, and inspect and alter the test results.
- A rule implementation can intercept test method execution and change the behavior of these tests, or it can include cleaning work like @Before, @After, @BeforeClass, and @AfterClass.
- The rules notion is similar to JUnitRunners, but with the added feature of combining different rules. When combining many Runners, it is best to use rule cases.
Using JUnit Extensions
JUnit 5 extensions are associated with a specific event during test execution known as an extension point. The JUnit engine invokes registered extensions when a given life cycle phase is reached.
Five primary types of extension points can be used:
- test instance post-processing
- conditional test execution
- life-cycle callbacks
- parameter resolution
- exception handling
To construct a JUnit 5 extension, you must specify a class that implements one or more interfaces corresponding to the JUnit 5 extension points. These interfaces extend the core Extension interface, which is merely a marker interface.
Best Practices for JUnit Test Suites
1. Naming Conventions
- The test names should be insightful, and users should be able to grasp the test’s behavior and expectations simply by looking at the name.
- givenEmployeeObject_whenSaveEmployee_thenReturnSavedEmployee
- givenEmployeesList_whenFindAll_thenReturnListOfEmployees
- givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee
2. Test Organization
- Separating the test classes from the production code is recommended. This means they are created, run, and maintained independently from the code used in production.
- In addition, it eliminates the risk of having development code executed in the production environment.
3. Test Suite Maintenance
- Make sure that each test is written independently of the others.
- So, whenever you write multiple Unit tests, ensure that they are all independent of one another. This will assist you in determining the root problem and correctly testing the logic unit.
- Use the @BeforeEach and @AfterEach annotations to put up any prerequisites for all of your test cases. The @BeforeEach and @AfterEach methods in the current class execute before and after each method annotated with @Test, @RepeatedTest, @ParameterizedTest, or @TestFactory.
- JUnit conducts tests in any sequence by default. To modify the order of test execution, just annotate your test class with @FixMethodOrder and pick one of the available MethodSorters:
- @FixMethodOrder(MethodSorters.JVM): Leaves the test methods in the order returned by the JVM. This order may differ from run to run.
- @FixMethodOrder(MethodSorters.NAME_ASCENDING): Sorts the test methods in lexicographic order by the method name.
What is the use of suite in JUnit 5?
The @Suite annotation is used to create test suites in JUnit 5. Suites facilitate the execution of tests dispersed over various classes and packages. To narrow down your test cases, you can take advantage of the Include and Exclude annotations.
To specify which tests should be included or excluded from a given suite, JUnit 5 offers the following annotations.
- @SelectClasses
- @SelectPackages
- @IncludePackages
- @ExcludePackages
- @IncludeClassNamePatterns
- @ExcludeClassNamePatterns
- @IncludeTags
- @ExcludeTags
Closing Notes
- JUnit testing in Java is the most used since it is resilient and constantly growing to improve test case execution. It has become a popular option for the test-driven development cycle.
- Selenium is a useful tool for automated web testing, and it works even better when combined with JUnit.
- JUnit allows for the use of numerous assertions and annotations. Developers can easily execute unit testing in Java with Selenium using BrowserStack Automate.
- It’s easy to use JUnit 5 on BrowserStack to run your Selenium tests.