A Test is Just a Function

I'm doing a few days on testing and TDD in advance of my webinar on the topic next week

A test is just a function. The function takes some code to execute plus an expected result, and compares the two. You could argue that a test is just a really verbose equality check.

Here's the worlds tiniest test runner, with just the bare minimum of developer ergonomics in the form of a description argument:

function test( actual, expected, description ) {
  console.log('Testing:', description)
  if (expected === actual) {
    console.log('  pass')
  } else {
    console.error('X FAIL')
    console.error(`  Expected ${actual} to equal ${expected}`)

Let's see it in action:

function five() {
  return 5

function add(x, y) {
  return x + y

function six() {
  return 5

test(five(), 5, "five() should return 5")
test(add(2, 3), 5, "add(2,3) should return 5")
test(six(), 6, "six() should return 6")

Output of running the above:

Testing: five() should return 5
Testing: add(2,3) should return 5
Testing: six() should return 6
  Expected 5 to equal 6

At its core, this is all any test runner is doing. It's running some code and comparing to a predetermined expectation. Everything else is developer ergonomics. We'll get into those ergonomics over the next day or two, but it's important to remember that this is what's going on.

When you recognize that this is what a test is, then you start writing your code thinking "How can I make this run in a function with the fewest possible external dependencies?". You start to think in explicit terms about the values that your components take in and return. This helps bring clarity to your architectural decisions and forces you to treat your application as a system of smaller components, instead of a lump of clay.

The act of writing the test makes your code more stable and reliable. The test itself remains as an artifact to make sure your code stays that way.

Did you like this?

I send a daily email with tips and ideas like this one. Join the party!