The goal is to be able to run this:
Create a new file called
index.js. The entire source code will live inside here. Let’s start from
describe function signature is
fn(description, callback). The first argument is simply a string describing the block, and the
callback contains the actual test code to execute. It would be also be nice to print out the description when the test executes.
Relatively straightforward! Another nice part of this we can have arbitrarily nested
describe blocks. For example:
Surprisingly simple. Moving on…
it is actually easier to implement than
describe, at least for this example. Why? Let’s take a look at the function signature. The first argument is a message, and the second is the callback:
… which is identical to
describe. Let’s just go ahead and use
Now we just need to implement
Let’s start with
expect. The function signature is as follows:
Since we want to chain
expect must return an object that has a
toBe property that is a method.
Start of by defining the
Now we can type
expect(1) . We just need an object with a
toBe property, that does the comparison between the value passed to
expect and the value passed to
The object returned by
expect will contain at least one matcher,
toBe, and possibly more in the future. It looks like this:
exp is the expected value, which is passed to
expect. We need to pass it into
matchers, to be able to make the comparison.
toBe receives the assertion, which is what we expect to equal value passed to
toBe is performing a strict comparison using
=. This means
toBe can only be used for primitives, such as
This is all we need to be able to run the example code from the start of the article! The full source code with example as follows, and can be pasted into a single
index.js and run using
I am exporting the methods at the bottom of the file, so I can
require and test them.
As promised, we will test the framework using itself. I will write the tests in a file called
index.test.js, which can be run using
First, a test on
describe… actually doesn’t do much. It simply
console.log a value, and executes the
callback. We could mock
console.log and ensure it is called, but that isn’t very interesting. Let’s focus on making sure the callback is called.
We start of by requiring all the functions we will test (and need to write the tests). We simply declare a
noop, or no operation function that increments a value each time is it called — this is how we will assert that
describe is calling the callback.
describe is now as simply as asserting
executes has indeed increments, which reflects that the
noop callback did indeed execute.
It just calls
describe, and does nothing different, so testing is isn’t very interesting.
expect is also very straight forward.
expect returns an object, with a
toBe property that is a
toBe is as simple to test as everything else. It should return
true for when primitives are equal, such as
1 = 1, and false for
1 === 2.
false is exactly the same, so I won’t include it.
index.js, not including whitespace and
exports , is less than 30 lines of code! This isn’t a very full featured framework by any means, but for just 30 lines, it’s relatively powerful. Adding more matchers as as simply as adding extra methods to
isTruthy and are trivial. Add more advanced matchers like
toHaveBeenCalled , and other test features like spies and mock functions are some improvements I’d like to implement, as well as better error handling and logger.