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
Related
I am currently working in Cypress, I will try to semplify my question as much as possible:
I have several test files:
integration/testA.spec.js
integration/testB.spec.js
integration/testC.spec.js
I also have a config.js file in which I have an object containing the name of the test I want to run:
{
test: 'testA.spec.js'
}
what I want to do - if possible - is a main.spec.js file that, depending on the testproperty, runs the relative spec file.
I have prepared almost everything
describe('Test', () => {
before(() => {})
beforeEach(() => {})
after(() => {})
describe('Test Booking', () => {
// retrieves the `test`property and returns the string name
let testName = retrieveTestName()
console.log('testName', testName)
/** I want to do something like this */
if (testName === 'testA.spec.js') {
// launch testA.spec.js file
}
}
})
but I ignore if I can do something like the code above; do you think is possible?
Or do I have to create a script file that
checks for the namefile
uses the --spec option and launches the test
?
An option can be to create commands using the --spec file and add it under scripts in your package.json. Something like:
"scripts": {
"testA": "npx cypress run --spec "cypress/integration/testA.spec.js",
"testB": "npx cypress run --spec "cypress/integration/testB.spec.js",
"testC": "npx cypress run --spec "cypress/integration/testC.spec.js"
}
You can run directly run the above command depending on the test you want to execute.
npm run testA
We have been building our automation suite using our staging environment, but are going live soon and want to be ready to tell the project where to run (staging, production).
The only difference between the sites in the environments is the URL. My question is, from start to finish, how can I set the .page URL via a CLI option?
Right now, I have created an environment config file that holds our staging and production URLS and then I call the data into my test files. This is fine for now, but I will need to create a script with an option to set the environment at runtime without having to do a manual find and replace before kicking it off.
I've looked around online and find, what I believe, to be code snippets and general instructions, but I'm not a dev at heart and go crossed eyed. If I could get an ELI5 for this, that would be awesome.
Example of what I'm doing now:
const env = require('../environment_variables.json')
fixture `blog`
.page `${env.production}`
And then I change production to staging or vice versa manually before kicking off the suite.
Since the project will run from CICD, I would like to be able to do something like this in my CLI and script:
testcafe env=production
The env value will then be set where the .page call is for every test file.
Thanks!
There are different ways of doing this. I've used environment variables successfully in this situation, so I'll share this solution since it will solve your problem.
I create config.json in the root of the project:
{
"baseUrl": {
"dev": "https://dev.com/",
"staging": "https://staging.com/",
"prod": "https://prod.com/"
}
}
Then I create two helper functions somewhere like Helpers/env.js:
import config from '../config';
function getEnv () {
return process.env.TESTCAFE_ENV;
}
function getBaseUrl () {
return config.baseUrl[getEnv()];
}
export { getEnv, getBaseUrl };
Then in my test files in Tests/:
import { getBaseUrl } from '../Helpers/env';
const baseUrl = getBaseUrl();
fixture `Test Suite`
.page(baseUrl);
And that's it. Then when I need to run tests on the dev, I execute:
$ TESTCAFE_ENV=dev testcafe
for staging:
$ TESTCAFE_ENV=staging testcafe
and for production:
$ TESTCAFE_ENV=prod testcafe
In v1.20.0 and later, TestCafe offers a way to specify the baseUrl in the test run configuration. You can use this approach along with environment variables, see the following example:
.testcaferc.js
const BASE_URL_MAP = {
dev: 'https://dev.com/',
staging: 'https://staging.com/',
prod: 'https://prod.com/'
};
module.exports = {
baseUrl: BASE_URL_MAP[process.env.TESTCAFE_ENV]
};
Alternatively, you can use different configuration files for each of the required setups using the --config-file option.
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)
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.
If we have a unit test file my-spec.js and running with mocha:
mocha my-spec.js
The default timeout will be 2000 ms. It can be overwritten for partial test with a command line parameter:
mocha my-spec.js --timeout 5000
Is it possible to change the default timeout globally for all tests?
i.e. the default timeout value will be different from 2000 ms when you call:
mocha my-spec.js
By default Mocha will read a file named test/mocha.opts that can contain command line arguments. So you could create such a file that contains:
--timeout 5000
Whenever you run Mocha at the command line, it will read this file and set a timeout of 5 seconds by default.
Another way which may be better depending on your situation is to set it like this in a top level describe call in your test file:
describe("something", function () {
this.timeout(5000);
// tests...
});
This would allow you to set a timeout only on a per-file basis.
You could use both methods if you want a global default of 5000 but set something different for some files.
Note that you cannot generally use an arrow function if you are going to call this.timeout (or access any other member of this that Mocha sets for you). For instance, this will usually not work:
describe("something", () => {
this.timeout(5000); //will not work
// tests...
});
This is because an arrow function takes this from the scope the function appears in. Mocha will call the function with a good value for this but that value is not passed inside the arrow function. The documentation for Mocha says on this topic:
Passing arrow functions (“lambdas”) to Mocha is discouraged. Due to the lexical binding of this, such functions are unable to access the Mocha context.
Just adding to the correct answer you can set the timeout with the arrow function like this:
it('Some test', () => {
}).timeout(5000)
Adding this for completeness. If you (like me) use a script in your package.json file, just add the --timeout option to mocha:
"scripts": {
"test": "mocha 'test/**/*.js' --timeout 10000",
"test-debug": "mocha --debug 'test/**/*.js' --timeout 10000"
},
Then you can run npm run test to run your test suite with the timeout set to 10,000 milliseconds.
In current versions of Mocha, the timeout can be changed globally like this:
mocha.timeout(5000);
Just add the line above anywhere in your test suite, preferably at the top of your spec or in a separate test helper.
In older versions, and only in a browser, you could change the global configuration using mocha.setup.
mocha.setup({ timeout: 5000 });
The documentation does not cover the global timeout setting, but offers a few examples on how to change the timeout in other common scenarios.