Deterministic tests in JUnit - Build an Automation Script
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import java.util.Random; import org.junit.jupiter.api.Test; public class DeterministicRandomTest { @Test void testRandomSequenceIsDeterministic() { int seed = 12345; Random random1 = new Random(seed); int[] sequence1 = new int[5]; for (int i = 0; i < 5; i++) { sequence1[i] = random1.nextInt(); } Random random2 = new Random(seed); int[] sequence2 = new int[5]; for (int i = 0; i < 5; i++) { sequence2[i] = random2.nextInt(); } assertArrayEquals(sequence1, sequence2, "Random sequences should be identical with the same seed"); } }
This test creates two Random objects with the same fixed seed (12345). Because the seed is fixed, the sequence of numbers generated by both Random instances will be the same.
We generate 5 integers from each Random object and store them in arrays. Then we use assertArrayEquals to verify both arrays are identical.
This ensures the test is deterministic, meaning it will always produce the same result every time it runs, which is important for reliable automated tests.
The test method is annotated with @Test from JUnit 5, and the code uses clear variable names and comments to keep it easy to understand.
Now add data-driven testing with 3 different seeds to verify deterministic sequences for each seed
Practice
Solution
Step 1: Understand the meaning of deterministic
Deterministic means something behaves the same way every time under the same conditions.Step 2: Apply this to JUnit tests
A deterministic test always gives the same result when run with the same input and environment.Final Answer:
It always produces the same result given the same input -> Option AQuick Check:
Deterministic = Same result every time [OK]
- Confusing deterministic with fast execution
- Thinking random data makes tests deterministic
- Assuming external services guarantee determinism
Solution
Step 1: Identify deterministic assertions
Deterministic assertions compare known expected values to actual results.Step 2: Check each option
assertEquals(expected, actual); compares expected and actual values directly, which is deterministic. Options A, B, and D depend on random or external calls, which are not deterministic.Final Answer:
assertEquals(expected, actual); -> Option DQuick Check:
Deterministic assertions compare fixed expected and actual values [OK]
- Using random values inside assertions
- Calling external services in assertions
- Assuming assertNull is always deterministic
int result = calculator.add(2, 3); assertEquals(5, result);
What will be the test result if the
add method always returns the sum of its inputs?Solution
Step 1: Understand the add method behavior
The add method returns the sum of inputs, so add(2, 3) returns 5.Step 2: Check the assertion
The assertion expects 5 and the actual result is 5, so the assertion passes.Final Answer:
Test will pass because the result matches expected -> Option BQuick Check:
Expected 5, got 5 = pass [OK]
- Thinking 2 + 3 is not 5
- Assuming syntax error without checking code
- Believing test is flaky without randomness
@Test
void testRandomNumber() {
int num = new Random().nextInt(10);
assertTrue(num == 0);
}What is the main reason this test is not deterministic?
Solution
Step 1: Identify randomness in the test
The test generates a random number each run, so output varies.Step 2: Understand impact on determinism
Because the number changes, the test result can vary, making it non-deterministic.Final Answer:
The test depends on random values causing different results -> Option AQuick Check:
Random values cause non-determinism [OK]
- Thinking assertion condition is wrong
- Believing new Random() fixes determinism
- Confusing test annotations with determinism
@Test
void testCurrentTime() {
long time = System.currentTimeMillis();
assertTrue(time > 0);
}Which approach best ensures determinism?
Solution
Step 1: Identify non-deterministic part
System.currentTimeMillis() returns changing time, causing test to vary.Step 2: Apply mocking for fixed value
Replacing it with a fixed mock value makes the test produce the same result every run.Final Answer:
Replace System.currentTimeMillis() with a fixed mock time value -> Option CQuick Check:
Fixed mock values ensure determinism [OK]
- Using sleep does not fix changing values
- Removing assertions hides problems, not fix determinism
- Averaging results does not guarantee same output
Ready to prove it?
Pass the test and this pattern moves unknown
