JUnit Testing Tutorial: JUnit in Java

Learn what JUnit is and how to write and run automated tests in Java. Run JUnit tests with Selenium on real browsers and devices using BrowserStack to validate functionality under real-world scenarios.

Get Started free
Guide Banner Image
Home Guide JUnit Testing Tutorial: JUnit in Java

JUnit Testing Tutorial: JUnit in Java

JUnit helps developers validate code behavior early in the development cycle and supports test-driven development.

Overview

What is JUnit?

JUnit is an open-source framework used to write and execute repeatable unit tests in Java. It is part of the xUnit family of testing frameworks and provides annotations, assertions, and test runners to streamline test creation and execution.

Benefits of JUnit Testing in Java

Here are some key benefits of JUnit testing in Java:

    • Accelerated development workflow: Writing tests alongside your code helps you make changes confidently and reduces debugging time.
    • Improved code maintainability: JUnit encourages you to split code into smaller parts that are easier to test and maintain.
    • Integration with development tools: JUnit works well with build tools like Maven and Gradle, and can run automatically in CI pipelines.
  • Consistent test structure: JUnit provides a clear, standardized way to write and organize tests, making them easier to read and maintain across teams.

Key Aspects of JUnit Testing in Java

Understanding JUnit requires familiarity with its basic components and how they work together in a test cycle.

  • Unit testing: Focuses on testing individual methods or components in isolation.
  • Annotations: JUnit uses annotations like @Test, @Before, and @After to define test behavior.
  • Assertions: Validates expected outcomes by comparing actual results to expected values using methods like assertEquals, assertTrue, etc.

This article explains how to get started with JUnit in Java, use its annotations and assertions, and run tests from an IDE or build system.

What is JUnit Framework?

JUnit is a testing framework used to write and run tests in Java. It helps developers check whether individual parts of their code, like methods or classes, are working as expected. These checks are called unit tests, and they focus on testing one specific unit of logic at a time.

Instead of manually checking outputs, JUnit lets you automate the process. You write test cases that define what the correct output should be for a given input. When you run your tests, JUnit automatically runs each one and reports which tests passed and which failed.

Benefits of JUnit Testing Framework

While JUnit is a primitive way to test Java-based projects, it provides many advantages.

Following are a few benefits of using the JUnit Testing Framework:

  • Open Source: JUnit is an open-source testing framework. Hence, a broader community can contribute to the software. That leads to better and faster development from developers across the world.
  • Early bug-finder: JUnit finds the bug early in code compared to other test frameworks. When a bug is found, it is indicated in a separate section until it is resolved. This helps drive focus on debugging.
  • Best for Test-Driven Development (TDD) Environment: To push the least bugs to QA teams, many engineering teams pick a test-driven development cycle. Developers first perform tests, and issues are resolved before taking the build for QA testing. JUnit uses assertions in the tests, which are most efficient when they fail. So, JUnit helps in the TDD build of the software.

Also Read: JUnit Vs TestNG

JUnit 5: Features and Extensions

JUnit 5 is a significant upgrade from the JUnit 4 framework. It introduces a modular architecture, cleaner APIs, and more flexible extension mechanisms to support modern Java development practices.

Here are some new features in JUnit 5.

  • Modular architecture: The framework is divided into JUnit Platform, JUnit Jupiter, and JUnit Vintage for better separation of concerns and easier integration.
  • Updated annotations: Replaces older lifecycle methods with clearer annotations like @BeforeEach, @AfterEach, @BeforeAll, and @AfterAll.
  • Improved test naming and structure: Offers @DisplayName for custom test names and @Nested for grouping related tests within inner classes.
  • Parameterized tests: Allows running the same test with different inputs using @ParameterizedTest and sources like @ValueSource or @CsvSource.
  • Dynamic tests: Supports generating tests at runtime with @TestFactory, which is helpful for data-driven testing scenarios.
  • Richer assertions: Provides advanced assertions like assertAll, assertThrows, and assertTimeout to write more meaningful tests.
  • Assumptions for conditional execution: Lets you skip tests when certain conditions aren’t met using assumeTrue, assumeFalse, or assumingThat.

Extensions in JUnit 5

JUnit 5 introduces a flexible Extension API to replace the older Runner and Rule mechanisms, making adding custom behavior to tests easier.

  • Flexible extension points: Includes callbacks like BeforeEachCallback, AfterAllCallback, and TestExecutionExceptionHandler.
  • Annotation-based registration: Apply extensions using @ExtendWith on test classes or methods.
  • Programmatic registration: Use @RegisterExtension for fine-grained control in specific test scenarios.
  • Supports parameter resolution: Inject test parameters using custom or built-in resolvers.

How to Set Up JUnit Testing

Setting up JUnit in your Java project depends on the version you’re using: JUnit 4 or JUnit 5. Both versions can be added using build tools like Maven or Gradle, or directly by adding JAR files to your project classpath.

Setting Up JUnit 5 Testing

JUnit 5 is built on a modular architecture and requires dependencies from the JUnit Jupiter and JUnit Platform components. It does not work with the old JUnit 4 @Test imports, and you need to use the JUnit 5 annotations from the org.junit.Jupiter package.

Using Maven: Add the following dependencies in your pom.xml:

<dependencies>

  <dependency>

    <groupId>org.junit.jupiter</groupId>

    <artifactId>junit-jupiter</artifactId>

    <version>5.10.0</version>

    <scope>test</scope>

  </dependency>

</dependencies>

Using Gradle:

testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'

Note: To run JUnit 5 tests with Gradle, enable the JUnit Platform:

test {

    useJUnitPlatform()

}

Setting Up JUnit 4 Testing

JUnit 4 is the older version, but it is still widely used in many existing Java projects. It uses a single JAR and relies on annotations from the org.junit package, such as @Test, @Before, and @After.

Using Maven:

<dependencies>

  <dependency>

    <groupId>junit</groupId>

    <artifactId>junit</artifactId>

    <version>4.13.2</version>

    <scope>test</scope>

  </dependency>

</dependencies>

Using Gradle:

testImplementation 'junit:junit:4.13.2'

JUnit 4 tests run by default in most IDEs and build tools without additional configuration.

BrowserStack Automate Banner

Annotations in JUnit Testing

JUnit is made up of assertions and annotations that are implemented in the code while testing. Annotations are the indicators in JUnit that tell the compiler what to do with the code following the annotation. For example, an annotation of @Test in JUnit indicates that the code following this annotation has the testing code in it.

JUnit annotations are very simple. Below listed are a few annotations:

@Before

Before annotation is used to run code before every test in JUnit. This is used to initialize methods before the test executions. This can be creating the entry in the database or initializing variables or other. As an example:

public class BrowserTest{
@Before
public void beforeTest(){
//Code to run before test
}
}

@Test

Test annotation contains the code for the initial test. It executes after the @Before code has been executed (if you have placed it).

public class BrowserTest{
@Before
public void beforeTest(){
// Code to run before the test
}

@Test
public void testingCode(){
//code for testing
}
}

@After

After annotation is used to indicate the code that has to run after the testing code has been executed. This is usually used to destroy the variables and free up memory.

public class BrowserTest{
@Before
public void beforeTest(){
// Code to run before the test
}

@Test
public void testingCode(){
//code for testing
}

@After
public void afterTest(){

//code after testing
}
}

@BeforeClass

The BeforeClass annotation indicates the code to run before running all the tests. This code runs once and must be static.

public class BrowserTest{

@BeforeClass
public static void beforeClassTest(){
// Code to run once before the test.
}

@Before
public void beforeTest(){
// Code to run before the test
}

@Test
public void testingCode(){
//code for testing
}

@After
public void afterTest(){

// Code after testing
}
}

@Beforeclass Code runs just once while the @Before Code runs every time the test needs to run. If the test has to run 10 times, @Before gets executed ten times while the @BeforeClass runs only once.

@AfterClass

AfterClass annotation indicates that the code following this annotation is executed after all the tests have been executed.

public class BrowserTest{

@BeforeClass
public static void beforeClassTest(){
// Code to run once before the test.
}

@Before
public void beforeTest(){
// Code to run before the test
}

@Test
public void testingCode(){
//code for testing
}

@After
public void afterTest(){

//code after testing
}
@AfterClass
public static void afterClassTest(){
//Code to run after the test
}
}

Like the @BeforeClass, @AfterClass runs once when all the tests are executed. So, we have briefed ourselves with the annotations, and now let us use them along with Selenium to test our code.

JUnit Assertions

Assertions are used to verify that the actual output of your code matches the expected output. If an assertion fails, JUnit marks the test as failed and displays an error message, helping you quickly identify issues in your logic.

In both JUnit 4 and JUnit 5, assertions are written using static methods from a dedicated assertions class:

  • In JUnit 4, assertions come from org.junit.Assert
  • In JUnit 5, they come from org.junit.jupiter.api.Assertions

JUnit 5 offers a broader and more flexible set of assertions, making tests more expressive and easier to manage.

To use assertions in JUnit 5, import them statically:

import static org.junit.jupiter.api.Assertions.*;

Common Assertions in JUnit 5

Here are some commonly used assertion methods:

  • assertEquals(): Checks whether two values are equal.
  • assertNotEquals(): Confirms that two values are not equal.
  • assertTrue(): Passes if the given condition is true.
  • assertFalse(): Passes if the given condition is false.
  • assertNull(): Passes if the object is null.
  • assertNotNull(): Passes if the object is not null.
  • assertThrows(): Verifies that a specific exception is thrown.
  • assertAll(): Groups multiple assertions and reports all failures together.
  • assertTimeout(): Ensures a block of code completes within a given time limit.
  • assumeTrue(), assumeFalse(): Skips a test if certain conditions aren’t met.

How to Run JUnit Tests from the IDE

Running JUnit tests directly from your IDE (such as IntelliJ IDEA or Eclipse) is simple and ideal for development workflows.

Here are the prerequisites to set up JUnit tests in your IDE:

  1. Install JDK: Ensure Java is installed and configured (JAVA_HOME set).
  2. Add JUnit to your project:
    • If using Maven or Gradle, add the JUnit dependency (junit:junit for JUnit 4, org.junit.jupiter:junit-jupiter for JUnit 5).
    • If not using a build tool, download the JUnit JAR and add it to your classpath.
  3. Create a Test Class: Use annotations like @Test to define test methods.

Once the prerequisites are met, you can run your JUnit tests easily within your IDE:

1. In IntelliJ IDEA:

  • Right-click the test class or method in the editor or Project panel.
  • Select Run ‘YourTestClass’.
  • View results in the test runner tab.

2. In Eclipse:

  • Right-click the test class or method.
  • Choose Run As > JUnit Test.
  • Results appear in the JUnit view.

Tip: Both IDEs allow you to run individual tests, all tests in a class, or even all tests in a package.

How to Run JUnit Tests Using Build Systems

Build tools like Maven and Gradle compile, package, and automate test execution, which is especially useful in CI pipelines.

Here are the prerequisites to set up JUnit tests with a build system:

1. Install JDK: Ensure Java is installed and configured (JAVA_HOME set).

2. Set Up Your Project:

  • For Maven, create a pom.xml and add the JUnit dependency:
 <dependency>

  <groupId>org.junit.jupiter</groupId>

  <artifactId>junit-jupiter</artifactId>

  <version>5.10.0</version>

  <scope>test</scope>

</dependency>
  • For Gradle, create a build.gradle with:
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'

test {

    useJUnitPlatform()

}
  • Create Test Classes: Place them in src/test/java and annotate with @Test.

Once the prerequisites are met, you can run your JUnit tests using the build tool commands:

  • Using Maven: Use this command to compile the project and automatically run all tests:
mvn test
  • Using Gradle: Use this command to execute tests and generate an HTML test report at build/reports/tests/test/index.html:
./gradlew test

How to Perform JUnit Testing with Selenium?

JUnit can be integrated with Selenium to automate web application testing. This approach falls under automation testing, as it allows test cases to be executed programmatically without manual intervention.

In this context, a common use case is validating login functionality using both valid and invalid credentials. Tests are executed on real browsers and devices using BrowserStack to ensure accurate results across different environments.

import java.util.concurrent.TimeUnit;

import org.junit.AfterClass; //Importing all the JUnit and Selenium classes
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class FirstTest {
private static FirefoxDriver driver;
WebElement element;

@BeforeClass
public static void openBrowser(){
driver = new FirefoxDriver(); //Initialising the browser driver
}

@Test
public void validUserCredentials(){ //To test successful login

System.out.println("This is the test code " + new Object(){}.getClass().getEnclosingMethod().getName());
driver.get("https://www.browserstack.com");
driver.findElement(By.xpath(".//*[@id='account']/a")).click();
driver.findElement(By.id("log")).sendKeys("userid"); //Sending ID
driver.findElement(By.id("pwd")).sendKeys("userpassword"); // Sending PWD
driver.findElement(By.id("login")).click();
try{
element = driver.findElement (By.xpath(".//*[@id='account_logout']/a"));
}catch (Exception e){
}
Assert.assertNotNull(element); //Checking the element presence
System.out.println("Test End " + new Object(){}.getClass().getEnclosingMethod().getName());
}

@Test
public void WrongUserCredentials()
{
System.out.println("Starting test " + new Object(){}.getClass().getEnclosingMethod().getName());
driver.get("https://www.browserstack.com");
driver.findElement(By.xpath(".//*[@id='account']/a")).click();
driver.findElement(By.id("log")).sendKeys("userid");
driver.findElement(By.id("pwd")).sendKeys("userpassword"); //Entering wrong pwd
driver.findElement(By.id("login")).click();
try{
element = driver.findElement (By.xpath(".//*[@id='account_logout']/a"));
}catch (Exception e){
}
Assert.assertNotNull(element);
System.out.println("Ending test " + new Object(){}.getClass().getEnclosingMethod().getName());
}

@AfterClass
public static void closeBrowser(){
driver.quit(); //Closing the driver once the tests are executed
}
}

The above test is just a sample test to show how JUnit and Selenium work together.

Talk to an Expert

Conclusion

JUnit is a widely adopted testing framework that simplifies writing and executing unit tests in Java. With support for clear annotations, rich assertions, and flexible extensions, JUnit helps ensure that individual application components behave as expected. It also promotes better code quality, faster debugging, and smoother development workflows.

JUnit can be integrated with Selenium and run on BrowserStack to ensure web applications work seamlessly across browsers and devices. BrowserStack enables cross-browser testing at scale by allowing teams to automate login flows, form submissions, and other UI checks on real user conditions.

Try BrowserStack for Free

Tags
Automation Testing Testing Tools