【问题标题】:How do I access React component's local state using Cypress?如何使用 Cypress 访问 React 组件的本地状态?
【发布时间】:2019-08-16 09:11:09
【问题描述】:

我正在使用 react with redux 并使用 cypress 进行测试, 我能够使用访问商店 cy.window().its('store').invoke('getState').then((state) => {} 但是如何访问组件的本地状态而不是应用商店?

我试过了

cy.get('.simple-component').its('getState')

cy.get('.simple-component').invoke('getState')

但赛普拉斯正在返回“CypressError: Timed out retrying: cy.invoke() errored because the property: 'getState' does not exist on your subject” 在赛普拉斯控制台(在 chrome 中)它正在屈服:

Yielded:   
<div class="simple-component" getstate="[object Object]"></div>

这似乎是由于 React 从 DOM 中删除了方法,所以我需要在 React 而不是 DOM 中访问它?

import React, { Component } from 'react';

class simpleComponent extends Component {
    constructor(props) {
        super(props)
        this.state = {
            sample: "hello"
            }
    }
    // getState() just for testing on cypress
    getState() {
      return this.state
    }
    render(){
      return <div className="simple-component" getState={this.getState()}></div>
    }    
}

作为替代方案,我可以使用 window.store 在简单组件末尾导出本地组件状态吗?

【问题讨论】:

  • 使用像 Cypress 这样的端到端测试工具,您实际上不会与 React API 或直接与组件的内部交互,例如执行 setState()。相反,您正在验证/测试用户将看到和体验的内容。您尝试做的更多是使用 Jest/Enzyme 等工具进行单元测试。通过单元测试,您可以调用组件的内部操作,例如事件处理程序,并在各种事件或 API 调用之前/之后验证 Redux 存储数据。赛普拉斯真的不适合这种类型的测试。
  • 此外,您的组件 getState 属性在每次渲染时执行 this.getState() ,而不是绑定要传递给子组件或响应点击等事件的类函数。就您的 React 应用程序而言,该 prop 和 class 方法的意图是什么?您将无法真正将状态暴露给窗口或供外部使用。
  • 好点,它不在原始代码中,但我添加它以便在 cypress 控制台上看到它,以消除 Cypress 在
    否则你的第一点回答了我的问题,认为能够使用 Cypress 访问类似于 redux 存储的本地状态会很好
  • 这个正是你所要求的。 stackoverflow.com/a/39165137

标签: reactjs redux state invoke cypress


【解决方案1】:

>= 版本 7.0.0

从 Cypress 7.0 开始,新的 Component Test Runner 现在与 Cypress 捆绑在一起

来自https://www.cypress.io/blog/2021/04/06/cypress-component-testing-react:

我们仍然需要安装 react 适配器来挂载组件:

yarn add -D cypress @cypress/react @cypress/webpack-dev-server

将与您的组件测试匹配的全局模式添加到cypress.json

{
  "component": {
    "testFiles": "**/*.test.{js,ts,jsx,tsx}",
    "componentFolder": "src"
  }
}

告诉赛普拉斯使用 @cypress/webpack-dev-server 进行组件测试。在cypress/plugins/index.js:

const injectDevServer = require("@cypress/react/plugins/react-scripts")

module.exports = (on, config) => {
  injectDevServer(on, config)
  return config
}

这会将 Cypress Webpack Dev Server 配置为使用与 Create React App 使用的相同的 Webpack 配置。

如果您使用的是不同的模板,例如 Next.js,我们还有其他一些可用的适配器。也可以创建自己的适配器。

有一个赛普拉斯插件,称为react-unit-test。它使您能够直接挂载React 组件(添加cy.mount() 命令)并提供对组件内部状态的访问。

这是回购自述文件中的一个示例:

// load Cypress TypeScript definitions for IntelliSense
/// <reference types="cypress" />
// import the component you want to test
import { HelloState } from '../../src/hello-x.jsx'
import React from 'react'
describe('HelloState component', () => {
  it('works', () => {
    // mount the component under test
    cy.mount(<HelloState />)
    // start testing!
    cy.contains('Hello Spider-man!')
    // mounted component can be selected via its name, function, or JSX
    // e.g. '@HelloState', HelloState, or <HelloState />
    cy.get(HelloState)
      .invoke('setState', { name: 'React' })
    cy.get(HelloState)
      .its('state')
      .should('deep.equal', { name: 'React' })
    // check if GUI has rerendered
    cy.contains('Hello React!')
  })
})

【讨论】:

  • 这在最新版本的赛普拉斯(v8 之后)中已过时。您将需要使用 Cypress 组件测试内容以及 npmjs.com/package/cypress-react-selector
  • @FrancisUptonIV 谢谢,我更新了答案
  • 哇,速度超级快。谢谢!
【解决方案2】:

您可以在不安装 react 组件的情况下识别元素。如果您正在与源代码隔离测试您的 React 应用程序或编写功能性 UI 测试用例,您可以考虑使用名为 cypress-react-selector 的赛普拉斯插件。即使在缩小之后,它也可以帮助您按组件、道具和状态识别 Web 元素。在这种情况下,您需要使用 React Dev Tool 来识别组件名称。

这是一个例子:

假设你的 react 应用:

const MyComponent = ({ someBooleanProp }) => (
  <div>My Component {someBooleanProp ? 'show this' : ''} </div>
)
 
const App = () => (
  <div id='root'>
    <MyComponent />
    <MyComponent name={bob} />
  </div>
)
 
ReactDOM.render(<App />, document.getElementById('root'))

然后您可以简单地识别反应元素,如:

cy.getReact('MyComponent', { name: 'bob' } ).getCurrentState();

查找更多样例测试here

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2020-06-12
    • 2017-12-26
    • 2022-07-12
    • 2018-02-24
    • 2019-11-03
    • 2020-08-14
    • 2018-09-25
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多