Skip to main content

The four questions

An integration test talks to the parts of a system that actually run: an API, a database, a broker, a browser, a clock you do not own. That is what makes it valuable, and it is why it fails in ways a unit test never does.

Before you can trust a test like that, it has to answer four questions.

Level 0, lesson 1About 8 minutes
By the end
  • Name the four questions an integration test has to answer.
  • Point at the part of a trace that answers each one.
  • Say what a passing test leaves behind.
Before you start
  • Nothing from this track.
  • The archives this level reads are on this site, so no install is needed. To run the sample as well, dotnet test samples/Northstar.ProtoTest needs the .NET SDK and the repository.

The scenario​

An integration test fails once, passes on the retry, and the failure message says nothing you can act on. Most integration failures look like this. Something outside the tested code changed, and the test never named what it depended on.

The four questions name those somethings. The rest of this level answers each one with a test that fails on purpose and the test that fixes it.

The four questions​

The sample suite answers each question twice: once the way that fails, once the way that holds. This is what the failing half recorded.

QuestionThe drillWhat the trace recorded
TimeARealWaitDoesNotCloseTheDueWindow waits one real secondthe shape check failed on $.status: expected past_due, read active
StateAnUnknownProjectIdIsTreatedAsMine reads the project id prj_1the request returned 404; no test in the run created that id
EnvironmentTheAddressWasHardcodedForOneMachine opens a raw client on 127.0.0.1:5099the test ran about two seconds and recorded no request at all
VisibilityABareStatusHidesWhatTheApplicationSaid sends an empty project namethe status check saw 400; the body that named validation_failed stayed unread

Time: who moves the clock?​

The application computes every stamp and billing period from a time provider. The test host hands it the test's clock, so real time does not move anything the application can see. A wait therefore changes nothing. The fix, TheTestClockClosesTheDueWindow, calls Proto.Context.Clock.Advance(TimeSpan.FromDays(8)) and then reads the same organization. One clock, moved from the test side.

State: what does the test share?​

A test that reads prj_1 reads a record some other run created, or no record at all. The fix, EachTenantSeesOnlyItsOwnProjects, creates its own project, lists the projects its tenant can see, and finds exactly one. Data that belongs to one test stays in that test, and it is removed when the test ends.

Environment: where does the address come from?​

A raw HttpClient with a fixed address talks to one machine: the one where it was written. It is also outside the run, so the trace cannot see the call. The fix, TheAddressComesFromTheComposition, calls the same endpoint through Proto.Context.Rest(), which takes its address from the run. The same test then works in-process, in a container, or against a published environment.

Visibility: what can the test show when it fails?​

A test that asserts the status alone throws away what the application said. The drill sent an empty project name, expected 201 Created, and the check reported 400. The body named validation_failed and the empty parameter, and nothing read it. The fix, TheProblemBodyNamesTheCodeAndDetail, asserts the problem body, so the same failure would name the code and the message.

A passing test answers all four: it moves the clock, creates and removes its own data, takes the address from the composition, and asserts something that names the difference when it fails. The rest of this level reads the four drill pairs in full.

Checkpoint​

The time drill waits one real second and the application still reports the organization as active. Why does the wait not close the due window?

Verify
Download l0-time-drill.prototrace, drop it on the viewer, and follow the failed check down to the values it printed. When you can explain the failure without running it again, you have the habit the rest of the track builds on.

What you learned​

  • Time, state, environment and visibility are the four things an integration test has to get right.
  • Each one has a concrete answer in the composition or in the trace.
  • A passing test answers all four at once; a failure is usually one missing answer.

Keep exploring​