简体   繁体   中英

Node.js assert library vs. other assert libraries

According to node.js assert library documentation :

The module is intended for internal use by Node.js, but can be used in application code via require('assert'). However, assert is not a testing framework, and is not intended to be used as a general purpose assertion library.

I was looking at Chai as an alternative assert library (no BDD API, only the assert API), and at the end I see that the assert functionality is very similar.

Why Chai's assert library is a better assert library? It does everything than node.js does (beside being just more rich in terms of assertion available, but that's just syntactic sugar-coating). Even simple things like the total count of assert executed is not available on both.

Am I missing something ?

UPDATE (April 2017): Node.js no longer warns people away from using assert so the answer below is now outdated. Leaving it for historical interest, though.

Here's the answer I posted to a very similar question on the Node.js issue tracker .

https://github.com/nodejs/node/issues/4532 and other issues allude to the reason the documentation recommends against using assert for unit testing: There are edge case bugs (or at least certainly surprises) and missing features.

A little more context: Knowing what we now know, if we were designing/building Node.js core all over again, the assert module would either not exist in Node.js or else consist of far fewer functions--quite possibly just assert() (which is currently an alias for assert.ok() ).

The reasons for this, at least from my perspective, are:

  • all the stuff being done in assert could easily be done in userland
  • core efforts are better spent elsewhere than perfecting a unit testing module that can be done in userland

There's additional context that others may choose to add here or not (such as why, all things being equal, we would favor keeping core small and doing things in userland). But that's the so-called 30,000 foot view.

Since assert has been in Node.js for a long time and a lot of the ecosystem depends on it, we are unlikely (at least as best as I can tell at the current time) to ever remove assert.throws() and friends. It would break too much stuff. But we can discourage people from using assert and encourage them to use userland modules that are maintained by people who care deeply about them and who aggressively fix edge-case bugs and who add cool new features when it makes sense. So that's what that's all about.

True, if you're doing straightforward assertions with simple cases, assert probably will meet your needs. But if you ever outgrow assert , you'll be better off with chai or whatever. So we encourage people to start there. It's better for them (usually) and better for us (usually).

I hope this is helpful and answers your question.

I guess since nobody gave me any good feedback I'll try to provide some light on my original question after some time of working with both node.js assert and chai's assert.

The answer at the very end is that functionality-wise they are the same. The only reason why chai's assert exist is so if you read the code you can get a better understanding of the tests, but that's about it.

For example, testing for a null value with Node.js:

assert(foo === null);

And using chai:

assert.isNull(foo);

They are perfectly equivalent, and sticking to node.js assert limits your dependency list.

Disclaimer: I am the author of the assertthat module that I will refer to in this answer.

Basically, you can achieve all the things with Node's very own assert module that you can do with all the other modules out there, such as Should.js , expect.js or assertthat . Their main difference is the way of how you can express your intent.

Semantically speaking, the following lines of code are all equivalent to each other:

assert.areEqual(foo, bar);
foo.should.be.equal(bar);
expect(foo).to.be(bar);
assert.that(foo).is.EqualTo(bar);

Syntactically, there are two major differences:

First, the should syntax only works if foo is not equal to null or undefined , hence it's inferior to the other ones. Second, there is a difference in readability: While assert.that(...) reads like natural language, all the others don't.

After all, Chai is only a wrapper around a few assertion modules to make things easier for you.

So, to cut a long story short: No, there is no technical reason why to prefer one over the other, but readability and null compatibility may be reasons.

I hope this helps :-)

PS: Of course, internally, they may be implemented differently, so there may be subtle things eg, how equality is checked. As said in the disclaimer, I'm the author of assertthat so I may be biased, but in the last few years I had the situation from time to time where assertthat was more reliable than the other ones, but as said, I may be biased.

Since noone mentioned it, I thought I would mention rockstar programmer Guillermo Rauch's article (link is to Web Archive backup) on why you should avoid expect-style frameworks in favor of plainer assert style testing.

Mind you, he is the author of expect.js , so he has once thought otherwise. So have I.

He makes an elaborate argument, but basically it's about reducing the mental burden of API overload. I can never remember which dialect of should and expect I am writing. Was it .includes(foo).to.be.true() or was it .includes(foo).to.be.true or was it ...

TJ Holowaychuck wrote a nice assert library called better-assert to get better output which you might check out .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM