runtimeanalyz.ing ● early access · sign-up open

← Runtime Analysis

You write the test first. Good. Your suite is the recording.

None of this needs production traffic, and none of it needs code written before its test. Runtime Analysis records your suite running on your laptop. The class you're about to write doesn't exist yet, but everything it collaborates with does, and earlier cycles' tests already ran that code for real.

01 · they exist

Only the very first red of a new project starts from nothing. Every cycle after it adds to code that earlier cycles drove out: the collaborators you're about to stub are already there.

02 · rspec is enough

Record rspec locally. Every call tree is tagged with the example that produced it, so each observation comes with the spec that made it. No staging, no production, nothing your app depends on.

03 · real once

Mock Gateway in Checkout's spec and Gateway's own spec still runs the real thing. Every object is real in its own spec, so every double has a real recording to be checked against.

Through the cycle

Evidence at red, green and refactor.

red

You stub the collaborator. The stub is checked against what the real collaborator did in its own spec: the messages it received, the classes it was passed, the shape it returned.

green

Run the specs that reach what you just changed, and only those. The example that produced each call tree is already recorded, so the map from method to example comes free and the loop stays in seconds.

refactor

See the slice of the interface each caller actually uses, and extract the role before the design sets. Grey out the public methods nothing but their own spec ever calls.

At red

Every stub is a claim about a collaborator. We check the claim.

The one part of a new spec that makes claims about code you didn't just write is the double. The real Gateway#charge ran in gateway_spec.rb, so the stub is held to what it did there.

the spec you just wrote
◆ checkout_spec.rb

8

9

10

11

12

13

it "charges the cart" do
  gateway = instance_double(Gateway)
  allow(gateway).to receive(:charge)
    .and_return(:ok)
    ⤷ real Gateway#charge never returned a Symbol
  expect(checkout(gateway).call).to be_paid
end
runtime-analysis💡 return a Receipt
runtime-analysis · verify_mock
runtime-analysis · verify_mock
$ ra verify_mock spec/checkout_spec.rb

Gateway#charge  stubbed at checkout_spec.rb:10
  stub returns  Symbol
  real returns  Receipt
                responds to #id, #amount, #paid?
  seen in       gateway_spec.rb:14 · :22 · :31

# evidence: your suite · 0 production calls

instance_double confirms #charge exists with the right arity. It can't tell you the real one hands back a Receipt, and Checkout will call #paid? on whatever it gets. Green in isolation should mean green integrated.

Across the suite

Collaboration tests, matched to contract tests.

A stub in one spec is only honest if a test somewhere else shows the real object doing what the stub claims. Keeping those two sides in step by hand is the discipline that slips first. Your suite already records both.

verify_mock

CLI · LSP · MCP · CI free

Catch a lying mock. A stub that passes green but returns something the real collaborator never would. Mutation testing can't see it. The recording can.

See more →

check_diff

CLI · CI · MCP free

Catch it in review. Point it at a branch or PR and it flags only what the change introduced, before it lands: a drifted mock, a fresh dependency cycle, new feature envy.

See more →

dead_api

LSP · CLI free

Find dead public API. Public methods no caller reached in any recorded run, including the ones whose only caller is their own spec. Greyed out in your editor.

See more →

how_far_it_reached

CLI · MCP free

Is your unit test a unit test? For each spec example, how many classes its real call tree touched and how deep it went. A unit spec that reaches thirty classes is telling you something.

See more →
mock everything

Still works. Each class is real in its own spec, so every double has something real to be checked against.

never mock

Then verify_mock has nothing to check, but the spec map, the reach per example, the interface splits and the code only its own spec calls still land.

the first red

On a brand-new project there's nothing recorded yet. It starts paying from the second cycle, once there's a real collaborator to stub.