Cypress的那些独特的地方

367 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

大家好,我是阿萨。12月是学习的好时机。大家一起加油。好好学习,天天向上。Cypress的基本用法基本都讲解完了。这一期,总结下Cypress 比其他 Web UI 自动化更好的地方。

一,闭包(Closure)

Cypress 中, 保存一个值或者引用对的最好方式是使用闭包。其中then 就是Cypress的典型应用。

先介绍一个场景: 有个button, 在点击了提交按钮后,这个button的文本会 变化。 然后我们写一个用例来比较下 form 提交后,button 会变化的场景。

代码如下:

 it('test then', function() {
 cy.get('btn').then(($btn)=>{const txt=$btn.text()
            cy.get('form').submit()
                cy.get('btn').should(($btn2)=>{          
                expect($btn2.text()).not.to.eq(txt) 
            }) 
            })
    })

二, 变量和别名。

Cypress 可以使用wrap 或者as 变量去给元素赋值或者实现变量共享。

  1.  wrap

我们先看wrap 的典型使用场景。

通过wrap 传递变量。

const getName =()=>{return 'Sarah'        }
cy.wrap({name:getName}).invoke('name').should('eq','Sarah')

来看看wrap的语法:

cy.wrap(subject)cy.wrap(subject, options)

常见用法,除了上面的例子,还有如下2种;

cy.get('form').within(($form) => {// ... more commands
  cy.wrap($form).should('have.class', 'form-container')})
cy.get('button').then(($button) => {// $button is a wrapped jQuery elementif ($button.someMethod() === 'something') {// wrap this element so we can// use cypress commands on it    cy.wrap($button).click()  } else {// do something else  }})
// import application code for logging inimport { userService } from '../../src/_services/user.service'
it('can assert against resolved object using .should', () => {  cy.log('user service login')const username = Cypress.env('username')const password = Cypress.env('password')
// wrap the promise returned by the application code  cy.wrap(userService.login(username, password))// check the yielded object    .should('be.an', 'object')    .and('have.keys', ['firstName', 'lastName', 'username', 'id', 'token'])    .and('contain', {      username: 'test',      firstName: 'Test',      lastName: 'User',    })
// cy.visit command will wait for the promise returned from// the "userService.login" to resolve. Then local storage item is set// and the visit will immediately be authenticated and logged in  cy.visit('/')// we should be logged in  cy.contains('Hi Test!').should('be.visible')})
  1. as 

as 是用来分配别名供以后使用。

语法:

.as(aliasName)

常见用法:

cy.get('.main-nav').find('li').first().as('firstNav') // Alias element as @firstNavcy.intercept('PUT', '/users').as('putUser') // Alias route as @putUsercy.stub(api, 'onUnauth').as('unauth') // Alias stub as @unauthcy.spy(win, 'fetch').as('winFetch') // Alias spy as @winFetch

给元素加个别名

it('disables on click', () => { 
cy.get('button[type=submit]').as('submitBtn')  
cy.get('@submitBtn').click().should('be.disabled')})

对用cy.intercept()定义的被拦截路由进行别名,然后使用cy.wait()等待别名路由。

cy.intercept('PUT', '/users', { fixture: 'user' }).as('editUser')

// we'll assume submitting `form` triggers a matching request

cy.get('form').submit()

// once a response comes back from the `editUser`// this `wait` will resolve with the subject containing `url`

cy.wait('@editUser').its('url').should('contain', 'users')

说白了, 这2个传递变量的方式就是为了规避Cypress的异步执行的坑。

明天讲解Cypress的那些坑。

今天就到这了。