Testing Problems Come From Architecture

Montreal cathedral Marie Rene Du Monde

Thanks to Logicroom for teaching me this.

With testing problems, the fix is rarely in the tests.

The fix is in the architecture.

As J.B. Rainsberger said, unit tests are the best.

With only a few integration tests at the edge.

But usually, the system is too coupled to have unit tests.

The tests write to the real filesystem, and run processes on the real operating system.

So the unit tests become integration or end to end tests.

The fix isn’t to improve the integration tests, as J.B. Rainsberger said.

Like using a better mocking library.

The fix is to decouple components, so you can unit test them.

For example, in my VS Code extension, tests were slow.

They bootstrapped a real VS Code instance:

Unit tests opening VS Code instance

That’s because the code was very coupled to VS Code:

Architecture diagram of VS Code extension coupled to VS Code

So it had to bootstrap VS Code to run the tests, which made tests almost impossible locally.

  • I didn’t write many tests
  • If they failed, I’d only see it in CI/CD
  • They were integration, not unit tests

The fix wasn’t to bootstrap VS Code better.

Or to use a mocking library.

The fix was to decouple the extension from VS Code:

Because it calls EditorGateway, you can replace that with FakeEditorGateway in tests:

const spy = jest.fn();
fakeEditorGateway.editor.commands.registerCommand = spy;Code language: TypeScript (typescript)

Many times, dependency injection is the solution, though not with a framework.

Just a composition root.

In Clojure, it could be DI, or testing macros.

Now, tests run in 7 seconds:

Terminal running Jest unit tests

But it’s not just faster.

It’s easier to write unit tests, so I write more.

They’re not flaky, so I believe them when they fail.

The right architecture makes tests easy.

One response to “Testing Problems Come From Architecture”

  1. Ryan Kienstra Avatar

    Testing is like a friendship. If it’s always hard, something’s wrong 😊

Leave a Reply

Your email address will not be published. Required fields are marked *