【问题标题】:Reading dynamic file name in cypress test spec在赛普拉斯测试规范中读取动态文件名
【发布时间】:2020-07-30 03:45:53
【问题描述】:

如何参数化赛普拉斯规范中的文件名并加载该文件?我通过工作正常的环境变量注入其他参数,但是提供给require(...) 的任何内容都不会作为文件找到(尽管错误消息以与硬编码完全相同的方式指定文件名)。

describe('run test', () => {
  const data = require('../fixtures/my.json');
  it('foo', () {
   ...
  });

因此,换句话说,上面的片段的行为不同于:

describe('run test', () => {
  const file = Cypress.env('file');
  const data = require('../fixtures/' + file);
  data.forEach((entry) => {
    it(`foo testing ${entry}`, () {
     ... run a test based on `entry`
    });
  });

当通过$(npm bin)/cypress run ... --env file=my.json 从命令行调用 cypress 时。在提供file 参数的示例中,将显示文件未找到错误消息(包含与硬编码文件名示例相同的确切文件路径)。我相信这是因为 require() 在运行时没有得到解决(但在此之前因此不能接受动态参数),但我不是 100% 确定并且也会考虑读取文件的替代方法。

【问题讨论】:

  • 您不使用cy.fixture(`/folder/${file}`).then()的具体原因是什么?
  • 因为它似乎不可能:“不能在运行测试之外调用cy.fixture()。”
  • ????我个人在before() 中使用cy.fixture()describe() 块中。我稍后会尝试解决这个问题
  • 我找到了这个示例食谱,你想要的似乎是不可能的?! fundamentals__dynamic-tests 很乐意听到您找到解决方案
  • 我通过您的链接设法实现了文件加载器。 docs.cypress.io/api/commands/…readFileMaybebefore() 中被调用,并将外部文件的内容存储在一个变量中,然后在测试用例中访问该变量(我使用来自外部的标识符通过 env 变量来构建测试用例,这些标识符引用加载文件中的值)。动态加载数据的相当间接的方法,但到目前为止它工作正常。

标签: javascript unit-testing cypress


【解决方案1】:

这是动态测试用例创建规范的基本结构。它由环境变量和文件的组合填充。环境变量ids 中的元素指定各个测试用例参数的键,这些参数在单独的文件中提供(也通过环境变量指定))。 ids 通过外部脚本进行序列化和分隔。

通过以下方式调用此脚本:

$(npm bin)/cypress run --config-file cypress.json --headless --env ids=foo@bar@blah,paramsFile=myParamfile.json

功能/test_xyz.js

let paramsFile = Cypress.env('paramsFile');
let ids = Cypress.env('ids');


describe('My test', () => {
  let params;

  before(() => {
    cy.task('readFileMaybe', paramsFile).then(fileContent => {
      if (fileContent === null) {
        throw new Error(`Could not find file ${paramsFile}.`);
      }
      // params = {id1: testcaseParam2, id2: testcaseParam2, ...}
      // `testcaseParamX` are objects or arrays and can therefore not be passed
      // easily into the test case via environment variables.
      params = JSON.parse(fileContent);
    });
  });

  // `ids` is a string -> needs to be split
  // e.g. `ids.split(delim).forEach(...)` to actually run.
  ids.forEach(id => {
    // Create test case.
    it(`test case for ${id}`, () => {
      let param = params[id];

      // run assertions here...
    });
  });
});

plugins/index.js (reference)

module.exports = (on, config) => {
  on('task', {
    // Needs to be done through a task, as we can't access `fs` in test case
    // (this task runs in Node which allows use of external libraries).
    readFileMaybe(filename) {
      // console.log('Loading ', filename);
      if (fs.existsSync(filename)) {
        return fs.readFileSync(filename, 'utf8');
      }
      // console.log('Could not find ', filename);
      return null;
    }
  });
};

开始工作非常痛苦。但是,直接在 Node 中运行 Cypress 上下文之外的命令的能力非常强大,也可以用于类似的问题。我希望其他人觉得这很有用。

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 2021-10-20
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 2021-11-06
    • 2020-05-16
    相关资源
    最近更新 更多