问题描述
问题:
尝试在从 Cypress 自定义命令返回的项目数组中调用测试。
尝试使用 npm 包 mocha-each 的方法和使用 forEach
函数的另一个测试。
自定义命令:
我创建了一个返回 AppParamsType
数组的自定义 Cypress 命令:
/// <reference types="Cypress" />
import { AppParamsType } from 'support';
declare global {
namespace Cypress {
interface Chainable {
cmdGetAppsParams: () => Chainable<AppParamsType[]>;
}
}
}
export function cmdGetAppsParams() {
const paramsApps: AppParamsType[] = [];
cy.cmdAppKeys()
.then(($appKeys: string[]) => {
cy.wrap($appKeys).each(($appKey: string) => {
cy.cmdProviderAppParams($appKey).then((paramApp: AppParamsType) => {
paramsApps.push(paramApp);
});
});
})
.then(() => {
return cy.wrap(paramsApps);
});
}
Cypress.Commands.add('cmdGetAppsParams',cmdGetAppsParams);
使用自定义命令进行测试:
以下 Cypress 测试调用自定义命令 cmdGetAppsParams()
以返回项目数组。
使用 npm 包 mocha-each 进行一次测试和使用 Array forEach 进行另一次测试对数组进行迭代。两种方法都不会调用循环内的测试。
import * as forEach from 'mocha-each';
let apps: AppParamsType[];
describe('DESCRIBE Apps Add Apps Spec',() => {
before('BEFORE',() => {
cy.cmdGetAppsParams().then(($apps: AppParamsType[]) => {
expect($apps).to.be.an('array').not.empty;
apps = $apps;
});
});
it('TEST Apps Params Array',() => {
cy.task('log',{ line: 'A',data: apps });
expect(apps).to.be.an('array').not.empty;
});
it('TEST each item mocha forEach',{ line: 'B',data: apps });
forEach(apps).it('item',(item: AppParamsType) => {
cy.task('log',{ line: 'B.1',data: item });
expect(item).to.be.an('object').not.null;
});
});
it('TEST each item array forEach',{ line:'C',data: apps });
expect(apps).to.be.an('array').not.empty;
apps.forEach((item: AppParamsType) => {
it('TEST App Param',() => {
cy.task('log',{ line: 'C.1',data: item });
expect(item).to.be.an('object').not.null;
});
});
});
我看到的结果是外部测试,由标签'A'、'B'和'C'表示,正在被调用。但是,不是由标签 'B.1' 和 'C.1' 指示的内部测试:
{
"line": "A","data": [
***
]
}
{
"line": "B","data": [
***
]
}
{
"line": "C","data": [
***
]
}
解决方法
在 it()
中嵌套 it()
看起来很新颖。我很惊讶你没有从中得到错误。
动态生成测试的基本问题是 Cypress 运行器需要在开始运行它们之前确切知道将生成多少个测试。但是任何 Cypress 命令(包括自定义命令)在整个测试脚本运行完毕(不包括回调代码)之前都不会运行,因此您无法从自定义命令中获取 apps
列表。
最好的方法是将 cy.cmdAppKeys()
、cy.cmdGetAppsParams()
和 cy.cmdProviderAppParams()
从自定义命令转换为普通的 javascript 函数,然后在脚本顶部运行该函数,例如
const apps = getMyApps(); // synchronous JS function,// will run as soon as the test starts
apps.forEach((item: AppParamsType) => {
const titleForTest = `Test App Param ${item.name}`; // Construct an informative title
it(titleForTest,() => {
...
})
})
如果您能提供自定义命令cy.cmdAppKeys()
和cy.cmdProviderAppParams()
的详细信息,或许可以帮助转换为同步函数。