【问题标题】:Ensure that fixtures exists when running a test. Control order of tests running确保在运行测试时存在固定装置。测试运行的控制顺序
【发布时间】:2022-06-13 19:28:43
【问题描述】:

其中很多都包含在命令中,但为了让问题更可行,我已经省略了这部分。

考虑这两个测试:

# Test1: Test login for user
 - Step1: Logs in manually (go to login-URL, fill out credentials and click 'Log in').
 - Step2: Save auth-cookies as fixtures.

# Test2: Test something is dashboard for user.
 - Step1: Set auth-cookies (generated in Test1)
 - Step2: Visits https:://example.org/dashboard and ensures the user can see the dashboard.

如果它们按照上面列出的方式运行,那么一切都很好。

但是如果 Test2 在 Test1 之前运行,那么 Test2 将会失败,因为 Test1 还没有生成 cookie。

所以 Test1 是 一种 Test2 的先决条件。

但 Test1 不需要在每次运行 Test2 时都运行 - 仅当未生成 auth-cookie 时。

我希望我可以将我的 Test2 定义为这样:

Test2: Test something is dashboard for user.
  - Step1: Run ensureAuthCookiesExists-command
  - Step2: If the AuthCookies.json-fixture doesn't exist, then run Test1
  - Step3: Sets auth-cookies (generated in Test1)
  - Step4: Visits https:://example.org/dashboard and ensures the user can see the dashboard.

方案尝试一:按顺序控制

很长一段时间以来,我一直使用这个答案:How to control order of tests。然后让我的测试定义如下:

{
  "baseUrl": "http://localhost:5000",
  "testFiles": [
    "preparations/*.js",
    "feature-1/check-header.spec.js",
    "feature-2/check-buttons.spec.js",
    "feature-3/check-images.spec.js",
    "feature-4/check-404-page.spec.js",
    //...
  ]
}

但这很烦人,因为这意味着我必须不断向该列表添加新功能,这很烦人。

只有在我想运行所有测试时才能解决问题。如果我想运行preparations.spec.js 及之后:feature-2/check-buttons.spec.js。那我就不能轻易做到了。


解决方案尝试 2:巧妙地命名测试

我也尝试简单地命名它们,比如在这里解释:naming your tests in Cypress

但这会污染测试的命名,使其更加混乱。它面临与解决方案尝试 1 相同的问题(我无法轻松地依次运行两个特定测试)。


解决方案尝试 3:为其创建命令

我考虑过创建一个测试它的命令。这是一些伪代码:

beforeEach(() => {
  if( preparationsHasntCompleted() ){
    runPreparations();
  }
}

这看起来很聪明,但它会为我的所有测试增加额外的运行时间。

【问题讨论】:

  • 您是否尝试在访问页面之前创建“批准模式和弹出窗口”cookie 以抑制模式?
  • 我真的不明白你的问题是什么。你能解释一下你的最终目标是什么样的吗?功能前怎么没有做好准备?
  • 建议让测试独立工作;仅提供凭据作为夹具。

标签: cypress


【解决方案1】:

这可能不适合您的测试目标,但新的cy.session() 可以确保无论测试处理顺序如何设置 cookie。

supportbeforeEach() 中使用它在每次测试之前运行。

运行的第一个测试(test1 或 test2)将执行请求,后续测试将使用缓存值(不重复请求)。

// cypress/support/e2e.js       -- v10 support file

beforeEach(() => {
  cy.session('init', () => {
    // request and set cookies
  })
})
// cypress/e2e/test1.spec.cy.js

it('first test', () => {
  // the beforeEach() for 1st test will fire the request
  ...
})
// cypress/e2e/test2.spec.cy.js

it('second test', () => {
  // the beforeEach() for 2nd test will set same values as before from cache
  // and not resend the request 
})

优势:

  • 每次运行执行一次登录(参考运行时问题)
  • 以任何顺序执行测试
  • 对会话中的所有测试使用相同的令牌(如果这很重要)

缺点:

  • 如果手动获取身份验证 cookie (vi UI),有效地将登录测试移动到 beforeEach()

通过请求登录示例

除了通过 UI 获取 auth cookie,还可以通过cy.request() 获取。

来自文档的示例,

cy.session([username, password], () => {
  cy.request({
    method: 'POST',
    url: '/login',
    body: { username, password },
  }).then(({ body }) => {
    cy.setCookie('authToken', body.token)
  })
})

【讨论】:

    【解决方案2】:

    一般不建议编写如best practices 中所述的相互依赖的测试。您永远无法确定它们是否正确运行。在您的情况下,如果第一个测试失败,所有其他测试都将失败,即使组件/功能正常运行。特别是如果您测试的不仅仅是纯登录过程,例如设计。

    正如@Fody 之前所说,您可以确保在 beforeEach() 挂钩中登录。 我会这样做:

    • 使用一个描述通过 UI 测试登录。
    • 使用另一个描述在before() 中放置登录名(通过 REST)并在beforeEach() 中使用以下命令Cypress.Cookies.preserveOnce('<nameOfTheCookie>'); 以不删除以下it()s 的测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 1970-01-01
      • 2015-02-25
      • 2012-11-28
      相关资源
      最近更新 更多