Testing concurrent code question 160 of 180 mid
Why is Thread.sleep in a test a bug rather than a delay?
- It is fine if the sleep is long enough
- Correct: It encodes a guess about timing: too short and the test is flaky, too long and the suite crawls, and it never proves the condition was met
- It does not compile in JUnit 5
- It only fails on Windows
A sleep says "this will probably have happened by now". On a loaded CI machine it will not, and the test fails for reasons unrelated to the code. Lengthen it and every run pays the cost, so a suite of two hundred such tests takes ten minutes to tell you nothing.
Wait for the condition instead of for the clock: a CountDownLatch the code under test counts down, a
BlockingQueue.poll(timeout), a Future.get(timeout), or a small polling helper that checks a
predicate every millisecond up to a deadline. Each fails fast with a clear message and passes as soon
as the work is done.
static void await(Duration timeout, BooleanSupplier condition) throws InterruptedException {
long deadline = System.nanoTime() + timeout.toNanos();
while (!condition.getAsBoolean()) {
if (System.nanoTime() > deadline) {
throw new AssertionError("condition not met within " + timeout);
}
Thread.sleep(1);
}
}
Quiz yourself on Testing concurrent code Suggest a correction