赛普拉斯:自定义命令返回数组:如何循环运行测试套件?

问题描述

问题:

尝试在从 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()的详细信息,或许可以帮助转换为同步函数。