【问题标题】:Overriding Cypress' before and after methods覆盖 Cypress 的 before 和 after 方法
【发布时间】:2024-01-14 00:05:01
【问题描述】:

我们正在使用 Cypress.io 来构建我们的自动化套件。我们需要在每次测试之前为我们的数据库播种并在之后清除数据。这可以像下面那样完成。

describe('Our test suite', function() {
  before(function () {
    //loadDbSeed is a custom command that will load the seed file based on the spec file
    seed = cy.loadDbSeed()
    cy.task('seed:db', seed)
  })

  it('should be true', function() {
    //Some test with some action followed by an assertion
    cy.visit('/some-page')
    cy.get('[data-cy="identifier"]')
      .click()
    expect(true).to.equal(true)
  })

  after(function () {
    // clearDb is a custom command that will clear out the DB.
    // We are still debating if we must clear the DB after the tests.
    // But we might still need to do some common actions for the entire suite after
    cy.clearDb()
  })
})

我们看到的问题是我们所有的测试套件都需要相同的beforeafter 操作。所以我们想覆盖这些方法,以便我们的测试是这样的。

describe('Our test suite', function() {
  before(function () {
    // DB seeding is done automatically
    // Write only custom before steps required for this test
  })

  it('should be true', function() {
    //Some test with some action followed by an assertion
    cy.visit('/some-page')
    cy.get('[data-cy="identifier"]')
      .click()
    expect(true).to.equal(true)
  })

  after(function () {
    // DB clearing is done automatically
    // Write only custom after steps required for this test
  })
})

我们如何实现这一目标?我一直在研究 Cypress 代码,但没有发现任何明显的东西。

【问题讨论】:

  • 您只需将 before()after() 方法添加到 '/cypress/support/index.js` 中,它们就会在每个套件中运行。请注意,您仍然可以在套件本身内部拥有特定于套件的 before()after(),事实上您可以拥有任意多次 - 它们按照它们出现的顺序被调用(首先支持它们)。
  • 理查德,非常感谢。我们将试试这个,看看它是否有效!

标签: testing automation cypress


【解决方案1】:

如果您查看赛普拉斯文档,不建议使用 after - Cypress Docs。我会警告不要在全球范围内设置数据,你真的需要它来进行每次测试吗?如果您需要在某个时候基于每个测试输入数据,这会与此全局数据冲突吗?你可以在每个测试的基础上做这样的事情:

describe('Our test suite', function() {
  beforeEach(function () {
     cy.then(async () => {
       await MyDatabaseService.resetdata()
       await MyDatabaseService.createSomeData()
     });
   });

  it('should be true', function() {
    //Some test with some action followed by an assertion
  })
})

当特定测试需要特定数据时,我还必须嵌套一些测试,如下所示(对不起,如果这里的某些格式有点不对,希望它会有意义!):

describe('Our test suite', function() {
  beforeEach(function () {
     cy.then(async () => {
       await MyDatabaseService.resetdata()
       await MyDatabaseService.createSomeData()
     });
   });

  it('should be true', function() {
    //Some test with some action followed by an assertion
  });

   describe('These tests need more data, this is a nested describe', function () {
     before(function () {
       cy.then(async () => {
         await MyDatabaseService.addSomeMoreData()
       });
     it('this test uses the extra data', function () {
     // Do some funky tests here
    });
   });
 });

})

对于上面的第二个测试,测试将运行所有三个数据库操作。

结果是,如果您在运行测试之前清除数据,那么事情就会变得更加清晰。

我希望这会有所帮助。我自己是 Cypress 的新手,很难改掉我们在 Selenium 中使用了一段时间的(坏的?)习惯!

【讨论】:

  • 西蒙,非常感谢您的意见。我没有在我的问题中说清楚(并为此道歉),但我们实际上并没有在全球范围内播种数据。每个规范或测试都有自己的种子 JSON 文件,我们只需要一种机制来在 before 块中加载相关的种子文件,而无需再次重写相同的代码。这有意义吗?
  • 关于after的使用,正如我在中提到的,我们仍在争论这个问题。我不清楚的一个方面是,如果每个测试都不清理数据库,我们如何确保测试彼此独立?例如,测试 1 在数据库中创建一个新项目并验证创建工作。测试 2 是一个独立的使用搜索和过滤器验证列表中的项目数。如果我们不重置和加载仅与测试 2 相关的数据,我们如何确保测试 1 不会影响测试 2?
  • 我猜在这种情况下,赛普拉斯建议测试 1 只是删除它添加的项目,而不是有一个通用的 after 块来重置整个数据库。对吗?
最近更新 更多