将数据从一个步骤同步传递到下一个步骤

时间:2018-11-19 20:17:56

标签: cucumberjs cypress

运行带有cypress-cucumber-preprocessor 1.5.1的Cypress 3.1.1。我需要将一些静态数据从一个步骤传递到另一步骤(在相同的场景/测试中)。我可以使用别名来做到这一点,就像这样: cy.wrap(someString).as('myString'),但随后我必须异步访问它:

cy.get('@myString').then(myString => ...)

这相当麻烦,特别是当我必须传递多个值(需要多个包装的闭包)而没有明显的好处时。 (当前,我正在通过为对象添加别名来解决此问题,但是我不需要这样做。)

如何将原始值从一个步骤同步传递到另一个步骤?

我想我可以简单地设置this.myString=''来设置Mocha共享上下文对象上的值,但是在那种情况下,该属性存在,但是在以后的步骤中访问时设置为undefined。

即使在步骤定义之外使用let创建自己的上下文变量也不起作用。这仅仅是赛普拉斯和/或赛普拉斯黄瓜预处理器的限制吗?

3 个答案:

答案 0 :(得分:3)

我设法通过以下方式使其工作:

  1. 在/plugins/index.js中添加2个任务
const testStore = {}
    module.exports = (on, config) => {
      on('task', {
        pushValue({ name, value }) {
          console.log(name, value)
          testStore[name] = value
          console.log(testStore)
          return true
        },
      })
      on('task', {
        getValue(name) {
          return testStore[name]
        },
      })
  1. 然后,您可以在任何测试中添加变量,并在其他任何地方访问它:
it('test', ()=>{
   cy.task('pushValue', { name: 'orderNumber', value: orderNumber })
})
it('test 2', ()=>{
    cy.task('getValue', 'orderNumber').then((order) => {
      cy.visit(`/bookings/${order}`)
    })   
})

答案 1 :(得分:0)

这不是一个完整的答案,但是您可以在before(() => {})语句中设置javascript变量,并且可以在任何嵌套 it(..., () => {})语句中使用它们。

例如,我有一组测试,用于检查以不同框架编写的同一应用程序的两个版本。因此,我需要了解要测试的框架,并加载不同的灯具。

为此,我使用以下内容

const framework = Cypress.env('FRAMEWORK')
let config;

before(function() {
  cy.fixture('frameworks').then(fixture => {
    config = fixture[framework]
  })
})

然后我可以在测试中使用config

cy.visit(config.pageUrl)

it('should have a title', () => {
  cy.title().should('contain', config.title)
});

您可以在测试套件的许多地方使用before(),通常在describe()context()之后,并且其中定义的变量都可以以“普通” javascript方式使用。

答案 2 :(得分:0)

这是一种稍微复杂一些(并且未经过全面测试)的方法。可以添加自定义命令以将值保存到全局对象。

在赛普拉斯测试运行器中,所有测试 似乎 都按顺序运行,但是如果使用CI和并行执行,则可能要小心。

/support/commands.js

export const testStore = {}

Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
  console.log('saveAs', value, propName)
  testStore[propName] = value;
  return value; 
})

myTest.spec.js

import { testStore } from '../support/commands.js'
...

it('should have a title', () => {
  cy.title()
    .saveAs('title')             // save for next test
    .should('contain', 'myTitle) // this test's expectation
});

it('should test something else', () => {
  cy.get('.myElement').contains(testStore.title);
});