I'm having trouble changing my mocha tests to jest tests.
I have three test files with three classes: FirstTestGroup, SecondTestGroup and ThirdTestGroup, each with a static execute method, that contains some tests, like this:
class FirstTestGroup {
execute(params) {
describe('some tests', function tests() {
it('one test', () => {
// uses params
});
...
});
...
}
}
Each of those execute methods use the same parameters. These parameters are created in an async before call, like shown bellow.
describe('My Tests', function testSuite() {
let params;
before('param creation', async function asyncFunc() {
// creates params asynchronously
});
it('should pass all', () => {
FirstTestGroup.execute(params);
SecondTestGroup.execute(params);
ThirdTestGroup.execute(params);
});
});
The it('should pass all', ...) is needed because everything inside a describe is run instantly, so params would be passed as null without it. This works in mocha because "it"s can be nested, but apparently this is not the case for jest.
I could make the beforeAll (equivalent of before in jest) be called each time before a test group is run, but I didn't want to do that as this seems inefficient.
I could also place the code inside the before call before the describe('My Tests', ...) is defined. This seems wrong as this should be part of the describe only.
I couldn't find anything in the jest documentation that could help me with that.
Am I doing something wrong? Is there a way to achieve this using jest, even if I have to restructure the tests? But I'd like to keep the tests in different files.
This is my first question here, so please tell me if more info is needed as I'm not used writting here.
Have you tried Jest-Codemods yet?
Jest-Codemods allows you to convert your Mocha, AVA, Jasmine tests into equivalent Jest tests. It would also help you migrate assertion libraries such as Chai and Expect.
The way you do it:
Install jest-codemods with npm install -g jest-codemods
Go to your project and execute jest-codemods
It will ask you Which test library would you like to migrate from?
Select Mocha by using arrow keys (As you want to migrate from Mocha)
Next, It will ask you Will you be using Jest on Node.js as your test runner?
Select Yes, use the globals provided by Jest (recommended)
Last, You need to provide file name on which you are working to migrate from Mocha to Jest.
And you are done!
It will automatically migrate your code from Mocha to Jest. No need to touch code. That's one of the most powerful feature of Jest which would save your time and you don't need to worry about changing mocha tests to jest tests.
Related
I have a jest.mock in my test for a node_modules module:
jest.mock('#namespace/some_node_modules_module', () => ({
SOME_CONST: 'const_value,
SOME_OTHER_CONST: 'other_const_value'
});
When I run this test directly, via jest test_name.test.ts it works nicely and module clearly gets mocked, test passess - everything fine. However when it is run with other tests (with runInBand or without it) mocking clearly fails and whole testing sequence errors out in the end.
Any ideas?
The developer guide makes it sound like you can only use jest with the cdk. However, our projects currently use mocha. We could use jest for the cdk and keep everything else the same, but we're wondering if anyone has had any luck using mocha to test the cdk.
EDIT:
So far, it seems to have worked with this simple set up:
installed ts-node, mocha
ran with mocha -r ts-node/register file.test.ts
file.test.ts:
import { expect as expectCDK, matchTemplate, MatchStyle } from '#aws-cdk/assert';
import * as cdk from '#aws-cdk/core';
import * as Infrastructure from '../lib/infrastructure-stack';
it('Empty Stack', () => {
const app = new cdk.App();
// WHEN
const stack = new Infrastructure.InfrastructureStack(app, 'MyTestStack');
// THEN
expectCDK(stack).to(matchTemplate({
"Resources": {}
}, MatchStyle.EXACT))
});
Has anyone tried more complicated tests?
I believe the cdk assert library was written with jest in mind but I couldn't find any classes that will only work with jest so it should work with any test framework since they provide their own expectations function, cdkExpect
Suppose my test setup has the following pattern:
Build a model for this test
Initialize some application based on this model
Test the functioniality in the application
As part of #3, there are some async functions which can be run.
I have thousands of tests and want to create a safeguard against leaks of async functions into other tests- in other words, developers who forget to await for the result
My idea is as follows - Implement an afterEach in a global context which would check if an applcation instance was created for this test. If it was, I can catch all open async functions from here, and throw an error
To do this, I would need to have a testId instance or test context to which I can register the app instance when creating it for tests.
If we were using jasmine and old ES5 syntax, jasmine has a userContext feature which would make this easy:
it('some test', async function(){
this.appInstance = createAppInstance(model)
...
})
afterEach(function(){
if(this.appInstance){
...
}
})
Is there a way to do something like this in jest?
I have a file tests.js that contains some test(...) definitions. I want to reuse these tests across multiple fixtures, preferably without making any modifications to the original code.
So I wrote a main.js that defines a fixture and imports tests.js, thereby "assembling" a test suite. (In case that works, I could write different driver files with different fixtures, importing the same tests.js from within each.)
However, I'm getting a test is not defined error when trying to execute main.js:
C:\Windows\Temp\dummy>testcafe chrome main.js --debug-on-fail
ERROR Cannot prepare tests due to an error.
ReferenceError: test is not defined
at Object.<anonymous> (C:\Windows\Temp\dummy\tests.js:1:1)
at Object.<anonymous> (C:\Windows\Temp\dummy\main.js:7:1)
Type "testcafe -h" for help.
Minimal sample:
// tests.js
test('wait', async t => {
await t.wait(1);
});
// main.js
fixture `here goes the name`
.page("http://localhost:3000")
.beforeEach(async t => {
// do stuff
});
import "./tests";
/*
trick testcafe to scan the file;
based on https://github.com/DevExpress/testcafe/issues/2889#issuecomment-423859785
test();
*/
I already tried:
removing the block comment hack (test();) - which gives ERROR No tests to run. Either the test files contain no tests or the filter function is too restrictive.
moving the tests.js import to the top - still gives test is not defined
importing testcafe from within main.js and tests.js - same error
Is there a way to make the test function "visible" to other files imported by the testcafe entrypoint file? Or will I actually need to modify my tests.js file in order to get this working? Maybe by adding the test definitions into a method, and invoking it from within main.js - as in the original code sample of this issue?
TestCafe doesn't allow calling fixture and test functions outside the test scope. You can wrap your tests from the tests.js file in a function and call this function in the main.js file:
// tests.js
export default function () {
test('Test 1', () => {});
test('Test 2', () => {});
test('Test 3', () => {});
}
// main.js
import defineTests from './tests';
defineTests();
See also: Organize Tests
Try to add the option --disable-test-syntax-validation on the TestCafe command-line
(works only in latest TestCafe version).
Since we've switched to generators I haven't been able to find a coverage tool to support this.
We use generators both in our code and in the mocha tests themselves.
We have enabled generators within the mocha tests by using co-mocha.
The only option I have in mind would be to transpile the tests instead of running them in their harmony mode.
Unit-coverage have basic harmony support.
Details here.
But, I can't use this tool correctly: I have error, when use class.
Awhile back co-mocha worked nicely for me. Later on in a new codebase it didn't. After some digging I found that mocha simply isn't handling promises properly anymore and it's probably related to node 5; I've logged a ticket.
With promise handling working properly, you theoretically shouldn't need to monkeypatch mocha to use generators. Simply using co.wrap() like so should work:
it('should yield in the generator', co.wrap(function*() {
yield aPromiseReturningFunction();
yield aGeneratorFunction();
}));
In the meantime, I've written a lil utility function that wraps a generator using co.wrap() and passes done as the then and catch handlers to the promise it returns:
function done(gen) {
const wrapper = co.wrap(gen);
return function(done) {
return wrapper.call(this, done).then(done).catch(done);
};
}
Then I do this:
it('should yield in the generator', done(function*() {
yield aPromiseReturningFunction();
yield aGeneratorFunction();
}));