`npm test` never exits - node.js

I use mocha to run my unit tests, and often use npm test in order to run it. My package.json contains these script definitions:
"pretest": "NODE_ENV=test node migrate all",
"test": "DEBUG= NODE_ENV=test mocha --recursive",
If I run either one of these commands directly in my shell (i.e. not going through npm) they execute fine (790 tests takes about 2m to run, the migration script is done in under 1s). The processes also exit cleanly.
If, however, I run these via npm test, everything runs in exactly the same way but the process doesn't exit (I have to manually cancel it with ^c).
I can't work out how to debug exactly what is going on here in order to work out why the process isn't exiting.
It's worth noting that if I test a subdirectory (npm test ./test/queue) which does not interact at all with the database, then the process exits fine. These tests do, however, interact with an AMQP broker so there is some activity over sockets. This suggests to me that the database connection is causing the problem. I am using knex to connect to a postgres9.6 server. This also suggests that the pretest script is not the problem. If I try to run a suite of tests which do interact with the database, the process never exits (so presumably the open sockets are preventing it from doing so, but why this should only happen in the case of npm test rather than direct execution is beyond me).
Extra info:
node version: 8.7.0
mocha version: 4.0.1
npm version: 5.6.0
knex version: 0.14.0
I am using async/await in my codebase

I was mistaken in thinking this to be an npm problem. Rather, when I was running mocha in my shell it was using the globally installed mocha, which is of a different version to the locally installed one. Running with this version causes the same hanging issue.
This change in behaviour appears to be coming from this issue, which is described thus in the changelog:
By default, Mocha will no longer force the process to exit once all tests complete. This means any test code (or code under test) which would normally prevent node from exiting will do so when run in Mocha. Supply the --exit flag to revert to pre-v4.0.0 behavior (#ScottFreeCode, #boneskull)

Related

Running Jest from node in a CRA application with expose-gc

I'm having issues with memory leaks coming from running my test suites with Jest where memory usage keeps growing with each suite.
After searching through the net, I've found that this could be related to a garbage-collector behaviour, and multiple Github threads suggest running this command:
node --expose-gc ./node_modules/jest/bin/jest.js --coverage --runInBand --logHeapUsage
The issue is that my project uses React (with CRA not ejected) and Typescript, so whenever I run this script it throws a Syntax error because of Typescript.
I've tried installing ts-jest library but it does not work. It may be related, but running the ts-jest setup init complains about already having a configuration due to CRA.
I've been searching and I have not found anything, since all related threads are about the known memory leaks Jest has, but none explain how to execute the node command with the expose-gc in a project with React and Typescript.
Is there any way I can expose the GC to the Jest script used by CRA so I can keep using the same configuration as until now?
Otherwise, how can I execute the node --expose-gc jest parsing my files so that it does not throw an error?
I'd also need to use the --inspect-brk to see where the leak comes from, so even if the --detect-leaks works, I still need to find a way to execute my Jest config from node command.
Thank you!
After reviewing the documentation from Jest, I've seen this section which suggests to run the debug configuration in VS Code calling react-scripts. After playing a little bit with it, this is the command that got it working:
node --inspect-brk node_modules/react-scripts/scripts/test.js --no-cache --env=jsdom --runInBand
As you can see, you have to call the test.js file inside react-scripts directly, and then you can send all the arguments you want to Jest, as you'd normally do when running tests directly from the terminal of your project.
If you execute this script:
node --inspect-brk node_modules/react-scripts/bin/react-scripts.js test --no-cache --env=jsdom --runInBand
You will be able to attach to the node debugger, but you won't be able to set debugger stops in your test files, as it will attach to the main process, which is react-scripts (and not the test script itself).
Hope this might help someone in a future!

How to start node server before running end to end tests using npm run?

I'm writing end to end tests for an express site, and I want to add a "test" command into package.js
This command needs to:
run eslint
compile typescript
start node server
run unit tests against that server and show output.
once done testing, close the server.
I know how to execute all those commands individually, but not all at once.
What I have now is :
npm run compile && npm run build && node ./dist/server.js --db=test && npm run test
It works to the point of: "&& npm run test"
since node server is running, it won't continue on to the next command, and if it closes then tests wouldn't run.
Any help is appreciated.
One thing that I have found to help with reliable, maintainable end-to-end tests is to separate concerns:
Test suite assumes that the server is already running
Orchestrator calls into separate commands to bring up your test stack then run the tests
In CI, this could look like
npm start-e2e-test-stack --port=XXXX --db=test
npm test --port=XXXX --db=test
npm teardown-e2e-test-stack
In my experiences, having the end-to-end tests operate against any server helps to allow them to verify all environments, local, dev, qa, staging, production.

How to run a Go server in Travis-CI?

I'm working on a Go project that exposes a RESTful http API.
I want to run the Go project and use Nodejs (Mocha) to test the endpoints. It seems as if the nohup command doesn't keep running in the background.
Locally everything works but I don't seem to be able to get it running in Travis-ci.
language: go
go:
- 1.8
env:
- "PATH=/home/travis/gopath/bin:$PATH"
before_install:
- go get ./...
script:
- npm install mocha -g
- npm install
- nohup go run ./cmd/server/main.go --scheme=http --port=8080 --host=127.0.0.1 &
- mocha
First, you should seriously question whether writing tests in mocha makes sense. Admittedly, there might be cases when it does make sense (i.e. if you're porting a nodejs app to Go, and already have tests written for node). But even then, you should consider this a stop-gap measure, and write all new tests, and even migrate old tests, to Go as soon as possible.
But that aside, there's no reason you shouldn't be able to just start the process in the background normally. Perhaps with a shell script called from your Travis config (can often be cleaner and easier to follow than putting all commands in the config directly):
#!/bin/sh
go run &
mocha
If you really must run your tests in an external process, there are certain advantages from starting that from a Go test anyway. Namely, you can get test coverage stats, and starting can be more easily synchronized (so you don't need a sleep). To do this, you can follow my advice in this answer. Specifically, for the mocha case:
Write a test file that executes your main() function in a go routine:
func TestMainApp(t *testing.T) {
go main() // Or whatever you need to do to start the server process
cmd := exec.Command("mocha", ...)
cmd.Start()
}
But seriously. You should write your tests in Go.
Mocha runs directly after - nohup go run ./cmd/server/main.go --scheme=http --port=8080 --host=127.0.0.1 & so the server didn't start up yet.
Adding a sleep was enough.
script:
- npm install mocha -g
- npm install
- nohup go run ./cmd/server/main.go --scheme=http --port=8080 --host=127.0.0.1 &
- sleep 4
- mocha
But, the point is taken, I will move to Go tests :-P

Log to node console or debug during webpack build

What is the best practice for debugging during webpack build process? Any console.log in the entry script doesnt output to node console.
As of the current version of webpack (September 2019), if you do a build instead of launch a dev server, console.log will output to std out (i.e. the node console).
Just make sure you are doing a full build (i.e. "npm run build") instead of a dev server (i.e. "npm run dev").
The dev server disables console.logs during the compile process in many circumstances, and/or the way the progress bar updates, the console.log strings are overwritten so you never see them.

Running jasmine tests in Webstorm stops in trace with exit code 0

I run jasmine tests in my node.js application via grunt. I've added grunt test to Webstorm's run configurations.
In "Run/Debug Configurations" the "Grunt Test" has following properties specified: node interpreter (node.exe in Program Files), working directory (project location), JavaScript file (grunt binary), and application parameters (test - grunt task name).
The configuration works correctly but stops without printing full jasmine output. Sometimes before printing any output, most often after some part of jasmine log, but before test summary or error details. Always the last line of output is
Process finished with exit code 0
When I take the Webstorm command and run it manually in console it works fine and always prints full output:
"C:\Program Files\nodejs\node.exe" C:\...\node_modules\grunt-cli\bin\grunt test
My tests includes asynchronous cases, so it takes about 20 seconds to run them all.
I noticed that each attempt to run tests via Webstorm prints a bit longer output. First attempt ends without any but after ten further I got full output with test summary.
Known issue, please see http://youtrack.jetbrains.com/issue/WEB-1926 and discussion on stackoverflow (mocha + webstorm - error message broken)
To fix the case described in question we can run jasmine tests directly by jasmine-node command (skipping grunt).
We have to set up new "Run/Debug Configuration" based on "Node.js" pre-conf.
Node interpreter (as usual):
C:\Program Files\nodejs\node.exe
Working directory: project root,
JavaScript file:
node_modules\grunt-jasmine-node\node_modules\jasmine-node\lib\jasmine-node\cli.js
This is for my case (using grunt-jasmine-node). We can also provide path to cli.js of jasmine-node installed globally.
Application variables:
--verbose src/test/js
Of course the last one is a path to directory of tests in my project. Here we can specify list of files or use other jasmine-node commands and parameters.
The problem that process.exit() does not wait the stdout. You should defer the exit call with one tick, that's all.

Resources