Testing Applications That Use CritterWatch
Running the CritterWatch monitoring pipeline inside your integration tests is pure overhead. The tests are not looking at the console, nothing is consuming the telemetry, and the work is not free: alongside publishing, AddCritterWatchMonitoring turns on message-causation tracking and event-append tracking, both of which do per-envelope work in the hot path.
Turn it off explicitly:
builder.ConfigureServices(services => services.DisableCritterWatch());WebApplicationFactory
var factory = new WebApplicationFactory<TProgram>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services => services.DisableCritterWatch());
});
var client = factory.CreateClient();The same call works from Alba, which builds on WebApplicationFactory, and from a plain IHostBuilder.
Call it in either order
// DisableCritterWatch() is order-independent. Called before UseWolverine it leaves a marker
// that makes AddCritterWatchMonitoring register nothing at all; called afterwards — which is
// what WebApplicationFactory does, since its callbacks run after the application's own
// registrations — it removes what was registered and undoes the WolverineOptions half.
builder
.ConfigureServices(services => services.DisableCritterWatch())
.UseWolverine(opts => opts.AddCritterWatchMonitoring(
critterWatchUri: new Uri("rabbitmq://queue/critterwatch"),
systemControlUri: new Uri("rabbitmq://queue/my-service-control")));Both orderings are supported, and they take different routes to the same result:
| Call order | What happens |
|---|---|
Before UseWolverine | A marker is left in the container and AddCritterWatchMonitoring returns without registering anything. |
After UseWolverine | The registrations are removed and the WolverineOptions changes are undone through an IWolverineExtension. |
The second is the case that matters most in practice, because WebApplicationFactory's ConfigureServices callbacks run after the application's own registrations.
What "disabled" covers
- No telemetry, heartbeats or metrics are published to the console.
EnableMessageCausationTrackingandTracking.EnableEventAppendTrackingare both off — the per-envelope cost, and very likely the larger share of the overhead.- Heartbeat emission is off.
- The
CritterWatchObserveris not attached to the runtime. - The background services registered by
AddCritterWatchMonitoring— includingEventProgressionPoller— are not registered.
One known gap: the control endpoint may still be compiled as a listener. Wolverine applies the IsListener flag as delayed endpoint configuration, after endpoint policies and after activators, so there is currently no supported hook that can un-listen an endpoint once it has been declared. Nothing routes to it — the subscriptions are cleared — so on a local:// control channel this is an in-memory queue with no writers. On a broker-backed control channel it remains an idle consumer.
Why there is no automatic opt-out
CritterWatch deliberately does not disable itself based on IHostEnvironment. Both readings of "Development" are wrong:
WebApplicationFactoryruns asDevelopmentby default unless a test explicitly overridesEnvironmentName, so environment sniffing would fail to fire for most of the scenario it is meant to solve.- Auto-disabling in
Developmentwould contradict embedded mode, where CritterWatch is a development-time tool by design.
So the opt-out is a call you make. To make it discoverable, a monitored host logs one Information-level line at startup naming this recipe — it shows up in the log of the run where someone is wondering why their test suite got slower.
