Timeout & Failures
TimeoutConfig
Every Xcepto test runs within a time budget split into two durations:
| Parameter | Covers |
|---|---|
| Total | Scenario setup + initialization + state machine execution |
| Test | State machine execution only |
- .NET
- Java
var timeout = new TimeoutConfig(
total: TimeSpan.FromSeconds(30),
test: TimeSpan.FromSeconds(25));
await XceptoTest.Given(scenario, timeout, builder =>
{
// ...
});
TimeoutConfig.FromSeconds(total) is a convenience factory that sets test slightly below total when total is at least one second.
var timeout = new TimeoutConfig(
Duration.ofSeconds(30), // total
Duration.ofSeconds(25)); // test
Xcepto.given(scenario, builder -> {
// ...
}, timeout, Duration.ofMillis(100)); // poll interval
The fourth argument to Xcepto.given is the poll interval — how often evaluateConditionsForTransition is called on the current state. Use a shorter interval for unit-speed test servers (e.g. 50ms), longer for real distributed systems.
Failure types
- .NET
- Java
| Exception | When thrown |
|---|---|
XceptoTestFailedException | Assertion failed in a state |
XceptoTimeoutException | Total budget expired before reaching the final state |
XceptoScenarioResetException | Scenario setup or cleanup failed |
| Exception | When thrown |
|---|---|
XceptoTestFailedException | Assertion failed in onEnter or evaluateConditionsForTransition |
TestTimeoutException extends XceptoTestFailedException | Total budget expired before reaching the final state |
XceptoScenarioResetException | setupEnvironment or stopEnvironment failed |
TestTimeoutException extends XceptoTestFailedException, so assertThrows(XceptoTestFailedException.class) catches both assertion failures and timeouts in negative-path tests.
Testing for expected failures
Use assertThrows / Assert.Throws to verify that a test fails for the right reason in negative-path cases:
- .NET
- Java
[Test]
public void InvalidCredentials_RejectLogin()
{
var scenario = new AuthScenario();
Assert.ThrowsAsync<XceptoTestFailedException>(() =>
XceptoTest.Given(scenario, builder =>
{
var ssr = builder.SsrAdapterBuilder()
.WithBaseUrl(scenario.BaseUri)
.Build();
ssr.Post("/auth/login")
.WithFormContent(
new LoginRequest("user", "wrong-password").ToForm())
.AssertSuccess(); // will fail — login returns 401
}));
}
@Test
void invalidCredentials_rejectLogin() {
var scenario = new AuthScenario();
assertThrows(XceptoTestFailedException.class, () ->
Xcepto.given(scenario, builder -> {
var ssr = new SsrAdapterBuilder(builder)
.withBaseUrl(scenario.baseUri)
.build();
ssr.post("/auth/login")
.withFormContent(SsrExtensions.toForm(
new LoginRequest("user", "wrong-password")))
.assertSuccess(); // will fail — login returns 401
}, TIMEOUT, Duration.ofMillis(50)));
}
Choosing timeout values
- Unit-speed test servers (in-process, no real I/O):
total = 5s,test = 3s - Integration environments (containers, local services):
total = 30s,test = 25s - Negative-path tests (expected to time out): use a short
test(e.g.500ms) to keep the suite fast
Define a private static final TimeoutConfig TIMEOUT constant per test class rather than repeating values in every test method.