Cypress web自动化32-完全测试登录流程 - 但只有一次!

前言

这篇是根据 cypress 官方文档 copy 过来的,关于自动化测试对登录场景的处理的思考,写的挺好的。
官方文档地址https://docs.cypress.io/guides/getting-started/testing-your-app.html#Logging-in
登录是我们遇到的第一个自动化用例场景,当然登录也是最难的场景之一。

完全测试登录流程 - 但只有一次

将注册和登录流程置于测试覆盖范围内是一个好主意,因为它对用户来说都非常重要,而且你永远不希望它有缺陷。
登录是任务关键的功能之一,可能涉及你的服务器。 我们建议你使用你的 UI 页面测试注册和登录,因为我们尽量模拟真实用户场景!

以下是从数据库构造数据开始的示例:

  • cy.exec() npm 执行脚本清理测试数据
  • cy.request() 往数据库写入你的测试账号,后面的用例使用该测试账号username: 'jane.lane'
describe('The Login Page', function () {
  beforeEach(function () {
    // 每次测试之前重置数据库,保证测试数据干净
    cy.exec('npm run db:reset && npm run db:seed')

    // 发个post请求 '/test/seed/user'注册用户, 往数据库写入测试用户数据
    // 假设它为我们生成一个随机密码
    cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
      .its('body')
      .as('currentUser')
  })

  it('sets auth cookie when logging in via form submission', function () {
    // 引用上面的currentUser对象
    const { username, password } = this.currentUser

    cy.visit('/login')

    cy.get('input[name=username]').type(username)

    // 输入密码后,按 {enter} 提交数据
    cy.get('input[name=password]').type(`${password}{enter}`)

    // 重定向到 /dashboard
    cy.url().should('include', '/dashboard')

    // 断言用户登录后cookie存在
    cy.getCookie('your-session-cookie').should('exist')

    // 断言UI页面是包含 'jane.lane' 文本
    cy.get('h1').should('contain', 'jane.lane')
  })
})

你可能还会继续测试你的登录界面的以下情况,比如:

非法的用户名/密码
用户名已存在
密码复杂度要求
边缘用例,比如用户锁定或已删除
以上每一种情况都要求进行全面的测试。

现在,当你的登录测试成功之后,你可能开始想:

“…好的,漂亮! 让我们在每一个测试用例中重复这些登录过程吧!”

不! 千万别!不要用UI登录来测试每一个用例。

让我们来研究和展开一下原因。

绕过UI

当你为非常具体的功能编写测试时,你应使用你的UI进行测试。

但是,当你在测试系统的另一个模块时,而它依赖于之前功能的状态时:不要使用你的UI设置此状态。

这是一个更具说服力的例子:

想象一下,你正在测试购物车的功能。 要对此进行测试,你需要能够将商品添加到该购物车。
那么商品来自哪里? 你是否应该使用UI登录管理区域,然后创建所有商品,包括其描述,类别和图像?
完成后,你是否应该访问每个商品并将每个商品添加到购物车?

不,你不应该这样做。

警告 不要用你的UI去构建状态。这是非常缓慢,繁琐和不必要的。

登录与我们刚才描述的完全相同的场景。 登录只是在所有其他测试之前的前置状态条件。

因为Cypress不是Selenium,我们实际上可以在这里采取一个巨大的捷径,不需要使用UI而直接使用cy.request()。

因为cy.request()会自动获取并设置cookie,我们实际上可以使用它来构建状态而不使用浏览器的UI,但仍然可以使其完全像它来自浏览器一样!

让我们重温上面的例子,但假设我们正在测试系统的其他部分。

describe('The Dashboard Page', function () {
  beforeEach(function () {
    // 每次测试之前重置数据库,保证测试数据干净
    cy.exec('npm run db:reset && npm run db:seed')

    // 发个post请求 '/test/seed/user'注册用户, 往数据库写入测试用户数据
    // 假设它为我们生成一个随机密码
    cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
      .its('body')
      .as('currentUser')
  })

  it('logs in programmatically without using the UI', function () {
    // 引用上面的currentUser对象
    const { username, password } = this.currentUser

    // 通过登陆接口发request请求,不需要用UI界面去登陆
    cy.request('POST', '/login', {
      username,
      password
    })

    // 现在已经是登陆状态了,可以用visit访问登陆后的任意页面了
    cy.visit('/dashboard')

    // 断言用户登录后cookie存在
    cy.getCookie('your-session-cookie').should('exist')

    // 断言UI页面是包含 'jane.lane' 文本
    cy.get('h1').should('contain', 'jane.lane')
  })
})

你看得到差别吗? 我们能够登录而无需实际使用我们的UI。 这节省了大量时间访问登录页面,填写用户名,密码,并等待服务器在每次测试之前(登录后)重定向。

因为我们以前在不使用任何捷径方式的情况下端到端地测试了登录系统,所以我们已经100%有信心它正常工作。

在处理系统的其他地方,那些需要设置状态的任何模块时,请使用上述方法。 请记住 - 不要使用你的用户界面!

接下来我们会想后面的用例都需要把登录当成前置,这时候需自定义一个登陆指令在support/commands.js 下定义一个命令用于发登录请求
详情参考前面这篇https://www.cnblogs.com/yoyoketang/p/13045333.html

官方文档地址https://docs.cypress.io/guides/getting-started/testing-your-app.html#Logging-in

posted @ 2020-06-05 16:04  上海-悠悠  阅读(2398)  评论(1编辑  收藏  举报