Testing in Java: Overview of Frameworks and Tools
Quality testing is an integral part of professional Java development. Without automated tests, it is difficult to maintain large projects, introduce new features, and avoid regression errors. In this article, we will review the key tools and frameworks for testing Java applications: from unit tests to integration checks and UI automation.
Why is it important to test Java code?
Tests allow you to:
- Detect errors in the early stages of development.
- Simplify refactoring — you immediately see what broke.
- Document code behavior.
- Automate regression checks with every commit.
JUnit 5 — the foundation of unit testing
JUnit 5 is the de facto standard for unit testing in Java. It consists of three modules: JUnit Platform, JUnit Jupiter, and JUnit Vintage. Jupiter provides a new programming model with annotations and extensions.
Basic test example with JUnit 5:
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); assertEquals(5, calc.add(2, 3), "2 + 3 should be 5"); }}Mockito — creating stubs and mocks
When testing, you often need to isolate a class from its dependencies (databases, external APIs). Mockito allows you to create mock objects and define their behavior.
Example of using Mockito with JUnit 5:
import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.junit.jupiter.MockitoExtension;import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)class UserServiceTest { @Mock private UserRepository repository;
@InjectMocks private UserService service;
@Test void testFindUser() { when(repository.findById(1L)).thenReturn(new User("Alice")); User result = service.findUser(1L); assertEquals("Alice", result.getName()); verify(repository).findById(1L); }}TestNG — an alternative to JUnit with extended capabilities
TestNG (Test Next Generation) is a framework inspired by JUnit, but adds support for test groups, parameterization, dependencies, and parallel execution. It is especially popular in large projects and for integration testing.
Example of a parameterized test in TestNG:
import org.testng.annotations.DataProvider;import org.testng.annotations.Test;import static org.testng.Assert.assertEquals;
public class ParamTest { @DataProvider(name = "numbers") public Object[][] data() { return new Object[][] { {1, 2, 3}, {0, 0, 0}, {-1, 1, 0} }; }
@Test(dataProvider = "numbers") public void testAdd(int a, int b, int expected) { assertEquals(a + b, expected); }}Selenium — web interface automation
For testing Java web applications (e.g., on Spring Boot), Selenium WebDriver is often used. It allows you to emulate user actions in the browser: clicks, text input, element verification.
Minimal Selenium test example:
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.junit.jupiter.api.Test;
public class LoginTest { @Test public void testLoginPage() { WebDriver driver = new ChromeDriver(); driver.get("https://example.com/login"); driver.findElement(By.id("username")).sendKeys("admin"); driver.findElement(By.id("password")).sendKeys("pa