问题的摘要:我正在编写几个测试套件(使用jest和puppeteer(来自动化我的angularjs应用程序的index.html页面。不幸的是,我在进行测试时看到了一些奇怪的行为,我认为这与玩笑的顺序相关。
背景:我正在使用开玩笑(V24.8.0(作为我的测试框架。我正在使用Puppeteer(v1.19.0(来旋转并控制一个铬浏览器,以便在该浏览器上进行测试。
我的代码:
<!-- index.html -->
<div ng-app="myApp" ng-controller="myCtrl as ctrl">
<form name="form1">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name1"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
<form name="form2">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name2"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
</div>
// index.spec.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://my-site.com');
describe('form 1', async () => {
test('populate form 1', async () => {
let formSelector = 'form[name="form1"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('casey');
let submitButtonSelector = 'form[name="form1"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
describe('form 2', async () => {
test('populate form 2', async () => {
let formSelector = 'form[name="form2"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('jackie');
let submitButtonSelector = 'form[name="form2"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
await browser.close();
})();
测试行为:有时当我运行npm test
时,似乎我的两个测试套件'form1'
和'form2'
(我用describe
定义(正在并行运行(尽管我知道这在JavaScript中是不可能的,所以我假设我是玩笑异步运行不同的测试套件(。无论哪种方式,当我以非头部模式运行测试时,我都可以看到form1
的名称输入是用'jackie'
填充的,即使应该是'casey'
。在此之后,form2
永远不会填写(即使我的第二个测试套件应该这样做(,并且测试完成了,此后JEST告诉我'populate form 2'
失败了。同样,这不会发生我进行测试的每个时间,因此您可能无法复制我的问题。
我的问题:
玩笑是否并行/异步运行测试套件?注意:我不是在谈论测试套件中使用
test
定义的单个测试,我知道如果我通过async
函数,这些测试是异步运行的。如果玩笑确实不同步运行测试套件,我该如何禁用?或者更好的是,智能/常规/最佳功能是否可以提供不同的测试套件不同的
browser
实例,以便它们在完全独立的窗口中运行?还有其他方法可以确保分别运行和/或同步运行?JEST不同步运行测试套件,那么您为什么认为我看到这种行为?
我要问的是因为我想找到一种方法来确保我所有的测试始终通过,而不是在某些时候。从长远来看,这将使我更容易确定我在开发过程中的更改是否打破了任何东西。
事先感谢您所有的开玩笑/木偶黑客!
默认情况下,Jest在每个文件中同时在每个文件中运行测试,但根据最大工人的不同,但运行全部描述和测试在文件中串行。
如果要在频段中串行运行所有文件,这将删除工人池。
但是,我建议重构,您可以嵌套describe
块
// instead of IIFE, nest describes for better parsing for jest and readability
describe('forms', async () => {
const browser = await puppeteer.launch({headless: false});
describe('form 1', () => {
test('populate form 1', async () => {
// make every test independent of the other to avoid leaky scenarios
const page = await browser.newPage();
await page.goto('https://my-site.com');
let formSelector = 'form[name="form1"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('casey');
let submitButtonSelector = 'form[name="form1"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
describe('form 2', () => {
test('populate form 2', async () => {
const page = await browser.newPage();
await page.goto('https://my-site.com');
let formSelector = 'form[name="form2"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('jackie');
let submitButtonSelector = 'form[name="form2"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
await browser.close();
})
update
在nodejs中,您可以产生过程,如果是开玩笑,每个过程都是一个节点实例,它们通过标准io进行通信。您可以告诉Jest通过CLI选项产生多少个,但是,当使用略带玩笑的工人时,我会遇到性能退化,这是因为NodeJS实例是重量级的,而Spawn/Sync可能比实际运行更为昂贵在乐队或几个工人中。
另外,如果您想产生10个进程,您的操作系统可能会安排全部到同一CPU线程,并且它们将以串联运行。