Test independence in JUnit - Build an Automation Script
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class Calculator { int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } } public class CalculatorTest { private Calculator calculator; @BeforeEach void setUp() { calculator = new Calculator(); } @Test void testAddition() { int result = calculator.add(2, 3); assertEquals(5, result, "2 + 3 should equal 5"); } @Test void testSubtraction() { int result = calculator.subtract(5, 3); assertEquals(2, result, "5 - 3 should equal 2"); } }
This test class CalculatorTest uses JUnit 5 to verify the Calculator methods.
The @BeforeEach method setUp() creates a new Calculator instance before each test. This ensures no shared state between tests.
Each test method (testAddition and testSubtraction) runs independently and asserts expected results using assertEquals.
Running tests individually or together will pass because they do not depend on each other.
Now add a test for multiplication with three different input pairs using parameterized tests
Practice
What does test independence mean in JUnit testing?
Choose the best explanation.
Solution
Step 1: Understand test independence concept
Test independence means tests do not rely on each other's results or states.Step 2: Compare options with definition
Only Each test runs without depending on the results or state of other tests. correctly states that tests run alone without dependencies.Final Answer:
Each test runs without depending on the results or state of other tests. -> Option DQuick Check:
Test independence = tests run alone [OK]
- Thinking tests must run in order
- Sharing data between tests
- Reusing objects without reset
Which JUnit annotation is best used to prepare fresh data before each test to ensure test independence?
Solution
Step 1: Identify setup annotations in JUnit
@BeforeEach runs before every test method, preparing fresh data each time.Step 2: Match annotation to test independence need
@BeforeClass runs once before all tests, not before each, so it doesn't ensure fresh data per test.Final Answer:
@BeforeEach -> Option BQuick Check:
@BeforeEach prepares fresh data [OK]
- Using @BeforeClass which runs only once
- Confusing @AfterAll with setup
- Not using any setup annotation
Consider this JUnit test class snippet:
class CounterTest {
int count = 0;
@Test
void testIncrement() {
count++;
assertEquals(1, count);
}
@Test
void testReset() {
assertEquals(0, count);
}
}What will happen if these tests run in this order without any setup method?
Solution
Step 1: Analyze shared variable usage
The variable count is shared across tests and not reset before each test, leading to order dependency.Step 2: Consider test order impact
If testIncrement runs first: count++ to 1, assert 1 passes (leaves count=1); testReset: assertEquals(0, 1) fails. If testReset first: assert 0 (initial) passes (leaves 0), testIncrement ++ to 1 passes. Thus, testReset may fail due to shared state.Final Answer:
testIncrement passes but testReset may fail due to shared count state. -> Option AQuick Check:
Shared state causes test order dependency [OK]
- Assuming tests run isolated without setup
- Ignoring shared mutable state
- Thinking manual reset in testReset fixes all issues
Identify the problem in this JUnit test class and how to fix it to ensure test independence:
class ListTest {
List<String> list = new ArrayList<>();
@Test
void testAdd() {
list.add("item");
assertEquals(1, list.size());
}
@Test
void testClear() {
list.clear();
assertEquals(0, list.size());
}
}Solution
Step 1: Identify shared mutable state
The list is a shared instance variable and is not reset before each test, causing tests to affect each other.Step 2: Apply proper setup for independence
Initializing the list inside a method annotated with @BeforeEach ensures a fresh list before every test, maintaining independence.Final Answer:
Problem: list is shared and not reset; Fix: initialize list in @BeforeEach method. -> Option AQuick Check:
Use @BeforeEach to reset shared objects [OK]
- Making list final does not reset contents
- Reordering tests does not guarantee independence
- Using static list shares state across tests
You have a JUnit test class where one test modifies a static shared resource, causing other tests to fail intermittently.
How can you redesign the tests to maintain test independence and avoid flaky failures?
Solution
Step 1: Understand static shared resource issue
Static resources are shared across all tests and can cause interference if modified without reset.Step 2: Apply test independence principle
To ensure independence, avoid static shared mutable state or reset it before each test by creating fresh instances in @BeforeEach.Step 3: Evaluate other options
Running tests sequentially or resetting once after all tests does not guarantee independence. Combining tests reduces clarity and independence.Final Answer:
Avoid using static shared resources; initialize fresh instances in @BeforeEach. -> Option CQuick Check:
Fresh instances per test ensure independence [OK]
- Relying on test order or sequence
- Resetting static resource only once
- Merging tests reduces clarity and independence
Ready to prove it?
Pass the test and this pattern moves unknown
