Power-assert – The No API Assertion Library
In Ackee, we are always looking for new libraries and tools that can make our job easier. Although replacing Jest was motivated by more than just trying out a new testing framework. And with Jest we also replaced its assertion libraries. After some research, we decided to try the power-assert library, which seemed like a good choice.
Why Jest may not be the best option for us?
- complex – Jest is a complex and huge testing framework - it doesn’t make sense to add such a huge dependency to a small project when we need just a tiny part of its functionality. We decided to move to mocha, which allows us to modularly install the dependencies we need.
- issues – We experienced many issues with Jest (see Jest: Does It Test Funny to You?), but the one that was the last nail in the coffin was memory leaks (more on this issue in the blog: Node Testing Frameworks: The Good, the Bad, the Slow and the Hungry)
- typescript support – Jest doesn’t have the best support for TypeScript. You need to download the types alongside the preprocessor ts-jest and configure it. Although other test frameworks need some kind of TypeScript setup too, from my experience, it is less work.
The good parts of power-assert
Let’s start with the good parts – the main reasons why we chose to try out power-assert.
No API is the best API
Every time you start using a new library or framework, you need to take time to study its API. If you are exploring new libraries often, this process takes serious time. When you use Jest as a testing framework, you need to learn a whole lot of assertion methods.
What if this part could be skipped? And we could use the library right away without needing to study complex APIs? Well, we can with power-assert – the only function we need to know is the assert(any_expession)
. It is the same assert function we are used to from built in node assert, it’s just enhanced with power-assert.
Structured output
The main difference from the built-in assert module in node is a pretty output in the console when a test fails.
AssertionError [ERR_ASSERTION]: # transaction-validator.spec.ts:69
assert(supportedNetworks.includes(result))
| | |
| false "algorand"
["ethereum","solana"]
+ expected - actual
-false
+true
As you can see from the example, power-assert decomposes the expression and it is easy to see values for each part.
The not so good parts
Now let’s go over the disadvantages of power-assert.
Structured output
As I mentioned in the previous part, one of the benefits of power-assert is the structured output. But when the expression gets more complex - on one project we compared objects that contained buffers, and when the buffers did not match, the output filled the whole terminal window hiding the output of other important fields.
You can see an example of this behavior in the following terminal output:
+ "depositTransactionTokenSymbol": "ff6cc8"
+ "footprint": {
+ "id": "185be5c4d59ea672334836e22a7b0c3f2660821dc70988e4b65a8e71e12f8d97"
+ "metadata": "{}"
"payload": [Buffer: [
- 132
- 13
+ 104
+ 52
This continued for several hundred lines, ending with a mocha error saying it was too long.
+ 21
+ 155
+ 89
+ 101
+ 134
[mocha] output truncated to 8192 characters, see "maxDiffSize" reporter-option
This kind of output just spams the terminal, but all the useful bits are truncated because of too much text and those that aren’t could be hard to find.
Setup with TypeScript is a pain in the… behind
Setting up power-assert with TypeScript requires installing an additional interpreter to function correctly – espower-typescript
. After we got it running, we encountered another problem. The interpreter throws generic error messages when something goes wrong. For example, when there was an error in the code and the build failed, the interpreter just showed some generic error message about JSON stringify instead of the correct one. What we ended up doing when seeing this message was to try to build the project manually and then try running the tests.
Also for some reason the assert must be imported with import assert = require('assert')
, it won’t work with the classic TypeScript import. This may lead to a situation, where power-assert works in one test file, but not in the others.
Conclusion: power-assert
In the end, we came to the conclusion that the benefits of the power-assert are not worth the hassle and we will probably stick with the Node's built-in assert module. There is no setup needed and although the structured output was nice sometimes, it is a thing we can live without.