Cant configure unit tests correctly with mocha - javascript

I am trying to configure mocha on a typescript project, but not working fine
I am using book: Typescript design patterns, chapter 1.
When I run mocha it says:
Warning: Could not find any test files matching pattern: out/test/ No
test files found
mocha.opts
--require ./test/mocha.js
out/test/
mocha.js
require('chai').should();
starter.js
describe('some feature', () => {
it('should pass', () => {
'foo'.should.not.equal('bar');
});
it('should error', () => {
(() => {
throw new Error();
}).should.throw();
}); });

Based on the error, it seems that mocha is trying to look for tests in the /out directory. First off, try removing /out/test from mocha.opts or replacing it with src/test to see if that resolves the path issue.
You could also try moving mocha.js into the /src/test directory, and move the mocha.opts to the /src directory.
Then, when running mocha, make sure you run from the root of the project (which in this case seems to be src)

Related

Mocking node modules with Jest and #std/esm

I'm currently having an issue writing tests for a node application that uses #std/esm. I've setup a manual mock of a node module inside a __mocks__ directory and the following code shows a test for the file uses this mocked node module. (It's used in db.mjs)
const loader = require('#std/esm')(module, { cjs: true, esm: 'js' })
const Db = loader('../src/db').default
const db = new Db()
describe('getNotes', () => {
it('gets mocked note', () => {
db.getNote()
})
})
However, when I run Jest, my manual mock is not being used, it is using the real node module.
Does anyone have any thoughts on why this could be happening?
Jest is particular about the location of your mocks. From their documentation on mocking node modules:
For example, to mock a scoped module called #scope/project-name,
create a file at mocks/#scope/project-name.js, creating the
#scope/ directory accordingly.
In your case it would be __mocks__/#std/esm.js

How to properly require modules from mocha.opts file

I'm using the expect.js library with my mocha unit tests. Currently, I'm requiring the library on the first line of each file, like this:
var expect = require('expect.js');
describe('something', function () {
it('should pass', function () {
expect(true).to.be(true); // works
});
});
If possible, I'd like to remove the boilerplate require code from the first line of each file, and have my unit tests magically know about expect. I thought I might be able to do this using the mocha.opts file:
--require ./node_modules/expect.js/index.js
But now I get the following error when running my test:
ReferenceError: expect is not defined
This seems to make sense - how can it know that the reference to expect in my tests refers to what is exported by the expect.js library?
The expect library is definitely getting loaded, as if I change the path to something non-existent then mocha says:
"Error: Cannot find module './does-not-exist.js'"
Is there any way to accomplish what I want? I'm running my tests from a gulp task if perhaps that could help.
You are requiring the module properly but as you figured out, the symbols that the module export won't automatically find themselves into the global space. You can remedy this with your own helper module.
Create test/helper.js:
var expect = require("expect.js")
global.expect = expect;
and set your test/mocha.opts to:
--require test/helper
While Louis's answer is spot on, in the end I solved this with a different approach by using karma and the karma-chai plugin:
Install:
npm install karma-chai --save-dev
Configure:
karma.set({
frameworks: ['mocha', 'chai']
// ...
});
Use:
describe('something', function () {
it('should pass', function () {
expect(true).to.be(true); // works
});
});
Thanks to Louis answer and a bit of fiddling around I sorted out my test environment references using mocha.opts. Here is the complete setup.
My project is a legacy JavaScript application with a lot of "plain" js files which I wish to reference both in an html file using script tags and using require for unit testing with mocha.
I am not certain that this is good practice but I am used to Mocha for unit testing in node project and was eager to use the same tool with minimal adaptation.
I found that exporting is easy:
class Foo{...}
class Bar{...}
if (typeof module !== 'undefined') module.exports = { Foo, Bar };
or
class Buzz{...}
if (typeof module !== 'undefined') module.exports = Buzz;
However, trying to use require in all the files was an issue as the browser would complain about variables being already declared even when enclosed in an if block such as:
if (typeof require !== 'undefined') {
var {Foo,Bar} = require('./foobar.js');
}
So I got rid of the require part in the files and set up a mocha.opts file in my test folder with this content. The paths are relative to the root folder:
--require test/mocha.opts.js
mocha.opts.js content. The paths are relative to the location of the file:
global.assert = require('assert');
global.Foo = require("../foobar.js").Foo;
global.Bar = require("../foobar.js").Bar;
global.Buzz = require("../buzz.js");

How to set execution order of mocha test cases in multiple files

I have two javascript files which contain mocha test cases.
//----------abc.js -------------
describe("abc file", function(){
it("test 1" , function(){
assert.equal(20 , 20);
});
});
//---------xyz.js--------------
describe("xyz file", function(){
it("test 1" , function(){
assert.equal(10 , 10);
});
});
I have put them in a folder called test and when I execute the mocha command the first file(abc.js) is always executed before xyz.js.
I thought this might be due to alphabetical ordering and renamed the files as
abc.js => xyz.js
xyz.js => abc.js
but still, the content of the xyz.js (previously abc.js) is executed first. How can I change the execution order of these test files?
In the second file, require the first one:
--- two.js ---
require("./one")
or if you are using ES modules:
--- two.js ---
import "./one"
Mocha will run the tests in the order the describe calls execute.
I follow a totally seperate solution for this.
Put all your tests in a folder named test/ and
Create a file tests.js in the root directory in the order of execution
--- tests.js ---
require('./test/one.js')
require('./test/two.js')
require('./test/three.js')
And in the tests files one.js, two.js and so on write your simple mocha tests
this way if you want to run them in the order you have defined then just run mocha tests.js
Mocha has a --sort (short -S) option that sorts test files:
$ mocha --help
[...]
-S, --sort sort test files
[...]
Since mocha sorts files in alphabetical order, I usually prefix my test files names with numbers, like:
0 - util.js
1 - something low level.js
2 - something more interesting.js
etc.
In addition to being really easy to maintain (no gulp grunt or any of that nonsense, no editing your package.json...), it provides the benefit that:
people reading your source code get an idea of the structure of your program, starting from the less interesting parts and moving up to the business layer
when a test fails, you have some indication of causality (if something failed in 1 - something.js but there are no failures in 0 - base.js then it's probably the fault of the layer covered by 1 - something.js
If you're doing real unit tests of course order should not matter, but I'm rarely able to go with unit tests all the way.
If you prefer a particular order, you can list the files (in order) as command-line arguments to mocha, e.g.:
$ mocha test/test-file-1.js test/test-file-2.js
To avoid a lot of typing every time you want to run it, you could turn this into an npm script in your package.json:
{
// ...
"scripts": {
"test": "mocha test/test-file-1.js test/test-file-2.js"
}
// ...
}
Then run your suite from the command line:
$ npm test
Or if you're using Gulp, you could create a task in your gulpfile.js:
var gulp = require('gulp');
var mocha = require("gulp-mocha");
gulp.task("test", function() {
return gulp.src([
"./test/test-file-1.js",
"./test/test-file-2.js"
])
.pipe(mocha());
});
Then run $ gulp test.
The way it worked for my tests to be executed in a specific order was to create a separate test.js file and then added a describe for each mocha test file I'd wanted to execute.
test.js:
describe('test file 1', function() {
require('./test1.js')
})
describe('test file 2', function() {
require('./test2.js')
})
Then simply run mocha test.js
I am exporting an array with all required files and that is the way I tell mocha the order of execution through index.js file in the folder with all my test files:
const Login = require('../login');
const ChangeBudgetUnit = require('./changeBudgetUnit');
const AddItemsInCart = require('./addItemsInCart');
// if the order matters should export array, not object
module.exports = [
Login,
ChangeBudgetUnit,
AddItemsInCart
];
mocha-steps allows you to write tests that run in a specific sequence, aborting the run at the first failure. It provides a drop-in replacement for it, called steps.
Example usage:
describe('my smoke test', async () => {
step('login', async () => {})
step('buy an item', async () => throw new Error('failed'))
step('check my balance', async () => {})
xstep('temporarily ignored', async () => {})
})
The repo hasn't seen much activity in three years, but it works fine with Mocha 9.

How to wait for a grunt task to complete before running mocha tests

In a nutshell...
I have some grunt tasks with external configs that I want to test (make sure they do what they're supposed to do). So I'd like to write a mocha test running the tasks in the before function and asserting everything went well.
...and with some details
In my gruntfile there is something like
# Load task configs from `grunt` dir.
configs = require('load-grunt-configs') grunt,
config:
src: ['tasks/*{.js,.json,.coffee,.cson}']
# Load all **grunt tasks** with patter `grunt-*`
require('load-grunt-tasks') grunt, pattern: [
'grunt-*'
]
# Pass configs to grunt
grunt.initConfig configs
and afterwards some task registration...
However I now have access to my less task residing as a less.cson in my tasks folder
(which uses grunt-contrib-less).
So far so good. :)
I'm using chai for assertions:
describe('Checking static resources for dev', function () {
describe('less task', function () {
before(function () {
grunt.task.run('less');
});
it('should have a compiled css file for docs', function () {
grunt.file.isFile('public/css/docs.css').should.be.ok;
grunt.file.isFile('public/css/docs.css.map').should.be.ok;
});
As expected, the task completes after the tests were run since it's not async and I don't know a way to tell grunt (without modifying the existing task/config) that it should call a possible done function when ready and then make the assertion.
I also tried grunt-run-task but could not manage to run any task (they abort with a timeout although I gave them more than 20 seconds to complete).
Guess I'm looking for something like
before(function (done) {
grunt.task.run('less', done);
});
Anyone some advice?

How to run a single test with Mocha?

I use Mocha to test my JavaScript stuff. My test file contains 5 tests. Is that possible to run a specific test (or set of tests) rather than all the tests in the file?
Try using mocha's --grep option:
-g, --grep <pattern> only run tests matching <pattern>
You can use any valid JavaScript regex as <pattern>. For instance, if we have test/mytest.js:
it('logs a', function(done) {
console.log('a');
done();
});
it('logs b', function(done) {
console.log('b');
done();
});
Then:
$ mocha -g 'logs a'
To run a single test. Note that this greps across the names of all describe(name, fn) and it(name, fn) invocations.
Consider using nested describe() calls for namespacing in order to make it easy to locate and select particular sets.
Depending on your usage pattern, you might just like to use only. We use the TDD style; it looks like this:
test.only('Date part of valid Partition Key', function (done) {
//...
}
Only this test will run from all the files/suites.
If you are using npm test (using package.json scripts) use an extra -- to pass the param through to mocha
e.g. npm test -- --grep "my second test"
EDIT: Looks like --grep can be a little fussy (probably depending on the other arguments). You can:
Modify the package.json:
"test:mocha": "mocha --grep \"<DealsList />\" .",
Or alternatively use --bail which seems to be less fussy
npm test -- --bail
Just use .only before 'describe', 'it' or 'context'. I run using "$npm run test:unit", and it executes only units with .only.
describe.only('get success', function() {
// ...
});
it.only('should return 1', function() {
// ...
});
run single test –by filename–
Actually, one can also run a single mocha test by filename (not just by „it()-string-grepping“) if you remove the glob pattern (e.g. ./test/**/*.spec.js) from your mocha.opts, respectively create a copy, without:
node_modules/.bin/mocha --opts test/mocha.single.opts test/self-test.spec.js
Here's my mocha.single.opts (it's only different in missing the aforementioned glob line)
--require ./test/common.js
--compilers js:babel-core/register
--reporter list
--recursive
Background: While you can override the various switches from the opts-File (starting with --) you can't override the glob. That link also has
some explanations.
Hint: if node_modules/.bin/mocha confuses you, to use the local package mocha. You can also write just mocha, if you have it installed globally.
And if you want the comforts of package.json: Still: remove the **/*-ish glob from your mocha.opts, insert them here, for the all-testing, leave them away for the single testing:
"test": "mocha ./test/**/*.spec.js",
"test-watch": "mocha -R list -w ./test/**/*.spec.js",
"test-single": "mocha",
"test-single-watch": "mocha -R list -w",
usage:
> npm run test
respectively
> npm run test-single -- test/ES6.self-test.spec.js
mind the -- which chains whatever text comes after it to the npm script
There are multiple ways by which you can do this.
If you just want to run one test from your entire list of test cases then, you can write only ahead of your test case.
it.only('<test scenario name>', function() {
// ...
});
or you can also execute the mocha grep command as below
mocha -g <test-scenario-name>
If you want to run all the test cases which are inside one describe section, then you can also write only to describe as well.
describe.only('<Description of the tests under this section>', function() {
// ...
});
If you have multiple test files & you wanted to run only one of then you can follow the below command.
npm test <filepath>
eg :
npm test test/api/controllers/test.js
here 'test/api/controllers/test.js' is filepath.
You can try "it.only"
it.only('Test one ', () => {
expect(x).to.equal(y);
});
it('Test two ', () => {
expect(x).to.equal(y);
});
in this the first one only will execute
Hi above solutions didn't work for me.
The other way of running a single test is
mocha test/cartcheckout/checkout.js -g 'Test Name Goes here'
This helps to run a test case from a single file and with specific name.
Looking into the doc, we see that simply using:
mocha test/myfile
will work. You can omit the '.js' at the end.
Using Mocha's --fgrep (or just -f) you can select tests containing string, for example:
mocha -f 'my test x'
will run all tests containing my test x in either it(), describe() or context() blocks.
For those who are looking to run a single file but they cannot make it work, what worked for me was that I needed to wrap my test cases in a describe suite as below and then use the describe title e.g. 'My Test Description' as pattern.
describe('My Test Description', () => {
it('test case 1', () => {
// My test code
})
it('test case 2', () => {
// My test code
})
})
then run
yarn test -g "My Test Description"
or
npm run test -g "My Test Description"
Not sure why the grep method is not working for me when using npm test. This works though. I also need to specify the test folder for some reason.
npm test -- test/sometest.js
Consolidate all your tests in one test.js file and add a script in your package.json:
"scripts": {
"api:test": "node_modules/.bin/mocha --timeout 10000 --recursive api_test/"
},
Type this command in your test directory:
npm run api:test

Categories