Cypress 系列之----03自定义命令Custom Commands

Posted liuyitan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cypress 系列之----03自定义命令Custom Commands相关的知识,希望对你有一定的参考价值。

// ***********************************************
//本篇主要针对创建各种自定义命令,重写命令,官方参考资料:https://on.cypress.io/custom-commands
//
// ***********************************************
// -- This is a parent command --父命令,用cy可以直接调用
// Cypress.Commands.add(‘login‘, (email, password) => { ... })
//
// -- This is a child command --子命令,可以理解为对cy获取到元素的操作命令,常用的click命令,属于这类
// Cypress.Commands.add(‘drag‘, { prevSubject: ‘element‘}, (subject, options) => { ... })
//
// -- This is a dual command --基本上是父命令和子命令的混合
// Cypress.Commands.add(‘dismiss‘, { prevSubject: ‘optional‘}, (subject, options) => { ... })
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite(‘visit‘, (originalFn, url, options) => { ... })

语法

Cypress.Commands.add(name, callbackFn)
Cypress.Commands.add(name, options, callbackFn)
Cypress.Commands.overwrite(name, callbackFn)

参数

 name (String)

The name of the command you’re either adding or overwriting.

 callbackFn (Function)

Pass a function that receives the arguments passed to the command.

 options (Object)

Pass in an options object to define the implicit behavior of the custom command.

options is only supported for use in Cypress.Commands.add() and not supported for use in Cypress.Commands.overwrite()

OptionAcceptsDefaultDescription
prevSubject BooleanString or Array false how to handle the previously yielded subject.

The prevSubject accepts the following values:

  • false: ignore any previous subjects: (parent command)
  • true: receives the previous subject: (child command)
  • optional: may start a chain, or use an existing chain: (dual command)

In additional to controlling the command’s implicit behavior you can also add declarative subject validations such as:

  • element: requires the previous subject be a DOM element
  • document: requires the previous subject be the document
  • window: requires the previous subject be the window

Internally our built in commands make use of every single one of these combinations above.

 

 最佳实践

1. 不要滥用

Custom commands work well when you’re needing to describe behavior that’s desirable across all of your tests. Examples would be a cy.setup() or cy.login() or extending your application’s behavior like cy.get(‘.dropdown‘).dropdown(‘Apples‘). These are specific to your application and can be used everywhere.

However, this pattern can be used and abused. Let’s not forget - writing Cypress tests is javascript, and it’s often more efficient to write a function for repeatable behavior that’s specific to only a single spec file.

If you’re working on a search_spec.js file and want to compose several repeatable actions together, you should first ask yourself:

2. 简单事情不要复杂化

Every custom command you write is generally an abstraction over a series of internal commands. That means you and your team members exert much more mental effort to understand what your custom command does.

There’s no reason to add this level of complexity when you’re only wrapping a couple commands.

 

This first custom command is wrapping cy.get(selector).click(). Going down this route would lead to creating dozens or even hundreds of custom commands to cover every possible combination of element interactions. It’s completely unnecessary.

The .shouldBeVisible() custom command isn’t worth the trouble or abstraction when you can already use: .should(‘be.visible‘)

Testing in Cypress is all about readability and simplicity. You don’t have to do that much actual programming to get a lot done. You also don’t need to worry about keeping your code as DRY as possible. Test code serves a different purpose than app code. Understandability and debuggability should be prioritized above all else.

Try not to overcomplicate things and create too many abstractions. When in doubt, use a regular function for individual spec files.

3. 一个命令不要做太多事 

Make your custom commands composable and as unopinionated as possible. Cramming too much into them makes them inflexible and requires more and more options passing to control their behavior.

Try to add either zero or as few assertions as possible in your custom command. Those tend to shape your command into a much more rigid structure. Sometimes this is unavoidable, but a best practice is to let the calling code choose when and how to use assertions.

4. 尽量跳过UI层命令

5. Write TypeScript definitions

You can describe the method signature for your custom command, allowing IntelliSense to show helpful documentation. See the cypress-example-todomvc repository for a working example.

以上是关于Cypress 系列之----03自定义命令Custom Commands的主要内容,如果未能解决你的问题,请参考以下文章

Cypress系列(20)- 可操作类型的命令 之 clear()

Cypress系列(22)- 可操作类型的命令 之 select()

Cypress系列(19)- 可操作类型的命令 之 type()

Cypress系列(21)- 可操作类型的命令 之 check()uncheck()

Cypress 在自定义命令中加载环境变量

如何在 cypress typescript 项目中正确导入自定义命令?