Do you want to request a _feature_ or report a _bug_?
feature
What is the expected behavior?
is it possible to loop its in Jest
describe('...', () => {
// first way
for (let test in tests) {
it('...', () => {
expect(...).toBe(...)
})
}
// second way
tests.forEach((test) => {
it('...', () => {
expect(...).toBe(...)
})
})
})
yes it is, just do it like you wrote.
but I got this error: JavaScript heap out of memory
const testcases = require('./testcases.data') // it's JSON
describe('...', () => {
testcases.forEach((test) => {
it('...', () => {
expect(...).toBe(...)
})
})
})
that means it is very likely you have an infinite loop somewhere and node just crashes.
Thank @cpojer maybe I do thing wrong
You don't get the before/after hooks making tests dynamically for some reason. I'm guessing the dynamic functions are out of scope.
@cpojer is it also doable with forEach? I'm encountering a race to the finish situation
I have a beforeAll() that fetches info from a local API endpoint.
the it() inside my forEach seems to sometimes run before the done() is called in the beforeAll()
What you can't do unfortunately is create tests dynamically where you have to do some async setup work, eg:
const createTest = async (config) => {
const foo = await api(config.url)
for (let test in config.tests) {
it('...', () => {
expect(...).toBe(...)
})
}
}
createTest(config)
That would work if there was no async/await.
I am running into the same problem with Puppeteer and Jest.
I just ran into this same issue. My setup needs to be async, but I guess jest needs to discover all the it blocks ahead of time
The same here, we need to call beforeAll
to upload a files to S3 bucket. However, a dynamically created it(...)
is called before result from beforeAll
resolves.
All describes
, it
s and test
s must be defined synchronously. Doing async work in hooks is possible though, and to use that inside tests. You cannot use it to _define_ tests, though.
Neither for loop nor forEach are working. Jest is not able to see any test!
fs.readdir('./testingImages/', async (err, images) => {
if (err) {
throw err;
}
for (const image in images) {
if (image) {
const imagePath = './testingImages/' + image;
it(`convertor should validate the image ${image}`, async () => {
const convert: any = await imageConvertor(imagePath);
expect(typeof convert).toBe('string');
fs.unlinkSync(convert); // clean up
});
}
}
});
Jest error:
Your test suite must contain at least one test.
@A-Atrash see: https://jestjs.io/docs/en/troubleshooting#defining-tests
@thymikee OK, so there is no way then?
There's always a way! You have at least 2 options:
1) generate tests based on the testingImages/
using a script.
2) put everything in one test
statement
I lean towards 1) because it will result in better test parallelization, while solution 2) will always run tests one-by-one
@thymikee can you give me a small example of the first 馃榿
No time for that. I'm sure you'll figure it out :)
You can use fs.readdirSync
as well, that should be possible
@thymikee I did it 馃槇
@SimenB Thanks!
@A-Atrash Care to share your solution to dynamically creating tests?
Dirty hack:
Run your tests via runCLI. Before the call you can do you async requests and wait for it. Then you pass in a static data to you Jest config as global
:
test.ts
import {runCLI} from 'jest';
import projectConfig from '../../../jest.config.js';
export const test = async (specs: string) => {
// Do your async preparation
const requests = await dereference(specs);
// Run jest
const result = await runCLI({
...projectConfig,
globals: JSON.stringify({requests}) // <--- Here we pass it in
}, [join(__dirname, '../project/root/')]);
}
mydynamic.test.ts
// Write your test
describe(`Test endpoints of ${specsPath}`, () => {
// @ts-ignore
const requests = global.requests; // <--- Here you go. Your async data
for (const request of requests) {
it(`${request.method} ${request.path}`, async () => {
// Yeah, now you can access even everything initialized in beforeAll() :-)
});
}
});
Most helpful comment
yes it is, just do it like you wrote.