Assumptions are a different beast from assertions. While assertions fail the test when a condition is not met, assumptions skip the test. This is useful when a test only makes sense under certain conditions.
Assumptions vs Assertions
+------------------+---------------------------+---------------------------+
| | Assertion | Assumption |
+------------------+---------------------------+---------------------------+
| Condition true | Test continues | Test continues |
| Condition false | Test FAILS | Test is SKIPPED |
| Purpose | Verify behavior | Check prerequisites |
| Import | Assertions.* | Assumptions.* |
+------------------+---------------------------+---------------------------+
Basic Assumptions
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
class AssumptionsTest {
@Test
void onlyOnLinux() {
Assumptions.assumeTrue(
System.getProperty("os.name").contains("Linux"),
"Skipping: not running on Linux"
);
// This test only runs on Linux
linuxSpecificTest();
}
@Test
void notOnWindows() {
Assumptions.assumeFalse(
System.getProperty("os.name").contains("Windows"),
"Skipping: running on Windows"
);
// This test runs on everything except Windows
}
@Test
void onlyWithDatabase() {
Assumptions.assumeTrue(
System.getenv("DATABASE_URL") != null,
"Skipping: DATABASE_URL not set"
);
// This test only runs when database is available
}
}
Assumption Methods
// assumeTrue - skip if condition is FALSE
Assumptions.assumeTrue(condition);
Assumptions.assumeTrue(condition, "reason message");
// assumeFalse - skip if condition is TRUE
Assumptions.assumeFalse(condition);
Assumptions.assumeFalse(condition, "reason message");
// assumingThat - run nested code only if condition is true
Assumptions.assumingThat(condition, () -> {
// Only executes if condition is true
// No assertion failure if condition is false โ test still passes
});
Practical Examples
class EnvironmentAwareTest {
@Test
void shouldWorkInCI() {
Assumptions.assumeTrue(
System.getenv("CI") != null,
"Skipping: not in CI environment"
);
// Test that only makes sense in CI
}
@Test
void shouldWorkWithExternalService() {
Assumptions.assumeTrue(
isServiceAvailable("https://api.example.com"),
"Skipping: external service not reachable"
);
// Test that depends on external service
}
@Test
void needsSpecificJavaVersion() {
Assumptions.assumeTrue(
Runtime.version().feature() >= 17,
"Skipping: requires Java 17+"
);
// Test using Java 17 features
}
@Test
void assumingThatExample() {
boolean isDebug = System.getProperty("debug") != null;
// Always runs
assertEquals(4, 2 + 2);
// Additional assertions only in debug mode
Assumptions.assumingThat(isDebug, () -> {
assertEquals(4, 2 + 2);
System.out.println("Running extra checks in debug mode");
});
}
}
When Assumptions Fail
When an assumption fails, the test is aborted, not failed. In your test report, it shows as "skipped" or "aborted" rather than "failed":
Tests run: 10, Skipped: 2, Failed: 0
shouldWorkOnLinux SKIPPED (not running on Linux)
shouldUseExternalService SKIPPED (service not available)
other tests PASSED
Common Use Cases
- Platform-specific tests - Only run on certain operating systems
- Environment-dependent - Only run when specific env vars are set
- External service availability - Only run when API/database is up
- Java version requirements - Only run on specific JDK versions
- CI vs local - Different behavior in CI vs development