Not quite unit testing ExpressJS

Everything is awful

I tried. First things first, Node isn’t running in the browser. The vast majority of modern JavaScript testing tools open up a browser. Of course this makes sense, but what a pain! If I see one more article about some web developer somewhere writing what’s effectively a unit test but doing it with a browser, I’m going to explode. “But what about PhantomJS?” you might say. PhantomJS is the answer to an entirely different question (also the project is over now that Chrome and Firefox are going headless). Server side code that only ever runs with Node should not be tested by a browser. The amount of complication and overhead being introduced is insane.

What are the options?

Here are some links:

Mocha, Jasmine, Karma, Tape, Sinon, Jest,  As with everything else in the modern JavaScript ecosystem, there are a million and a half options that are all considered to be anti-patterns by one person or another. There are many articles by enlightened people who suggest using Tape instead of one of those bloated, new-agey frameworks. I was actually pretty convinced by the article, it hit a lot of points that resonated with me. Then I used it. Oh, you want to use TypeScript? Maybe some promises or other asynchronous things? How about creating a test structure that allows you to organize in a meaningful way? Now that you’re a minimalist you can do all that work yourself!

Everyone is awful

What slays me about articles like that are comments like these:

Think you’ll miss automagic test parallelization? I keep tests for different modules in different files. It takes about five minutes to write a little wrapper that will fire up workers across all your machine cores and zip through them in parallel.

and this…

Before/After/BeforeEach/AfterEach

You don’t need these. They’re bad for your test suite. Really. I have seen these abused to share global state far too often. Try this, instead:

*sigh*. People will always abuse stuff. Abandoning functionality because it can be misused should be carefully considered. Code reuse is a spectrum. There are people who pull giant libraries just to use a 3 line function, and they get shamed for it (jQuery anyone?). In my experience, the other end of that spectrum is just as bad. I’ve seen multiple implementations of HTML sanitizers. WHY?! It’s going to suck and be wrong and probably open you up to some code injection. Someone else has done it better.

What to do?

First, one of the things I realized was SUPER important about this effort is being mindful of what you’re trying to test. I found myself too often most of the way through writing a test and discovering I was really just testing the router or some other provided piece of functionality. I tried a few strategies and it all seemed like a bit of a mess. There’s a blog post here with some information, but I don’t really buy it all.

The most effective strategy I found was really framework independent. Take a look through focusaurus’ repository here – and I mean really look at it. While I didn’t follow the suggestions there 100%, by incorporating some of the ideas I found I was able to break most of my application into plain old JavaScript.

Which framework should I use?

  • Purely Node? Try tape
  • Angular? You’ll likely be using Mocha and Jasmine
  • React? Jest looks like its the way to go

Every testing framework I’ve ever used has been a bit of a pain. Tests end up extremely coupled to the framework itself. Once the application has been decomposed nicely, I honestly don’t think frameworks make much difference. Read the examples, pick the one you like the style of most, then deal with all the ways it kind of sucks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s