使用 cypress 测试 vuex

Nea*_*kit 4 vue.js vuex cypress

I\xe2\x80\x99m 在我的 Vue.js 项目 (Nuxt.js) 中使用 Cypress。我能\xe2\x80\x99t管理的主要问题是如何理解vuex存储已经准备好。让\xe2\x80\x99s 说我有一个按钮可以调用axios 来获取一些数据。然后数据通过突变进入存储,Vue 将在模板中渲染它。在商店建成之前,我想要与之交互的下一个元素是空的。但柏树正在试图检查它。

\n\n

商店建立后如何调用下一个 cypress 操作(如 cy.get)?

\n\n

我的项目比较复杂。但核心问题是,cypress 有时不\xe2\x80\x99t 等待商店构建并尝试进一步工作。我们第一次使用cy.wait(1000),但似乎不是那么完美的决定。

\n\n
<div>\n    <button data-cy="fetchDataBtn" @click="fetchData">get items</button>\n    <ul>\n        <li v-for="item in items">\n           <p>{{ item.title }}</p>\n           <button\n                @click="fetchProduct(item.id)"\n            >\n                buy {{ item.name }}\n            </button>\n        </li>\n    </ul>\n</div> \n\n    <script>\n    import { mapState } from \'vuex\';\n    export default {\n        name: \'App\',\n        computed: {\n            ...mapState(\'list\', [\'items\'])\n        }\n    } \n    </script>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我期望出现以下场景:

\n\n
cy.get([\xe2\x80\x98data-cy=fetchDataBtn\xe2\x80\x99]).click()\n// wait for store is ready and list is already rendered \n// (NOT cy.wait(\'GET\', \'url_string\') or cy.wait(milliseconds))\ncy.contains(\xe2\x80\x98button\xe2\x80\x99, \'buyItemName\').click()\n
Run Code Online (Sandbox Code Playgroud)\n

Ric*_*sen 6

看一下这篇文章Testing ... with Vuex Store ...,关键是在window中添加对Vue应用程序的引用,

const app = new Vue({
  store,
  el: '.todoapp'
  //
})
if (window.Cypress) {
  // only available during E2E tests
  window.app = app
}
Run Code Online (Sandbox Code Playgroud)

然后在继续测试 DOM 之前测试存储中是否有适当的键

const app = new Vue({
  store,
  el: '.todoapp'
  //
})
if (window.Cypress) {
  // only available during E2E tests
  window.app = app
}
Run Code Online (Sandbox Code Playgroud)

然而,它还可以比这更简单!

你说

在商店建成之前,我想要与之交互的下一个元素是空的。

通过正确的命令组合,Cypress 将等待通过 axios 获取的内容,只要您选择正确的“指示器”元素并测试其内容,例如

const getStore = () => cy.window().its('app.$store')

it('has loading, newTodo and todos properties', () => {
  getStore().its('state').should('have.keys', ['loading', 'newTodo', 'todos'])
})
Run Code Online (Sandbox Code Playgroud)

这将等待最多 10 秒以显示获取的内容(如果较早出现,则等待时间更短)。如果没有超时参数,它最多等待 5 秒,这已经足够了。

注意,Cypress 链式命令存在一个微妙的陷阱。

不要使用

cy.contains('my.next.element.i.want.to.interact.with', 'the.content.fetched.with.axios', { timeout: 10000 })
Run Code Online (Sandbox Code Playgroud)

因为你的 Vue 模板可能从一开始就具有元素标签或类,但它的内容最初是空的,并且此模式不会等待你想要看到的内容。它只会比较初始内容(无内容),而不等待提取完成。