Mocha Testing in Separate Files and Dotenv

On the way become backend developer
Search for a command to run...

On the way become backend developer
No comments yet. Be the first to comment.
Well, I was just learning Playwright days ago and I've got an issue with Webkit. I think I could share this with you as you might encounter the same issue with Playwright. I'm impressed with Playwright; the tests are fast enough and available in thre...

Concept Using if/else statement is always related to boolean, whether it is true or false. This checking may be called a truthiness check. In Javascript if/else statement not always about boolean data type but also behavior. Variables might have the ...

Introduction For those who need Linux, Windows already have WSL, but for some reason, I prefer to choose a virtual machine. IMO, WSL might be a good option for simple tasks but not for software development. For example a cron job, you have to configu...

The main goal of dividing tests into multiple files is to make tests readable and easier to maintain. Each file should be responsible for a single responsibility. Here is how I separate tests into multiple files:
First, we need to specify which files mocha will test. I personally create*.test.js to specify that mocha will only run files with .test.js. So another file that should be a part of the main test will be ignored. For this example, I will create a math module.
Let's say our project has math_problem.js file in src as our module.
const sumData = (a, b, c = 0) => {
return a + b + c;
};
module.exports = { sumData };
I assume our project already has mocha and chai in project dependencies. Complete source code available in my GitHub repository
For the first problem, create part of test 1. problem_one.part.js in tests/modules directory
const { sumData } = require("../../src/math_problem");
const { expect } = require("chai");
const problem_one_test = () => {
it("has to be 4", () => {
const result = sumData(2, 2);
expect(result).eql(4);
});
};
module.exports = problem_one_test;
Then for the test file create function.test.js in tests directory.
process.env.NODE_ENV = "testing";
const problemOne = require("./modules/1. problem_one.part");
describe("math problem", () => {
describe("problem one", problemOne.bind(this));
});
In this file, I force Node environment to testing, it is not required for this project, but this would help if you need a specific environment for testing.
Finally in your package.json add test command in scripts section
"scripts": {
"test": "mocha tests/*.test.js --exit"
},
Done!.
Now you can run mocha test in separate files by run npm test or npm run test.
Let's say you already create a variable that would be required for test part files. To pass a variable from main test file to part file, we create a parent function.
Now, create 2. problem_two.part.js in tests/moduels directory.
const { sumData } = require("../../src/math_problem");
const { expect } = require("chai");
const problem_two_test = (c) => {
return function () {
it("has to be 8", () => {
const result = sumData(2, 2, c);
expect(result).eql(8);
});
};
};
module.exports = problem_two_test;
Assume in our test, c variable will be added from c param in problem_two_test function. So c variable will be required for tests available in 2. problem_two.part.js file.
In function.test.js file, import problem two by adding code below after problemOne variable
const problemTwo = require("./modules/2. problem_two.part")(4);
and add another decribe test for problemTwo
describe("problem two", problemTwo.bind(this));
Sofunction.test.js file will be like this
process.env.NODE_ENV = "testing";
const problemOne = require("./modules/1. problem_one.part");
const problemTwo = require("./modules/2. problem_two.part")(4);
describe("math problem", () => {
describe("problem one", problemOne.bind(this));
describe("problem two", problemTwo.bind(this));
});
Done, Now we can pass variable from main function to test part file.
in this line
const problemTwo = require("./modules/2. problem_two.part")(4);we pass4ascparam in2. problem_two.part.jsfile. co variableproblemTwowill return test functions and already hascparam.
Breaking tests into multiple test files will benefit easier and more readable code. But how if you want to test only a single file before being added to the main test case? We don't want to test every test just to make sure that a specific test is right.
In order to test a single test file running, we create describe test in every part files but if only it run in single test command. So to make a difference from batch test, in function.test.js we set a TEST_MODE environment variable. Add process.env.TEST_MODE = "batch"; below NODE_ENV.
So function.test.js file will be like this:
process.env.NODE_ENV = "testing";
process.env.TEST_MODE = "batch";
const problemOne = require("./modules/1. problem_one.part");
const problemTwo = require("./modules/2. problem_two.part")(4);
describe("math problem", () => {
describe("problem one", problemOne.bind(this));
describe("problem two", problemTwo.bind(this));
});
And for each part files, add describe test, so each file will be like this below.
1. problem_one.part.js file:
const { sumData } = require("../../src/math_problem");
const { expect } = require("chai");
const problem_one_test = () => {
it("has to be 4", () => {
const result = sumData(2, 2);
expect(result).eql(4);
});
};
if (process.env.TEST_MODE !== "batch") {
describe("problem one", problem_one_test.bind(this));
}
module.exports = problem_one_test;
2. problem_two.part.js file:
const { sumData } = require("../../src/math_problem");
const { expect } = require("chai");
const problem_two_test = (c) => {
return function () {
it("has to be 8", () => {
const result = sumData(2, 2, c);
expect(result).eql(8);
});
};
};
if (process.env.TEST_MODE !== "batch") {
describe("problem one", problem_two_test(4).bind(this));
}
module.exports = problem_two_test;
In package.json file, add test-single command, so scripts section will be like this
"scripts": {
"test": "mocha tests/*.test.js --exit",
"test-single": "mocha --exit"
},
now you can test each file by run command like this
npm run test-single-env '.\tests\modules\1. problem_one.part.js'
What if you have a .env file for testing? You want to create a specific environment for your test. There are many ways to load Node environment from .env file. You will need dotenv dependency here. Assume you have already installed it in your project. For example, we create third test case.
Create 3. problem_three.part.js in tests/modules directory. Write code like below
const { sumData } = require("../../src/math_problem");
const { expect } = require("chai");
const problem_three_test = () => {
it("has to be 10", () => {
const result = sumData(2, 2, Number(process.env.STATIC_NUMBER));
expect(result).eql(10);
});
};
if (process.env.TEST_MODE !== "batch") {
describe("problem three", problem_three_test.bind(this));
}
module.exports = problem_three_test;
Now add test case in functions.test.js file
process.env.NODE_ENV = "testing";
process.env.TEST_MODE = "batch";
const problemOne = require("./modules/1. problem_one.part");
const problemTwo = require("./modules/2. problem_two.part")(4);
const problemThree = require("./modules/3. problem_three.part");
describe("math problem", () => {
describe("problem one", problemOne.bind(this));
describe("problem two", problemTwo.bind(this));
describe("problem three", problemThree.bind(this));
});
Dotenv will be loaded in script command, so make test command that require dotenv/config in package.json file. I will define specific file .env. for testing environment.
In .env.testing file, assume we have STATIC_NUMBER environment variable
STATIC_NUMBER=6
For package.json file add script command below
"scripts": {
"test": "mocha tests/*.test.js --exit",
"test-single": "mocha --exit",
"test-env": "mocha -r dotenv/config tests/*.test.js --exit dotenv_config_path=./.env.testing",
"test-single-env": "mocha -r dotenv/config --exit dotenv_config_path=./.env.testing"
},
Now the test-env and test-single-env commands will automatically load .env.testing file to environment variable.
You might notice a warning message
Cannot find any files matching pattern "dotenv_config_path=./.env.testing". This is because mocha also read this as spec test file param.