簡體   English   中英

有條件地跳過賽普拉斯的測試

[英]Skipping a test in Cypress conditionally

我試圖找出我是否能夠在我的測試套件中有條件地跳過測試it()並處理它的異步性質。

我已經在 Cypress 文檔https://docs.cypress.io/guides/core-concepts/conditional-testing.html以及關於它的 mochajs文檔 https://mochajs.org/ 中閱讀了有關條件測試的信息。

我的目的是檢查網站上是否顯示錯誤,如果顯示錯誤則跳過測試。 否則繼續斷言。

我試圖在 Cypress 中測試的來自 mochajs 的代碼片段是:

it('should only test in the correct environment', function() {
  if (/* check test environment */) {
    // make assertions
  } else {
    this.skip();
  }
});

所以我在賽普拉斯得到的是:

it('shows the list', function() {
    if (queryFailed()) {
      this.skip();
    } else {
      cy.get('.list')
        .should('be.visible')
    }

請注意,我將it()中的箭頭 function 更改為function()以便我可以使用this

queryFailed()是一個 function 檢查查詢是否成功。

function queryFailed() {
  cy.get('.spin')
    .then($container => {
      const htmlLoaded = $container[0].innerHTML;

      if (htmlLoaded.indexOf('List') !== -1) {
        return false;
      }

      if (htmlLoaded.indexOf('error') !== -1) {
        return true;
      }

      cy.wait(1000);
      queryFailed();
    });
}

簡而言之,如果我等待的div元素的內容有“錯誤”,那么我知道查詢失敗,所以我返回 true,否則我返回 false。

我在調試后的測試中看到的是,即使條件運行良好,JS 的異步特性也會同時執行else語句中的代碼而不是if語句。 所以最后的 output 就好像根本沒有條件一樣,因為一切都經過了測試。

有沒有更好的方法來處理 JS 的這種異步特性?

謝謝詳細的說明! 我為你的第一個問題提供了解決方案

我試圖找出我是否能夠在我的測試套件中有條件地跳過測試 it() 並處理它的異步性質。

使用環境變量,我向您報告我的解決方案(實際上在我的管道中使用)。

if (!Cypress.env("SKIP_E2E_TESTS")) {
  it(...);
}

在我的package.json文件中,我有一個看起來像這樣的腳本

"test": "CYPRESS_SKIP_E2E_TESTS=true npm-run-all --parallel --silent test:unit test:cypress",

我的目標和你的一樣,我想在某些情況下禁用一些測試(在我的例子中是 CI 管道)。

因此,將整個測試放入條件中,而不是進行條件測試。

如果您需要更多幫助,請告訴我😉

Cypress 現在還提供了一個庫@cypress/skip-test ,它可以通過以下方式提供更多控制

  • cy.skipOn
  • cy.onlyOn
  • isOn
  • 布爾標志
  • 有頭/無頭環境
  • 環境

披露:我與賽普拉斯無關。

我正在使用@NoriSte 答案的改編版本,該版本仍會注冊測試,但已跳過:

const maybeDescribe = Cypress.env('SOME_ENV_VAR') ? describe : describe.skip

maybeDescribe('Test suite', function() { /* ... */ })

然后類似地,在 CI 上,我想跳過測試:

export CYPRESS_SOME_ENV_VAR=
$(npm bin)/cypress run

我的源代碼控制cypress.json定義了SOME_ENV_VAR因此當我在本地運行時,不會跳過測試。

我想你快到了,但是你需要異步回調模式而不是同步if () {...} else {...}模式。

it('shows the list', function() {

  const whenFailed = function() {
    this.skip()
  }

  const whenSucceeded = function() {
    cy.get('.list').should('be.visible')
  }

  queryFailed(whenFailed, whenSucceeded);
}

function queryFailed(whenFailed, whenSucceeded) {
  cy.get('.spin')
    .then($container => {
      const htmlLoaded = $container[0].innerHTML;

      if (htmlLoaded.indexOf('List') !== -1) {
        whenSucceeded();
        return;
      }

      if (htmlLoaded.indexOf('error') !== -1) {
        whenFailed();
        return;
      }

      cy.wait(1000);
      queryFailed(whenFailed, whenSucceeded);
    });
}

但是,我注意到對queryFailed()的遞歸調用,看起來您正在手動重試旋轉容器的內容。

Cypress 內置了重試功能,因此您要做的就是決定您的結果可能需要的最長時間(比如 20 秒),它會在所需內容到達時立即結束命令,或者如果它完全失敗則測試失敗不會在 20 秒內發生。

此外,您應該控制微調器正在等待的任何內容的成功/失敗(例如,通過 XHR 獲取列表)。 所以你應該把測試分成兩部分——一個成功,一個失敗。

context('when the list loading succeeds' function() {

  it('shows the list', function() {
    // Mock XHR success here
    cy.contains('.spin', 'List', { timeout: 20000 });
    cy.get('.list').should('be.visible');
  })

  it('does not show an error message', function() {
    ...
  })

})

context('when the list loading fails' function() {

  it('does not show the list', function() {
    // Mock XHR failure here
    cy.contains('.spin', 'error', { timeout: 20000 });
    cy.get('.list').should('not.be.visible');
  })

  it('shows an error message', function() {
    ...
  })

})

這有點粗糙,因為我不知道預期的確切 HTML,或者微調器正在等待什么,但您可以看到這種模式更加整潔,並以受控方式測試所有路徑。

最新的方法是通過@cypress/skip-test 但是,我對 cypress v10 和 TypeScript 的用法與自述文件中的用法略有不同:

yarn add --dev @cypress/skip-test

無需進一步設置,只需在規范中:

import { skipOn } from '@cypress/skip-test'

describe('something', () => {
  skipOn(Cypress.env('mySetting') === 'settingValue', () => {
    it('can do something', () => {
      // ...
    })
  })
})

我們正在使用 Ben Mosher 的改編版本

const maybeDescribe = Cypress.config("baseUrl") === "https://your-env-url/" 
? describe 
: describe.skip
   
maybeDescribe('Test something... or not dunno', function() { /* */ })

似乎也適用於運行測試的 Github 工作流。

Cypress Real World App一個支付應用程序,用於演示 Cypress 測試方法、模式和工作流的實際使用情況,其中包含一些用於在 CI 中有條件地運行測試的工作流,以及用於移動視口的已更改工作流。

此外,從 Cypress v4.8.0 開始,某些測試配置可應用於套件或單個測試。

例如:

it('Show warning outside Chrome', {  browser: '!chrome' }, () => {
  cy.get('.browser-warning')
   .should('contain', 'For optimal viewing, use Chrome browser')
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM