Skip to main content

Capabilities and the host

Level 0 was about what a test answers. This level is about the other side: what the run provides, and where that decision lives.

Level 2, lesson 1About 8 minutes
By the end
  • Say what a capability is and which piece serves it.
  • Read a run's composition from its trace.
  • Tell what belongs to the host from what belongs to a test.
Before you start
  • Level 1 (read the trace).
  • The sample cloned. Reading the archives alone also works.

The scenario​

The host is built once for the run. Every journey then asks the context for what it needs: a REST client, a database connection, a signed-in member. That is why a failure in setup is one line in the trace instead of a hunt through test code.

Time and state had their answers in the test. Environment and visibility had theirs in the composition. This lesson reads the composition.

Capabilities​

A capability is a named action the run supports, such as calling an API or serving a broker. Each one has a kind and the package that declares it. The run records all of them as items, and the trace's run layer prints them.

From the first journey's archive:

CapabilityKindDeclared by
RESTprotocolProtoTest.Rest
GraphQLprotocolProtoTest.GraphQL
ASP.NET CoreserverProtoTest.AspNetCore
SQLstoreProtoTest.Sql
DatadataProtoTest.Data
SheetsdocumentProtoTest.Sheets
PlaywrightbrowserProtoTest.Web.Playwright

Two rules keep the list true. A capability is declared by the piece that can serve it, never by a test that hopes it exists. And the run omits a capability it cannot serve, with a reason the composition can register.

One Configure method​

The sample composes everything in samples/Northstar.ProtoTest/Setup.cs. This is ConfigureApplications:

Setup.cs6 notes
1private static void ConfigureApplications(IProtoHostBuilder builder, NorthstarRun run)
2{
3builder.AddApplication(NorthstarTargets.Api, app =>
4{
5if (run.RunsLocalApplications)
6{
7// The in-process server is what carries the test clock into the application.
8app.AddAspNetCoreServer<NorthstarProgram>(configureWebHost: webHost =>
9ConfigureHostedApplication(webHost, run));
10}
11
12app.AddRest(rest => rest
13.CaptureAttachments()
14.AddClient(NorthstarTargets.Api)
15.AddCollector<RestCoverageCollector>()
16.AddCollector<RestTrafficCoverageCollector>())
17.AddGraphQL(graphQL => graphQL
18.CaptureAttachments()
19.AddClient("GraphQL", endpoint: "GraphQL"));
20});
21
22if (run.RunsLocalApplications)
23{
24// The browser needs a real listener; the page journey follows this instance's address.
25builder.AddLoopbackApplication(NorthstarTargets.Web, NorthstarProgram.CreateApp);
26builder.AddHttpReadiness(NorthstarTargets.Web, "/health");
27}
28
29builder.AddApplication(NorthstarTargets.Web, app => app
30.AddRest(rest => rest
31.CaptureAttachments()
32.AddClient(NorthstarTargets.Web))
33.AddWeb(options => options.Headless = true));
34}
  1. One place composes the run

    Setup runs once before any test and builds the host every journey shares.

  2. Name the application

    Api is the target tests select with [Application]; the same name is used by the clients and by the trace.

  3. Host the application in-process

    The in-process server carries the test clock into the application, which is what makes the time answer work.

  4. REST and GraphQL from one registration

    Each Add... adds a client and the capability that serves it.

  5. A real listener for the browser

    Playwright needs an address, so the run starts a loopback instance and waits for /health before any test uses it.

  6. Compose the browser client

    AddWeb adds the Playwright capability; the web application gets its own REST client for the page journey.

From samples/Northstar.ProtoTest/Setup.cs. The store and the broker follow the same shape through AddInfrastructure, which the next lesson covers.

What the host owns, and what a test owns​

The split is about lifetime:

  • The host owns what the whole run shares: applications, infrastructure such as a database or a broker, report sinks, and run gates. It starts them once and releases them when the run ends.
  • A test owns its execution context: the data it creates, the state it sets, the checks it makes and the attachments it publishes. All of it is recorded and released per test.

The sample shows both. The store, the loopback instance and the broker are run pieces. The tenant, the project and the sign-in are test pieces, created by attributes and removed at teardown. The next lesson watches one of those run pieces come and go.

Checkpoint​

The first journey's trace lists the capabilities the run declared. Name three of them and where each one comes from in Setup.cs.

Verify
Download l1-first-journey.prototrace, open it in the viewer, and read the run screen. Then find each registration in samples/Northstar.ProtoTest/Setup.cs.

What you learned​

  • A capability is declared only by something that can serve it.
  • The composition is written once, in one Configure method, and the run records what it declared.
  • The host owns what the run shares; a test owns its own data and assertions.

Keep exploring​