nodejs: how to run tests and then build dockerfile - node.js

I am trying to create a basic CI CD Pipeline, I am trying to create batch file to run tests and then execute the docker build. here is my basic batch file
#ECHO OFF
call npm run test
call docker build -t my-docker-file .
PAUSE
how can I know if all the tests were run successfully? I am using mocha and chai

First of all you will need to use --exit flag to execute your tests. My package.json looks like this:
"test": "mocha test --timeout 4000 --exit"
So the console will not stuck open when the tests finish.
Then, the idea is create a communication between batch and node. I've used bash but the idea is the same.
Basically is write in the .env file if tests has been passed and after the execution check if variable is set to true or not.
First of all, to do this you need to update your test.js file with this.
I use envfile. You can check this question
//get the reference to your environment file and update
//THIS is you have to add
afterEach(function () {
const state = this.currentTest.state;
if (state !== "passed") {
//write into .env: MYENVVAR=0
}
});
Then, you will have into your .env file a variable to know if the tests has been executed correctly.
So, the next step is read the value in your batch process and continue if is ok.

Related

How to knowif all tests have passed with mocha

I would like to know if it is possible to execute something if all my test files have passed with mocha.
Below: is my index.js file which is run by mocha (in order to get the order I want)
require('dotenv').config();
const logger = require('../toolkits/logger');
//silent mode for testing
logger.transports.forEach((t) => (t.silent = true));
require("./broker.test");
require("./mongo.test");
require("./auth.test");
require("./meal.test");
require("./bowl.test");
I want to process.exit(0) if the tests passed (to integrate it into gitlab CI).
I succeded in check if a test hasn't passed by doing this :
afterEach(function(){
if (this.currentTest.state === "failed")
process.exit(1);
})
But I can't detect if all the tests passed.
I can't just process.exit(0) after requiring all the tests because some of them are asynchronous.
Do you have an idea how I can do that?
! Update !
I found out that I could pass the --exit argument when running mocha from npm :
mocha file --exit

How do launch/shutdown a Docker container before/after a mocha Test for NodeJS?

We have a NodeJS application that depends on an external database. Currently I run the mocha tests in one of two ways:
manually start a docker container, run the tests, shutdown the container
on merge using a github action (service works like a charm)
What I would like to achieve:
Being able to run my tests using npm run testsuite that starts my database container, run the mocha test and shut down the container
On investigation I found plenty of tutorials how to run tests inside a container using docker or docker-compose, but nothing how to "just" launch a temp container for the database only.
Help is very much appreciated
Encapsulate your test like so in your package.json:
{
"scripts": {
"test": "docker-compose up -d && mocha && docker-compose down"
}
}
The -d flag will allow the shell to keep processing commands after the container starts. Otherwise the docker container will indefinitely block your shell (and your tests). In case you're not using docker compose, you can always run:
docker run -d
Hopefully that helps!
I'm assuming you may be starting the test using mocha runtime with npm test -- if that's the case you may want to try starting the mocha tests by calling the API directly from a node file.
In your wrapper Node file you can try and start up the container, then start Mocha.
//start container
const mocha = new Mocha();
//more config
mocha.run( ...etc )
//shut down container

How to setup mocha to run unit tests first and then start a server and run integration tests

I have unit tests and integration tests that need to be run with one 'npm run mocha' command. The suite before my integration tests was set up and working properly with mocha.opts including the before step like so:
test/beforeTests.js (sets up some important variables)
test/*.x.js (bulk of the tests, all the files ending in .x.js are run)
When including my integrations tests, a unit test fails because the running server clashes with some stubbed functions. Therefore I wanted to run unit tests first, then star the server, run integration tests and close the server. Which I have tried by changing mocha.opts to:
test/beforeTests.js (sets up some important variables)
test/*.x.js (bulk of the tests, all the files ending in .x.js are run)
test/startServer.js (start the server)
test/integration/*.x.js (run integration tests)
test/afterTests.js (close the server)
beforeTests.js:
before(function(done) {
// do something
});
startServer.js:
before(function() {
return runServer()
});
both beforeTests, and startServer work however they are both executed in the beginning of the test instead of
beforeTest > do unit tests > start server > do integration tests > stop server
I cannot merge the integration tests in one file, or the unit tests as there are too many. Is there a way to set up mocha.opts to do what I want. I've looked around and nothing really fits what I want to do.
One of technique that I use before for this is to have two npm commands for unit and integration test then combine them in one npm command if I want to run them in single execution.
"test": "npm run test:unit && npm run test:integration"
"test:unit": "mocha test/unit",
"test:integration": "mocha test/integration"
You can start server as part of integration test.
I suggest to use test for npm test instead of mocha for npm run mocha because it is more standard test command name in node project.
Hope it helps

Separation of unit tests and integration tests

I'm interested in creating full mocked unit tests, as well as integration tests that check if some async operation has returned correctly. I'd like one command for the unit tests and one for the integration tests that way I can run them separately in my CI tools. What's the best way to do this? Tools like mocha, and jest only seem to focus on one way of doing things.
The only option I see is using mocha and having two folders in a directory.
Something like:
__unit__
__integration__
Then I'd need some way of telling mocha to run all the __unit__ tests in the src directory, and another to tell it to run all the __integration__ tests.
Thoughts?
Mocha supports directories, file globbing and test name grepping which can be used to create "groups" of tests.
Directories
test/unit/whatever_spec.js
test/int/whatever_spec.js
Then run tests against all js files in a directory with
mocha test/unit
mocha test/int
mocha test/unit test/int
File Prefix
test/unit_whatever_spec.js
test/int_whatever_spec.js
Then run mocha against specific files with
mocha test/unit_*_spec.js
mocha test/int_*_spec.js
mocha
Test Names
Create outer blocks in mocha that describe the test type and class/subject.
describe('Unit::Whatever', function(){})
describe('Integration::Whatever', function(){})
Then run the named blocks with mochas "grep" argument --grep/-g
mocha -g ^Unit::
mocha -g ^Integration::
mocha
It is still useful to keep the file or directory separation when using test names so you can easily differentiate the source file of a failing test.
package.json
Store each test command in your package.json scripts section so it's easy to run with something like yarn test:int or npm run test:int.
{
scripts: {
"test": "mocha test/unit test/int",
"test:unit": "mocha test/unit",
"test:int": "mocha test/int"
}
}
mocha does not support label or category. You understand correctly.
You must create two folders, unit and integration, and call mocha like this
mocha unit
mocha integration

Sails.js testing with mocha only runs one test not two

I followed the sails.js testing example at http://sailsjs.org/#!/documentation/concepts/Testing . I have got it to run, but it only runs one test. The command line in package.json script.test is:
mocha test/bootstrap.test.js test/unit/**/*.test.js
"test/unit/**/*.test.js" should be catching 2 tests, UsersControllers.test.js and Users.test.js . It is only running Users.test.js . And yes, both tests are in the test/unit/ directory.
What am I doing wrong here ?
After copying the documented test cases from the sails js docs, make sure to change the following line in the User.test.js file
describe.only('UsersModel', function() {
to
describe('UsersModel', function() {
then you should see the controller test as well.

Resources