Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly failing tests jest and supertest Node.js

so long story short I'm developing RESTapi that takes a movie title on POST request to the /movies route, fetches info about that movie from external api and saves that object to the database. On POST /comments you add a comment to the different collection but every comment has a 'movie_id' property that has an associated movie.

That's my first bigger project so I'm trying to write integrational tests. Everything is great, at least in my opinion, except 3 weird test cases that are failing just out of nowhere. Tests could pass 10 times in a row and then suddenly that weird 'jest' timer shows up and 3 cases fail.

I'm using native mongodb driver, express and jest with supertest for testing, dropping test-database BeforeAll and AfterEach, I have no idea whats the reason of that.

Timer thingy: enter image description here

And after timer this shows up, failed tests: enter image description here

Full source code is here GITHUB

Other failed cases: enter image description here enter image description here

Any ideas, tips?

like image 620
lekterable Avatar asked Apr 20 '18 08:04

lekterable


People also ask

Is Jest good for node JS?

This also provides an added advantage to the users in the way that they can add any new features without breaking any other part of their application. For your NodeJS applications, Jest can be used for Unit Testing.

What is SuperTest in node JS?

SuperTest is a Node. js library that helps developers test APIs. It extends another library called superagent, a JavaScript HTTP client for Node. js and the browser. Developers can use SuperTest as a standalone library or with JavaScript testing frameworks like Mocha or Jest.

What is Jest and SuperTest?

Jest provides you with multiple layers on top of Jasmine. What is SuperTest? *A library for testing node. js HTTP servers *. It is a super-agent driven library for testing node.

Is Jest enough for testing?

Despite what many may think, Jest is not just a test runner—it is a complete testing framework that has brought testing to another level. It's powerful but easy to use, so give it a try.


2 Answers

I was in the same hell "jest parallel tests" problem and i find a solution, maybe not the best but now jest run tests in "queue mode" so when i delete datas in beforeAll my next group of tests is ready to go with "fresh" new inserted datas.

--runInBand Alias: -i. Run all tests serially in the current process, rather than creating a > worker pool of child processes that run tests. This can be useful for debugging.

jest source

So in my config.json i have :

    "scripts": {
        "test": "set NODE_ENV=test&& jest ./tests --runInBand --detectOpenHandles --forceExit",
        "server": "set NODE_ENV=development&& nodemon app.js"
    }
like image 156
nathan lebreton Avatar answered Oct 25 '22 11:10

nathan lebreton


The code seems to return one entry, while the test expects zero. This looks very much like an issue with test independence: Your tests seem to depend on each other (through the database).

I would guess that one test creates the movie and then clears it again. When everything works fine, the second test does not find the movie. But, in some unforunate cases (bad timing, different execution order, ...), the database is not cleared fast enough and the second test finds the movie.

So, you should work hard on making your tests independent. This is not easy with integrated tests, especially when they involve a real database.

Maybe you can create smaller tests (Unit tests, micro tests, ...) to achieve independence. If this is not possible, the test could check it's precondition (database empty or whatever) and wait until it's fulfilled (or until a timeout happens).

Dropping the database in BeforeAll and AfterEach might not be enough, because Jest even runs your tests in parallel: Are tests inside one file run in parallel in Jest?

Also, dropping might not be a completely synchronous and atomic operation, especially when there is some caching in the DB driver. But I don't know mongodb and it's node.js integration well enough to judge that.

like image 29
David Tanzer Avatar answered Oct 25 '22 12:10

David Tanzer