我熟悉Mocha对delaying the root suite的支持,以通过使用带有--delay
标志的Mocha运行在执行测试之前执行异步操作,但这会影响所有测试。
是否可以在不使用--delay
标志的情况下逐个测试地执行类似的操作?
下面是一个有效的异步测试示例,但不幸的是,我们并非所有测试都异步并调用run()
。请注意,以下示例还利用dynamically generating tests为在套件执行之前在异步操作期间检测到的每个URL生成测试。
driver = await new Builder().forBrowser('chrome').build();
await driver.get('http://example.org');
await driver.findElements(By.css('article header a')).then(async function (anchors) {
Promise.all(
anchors.map(async anchor => {
return new Promise(async function (resolve, reject) {
try {
const href = await anchor.getAttribute('href');
urls.push(href);
resolve();
} catch (err) {
console.log('Catch')
reject(err);
}
})
})
).then(function () {
driver.quit();
describe('my suite', function () {
urls.forEach(function (url) {
it(`Loads ${url}`, async function () {
await driver.get(url);
await driver.getTitle().then(function (title) {
assert.strictEqual(1, 1);
});
});
});
});
run();
})
});
按照@destroyer的建议,我成功使用asynchronous hooks(如下)完成了类似的工作,但是由于Mocha不会延迟根套件的执行,因此无法为每个URL动态生成单独的测试。
describe('Async test suite', function () {
const getAnchors = function () {
return new Promise(async (resolve) => {
driver = await new Builder().forBrowser('chrome').build();
await driver.get('http://example.org');
await driver.findElements(By.css('article header a'))
.then(async (anchors) => {
resolve(anchors);
})
});
}
const getUrls = function (anchors) {
return new Promise(async resolve => {
for (i = 0; i < anchors.length; i++) {
urls.push(await anchors[i].getAttribute('href'));
if (i === (anchors.length - 1)) {
resolve(urls);
}
}
});
}
const iterateUrls = function (urls) {
return new Promise(async (resolve, reject) => {
for (i = 0; i < urls.length; i++) {
await driver.get(urls[i])
const thisUrl = await driver.getCurrentUrl();
try {
await assert.strictEqual(thisUrl, urls[i]);
} catch (err) {
reject(err);
break;
}
if (i === (urls.length - 1)) {
resolve();
}
}
})
}
async function asyncController() {
Promise.all([
anchors = await getAnchors(),
await getUrls(anchors)
])
}
// Trigger async functions here
before(function (done) {
asyncController()
.then(() => {
done();
})
});
// Close the browser after test completes
after(async function () {
await driver.quit()
});
describe('Checks URLs', function () {
it('Iterates over URLs', async function (done) {
try {
await iterateUrls(urls);
} catch (err) {
done(err);
}
});
});
});