Jeremy W. Sherman

stay a while, and listen

Beyond Our Ken

The more I poke around, the more convinced I become that actually knowing what a piece of software is supposed to do is truly rather rare and generally beyond mortal ken. Making it do what you think it should do is nearly beyond our grasp.

If we’re honest with ourselves, we need every tool we can get just to wrangle software into behaving. That means types, that means tests, and that means, yes, even: proofs.

And that also means that proofs need tests, too.

What drove this home was reading a couple papers related to combining proving and testing.

Beyond Type Wars: Types Can Be Tests Too

Types and tests are not at war. Choose both.

In fact, if we tilt our heads a bit, types are just another flavor of test.

Don’t use just one flavor of testing; use all the tools you have at your disposal to make the best software you can.

Type Wars

Robert C. Martin believes code TDD’d into existence, and so having 100% test coverage by construction, nullifies the value of types:

Types Complement Tests Complement Types

Types and tests are complementary. They might even be synergistic: The two together can accomplish what neither can alone. They definitely are not rivalrous goods, and if you’re picking only one, you’re doing yourself a disservice.

If You Have To Pick One, Though

There’s a ceiling to how far we can get with types. Most languages developers work in have rather limited type systems. Most developers lack the skill, practice, and simple exposure to past examples to make use of more powerful type systems. That’s not a slight: Generating those examples today can be a good way to get yourself at least a Masters if not a PhD.

We can push automated testing really far regardless of type system. There’s an abundance of popular literature on the subject. If you want to get better, you don’t have to look far, and you can put what you learn to practice immediately.

If you had to pick between either building 100% TDD’d code in a unityped language or building code with no automated tests in a conventionally typed language, you’d be a fool not to pick the TDD’d codebase.

But You Don’t, So Use Both

You don’t have to choose one or the other. Reject the false dichotomy, chase off its acolytes on their hobby horses, and make the most of all the technologies available to you today to produce better software.

XCTestExpectation Gotchas

XCTestExpectation simplifies testing callback-style code, but some of its design choices make tests using it fragile unless they’re mitigated:

  • It explodes if everything works right but later than you expected.
  • It explodes if everything works right more than once.

This article presents two concrete mitigations:

  • Use weak references to ensure the expectation dies before it can cause you trouble.
  • Use a different promise API to do your waiting.