JS 端到端测试 (E2E):Cypress / Playwright 自动化浏览器测试

大家好,我是你们今天的自动化测试小助手。今天咱们来聊聊前端E2E测试那些事儿,特别是Cypress和Playwright这两位当红炸子鸡。放心,咱们不搞学术报告,争取把这事儿聊得像唠嗑一样轻松愉快。

开场白:E2E测试是啥玩意儿?为啥要搞它?

想象一下,你辛辛苦苦写了一堆代码,信心满满地部署上线。结果用户一用,哎呦喂,页面崩了,功能失效了,简直就是一场灾难片!

E2E测试,全称End-to-End testing,端到端测试,就是为了避免这种灾难而生的。它模拟真实用户的使用场景,从头到尾地测试你的应用,确保所有的组件、模块、服务都能协同工作,最终用户体验流畅丝滑。

简单来说,E2E测试就像是你的应用的“全面体检”,帮你找出潜在的bug,提升代码质量,让你更有底气面对用户的挑战。

Cypress vs Playwright:两位大哥的巅峰对决

Cypress和Playwright都是非常优秀的E2E测试框架,它们各有千秋,就像武林高手一样,都有自己的独门绝技。

特性 Cypress Playwright
架构 运行在浏览器内部,使用Node.js作为控制台 独立进程,通过DevTools协议与浏览器通信
编程语言 JavaScript JavaScript, TypeScript, Python, Java, .NET
浏览器支持 Chrome, Edge, Firefox, Electron (有限支持) Chrome, Edge, Firefox, Safari, WebKit
跨域处理 内置代理,方便处理跨域问题 自动处理跨域问题,无需特殊配置
调试 强大的调试工具,时间旅行功能 强大的调试工具,支持浏览器开发者工具
性能 速度较快,但并发能力有限 并发能力强,可并行执行多个测试
社区支持 活跃,文档完善 活跃,文档完善
上手难度 简单易上手 稍复杂,但功能更强大

Cypress:小巧灵活的JS战士

Cypress就像一位身手敏捷的JS战士,它精通JavaScript,能够轻松驾驭各种前端场景。

  • 安装Cypress

    首先,我们需要安装Cypress。打开你的终端,输入以下命令:

    npm install cypress --save-dev
    # 或者
    yarn add cypress --dev
  • 运行Cypress

    安装完成后,运行Cypress:

    npx cypress open
    # 或者
    yarn cypress open

    Cypress会打开一个图形界面,你可以选择要运行的测试文件。

  • 编写第一个Cypress测试

    创建一个名为cypress/integration/example.spec.js的文件,写入以下代码:

    describe('My First Test', () => {
      it('Visits the Kitchen Sink', () => {
        cy.visit('https://example.cypress.io')
    
        cy.contains('type').click()
    
        // Should be on a new URL which includes '/commands/actions'
        cy.url().should('include', '/commands/actions')
    
        // Get an input, type into it and verify that the value has been updated
        cy.get('.action-email')
          .type('[email protected]')
          .should('have.value', '[email protected]')
      })
    })

    这段代码做了什么呢?

    1. describe:定义一个测试套件,相当于一个测试用例集。
    2. it:定义一个测试用例,相当于一个具体的测试步骤。
    3. cy.visit:访问指定的URL。
    4. cy.contains:查找包含指定文本的元素,并点击它。
    5. cy.url:获取当前URL,并进行断言。
    6. cy.get:获取指定的DOM元素。
    7. cy.type:在输入框中输入文本。
    8. cy.should:进行断言,判断元素是否符合预期。
  • Cypress的优势

    • 时间旅行:Cypress可以记录每个测试步骤的状态,你可以像时光倒流一样,回到任何一个步骤,查看当时的DOM结构、网络请求等信息,方便调试。
    • 自动等待:Cypress会自动等待元素加载完成,避免了手动添加等待时间的麻烦。
    • 内置代理:Cypress内置代理,可以方便地处理跨域问题。
    • 易于上手:Cypress的API设计简洁明了,易于学习和使用。
  • Cypress的局限性

    • 浏览器支持有限:Cypress主要支持Chrome、Edge、Firefox,对Safari的支持有限。
    • 并发能力有限:Cypress的并发能力相对较弱,不适合大规模的并行测试。
    • 只能使用JavaScript:Cypress只能使用JavaScript编写测试代码,对于习惯使用其他语言的开发者来说,可能需要学习新的语法。

Playwright:全能型的跨平台选手

Playwright就像一位全能型的跨平台选手,它精通多种编程语言,能够驾驭各种浏览器和操作系统。

  • 安装Playwright

    打开你的终端,输入以下命令:

    npm install -D @playwright/test
    # 或者
    yarn add -D @playwright/test
  • 安装浏览器

    Playwright需要安装浏览器才能运行测试。你可以使用以下命令安装所有支持的浏览器:

    npx playwright install
    # 或者
    yarn playwright install

    也可以选择安装特定的浏览器:

    npx playwright install chromium
    npx playwright install firefox
    npx playwright install webkit
    # 或者
    yarn playwright install chromium
    yarn playwright install firefox
    yarn playwright install webkit
  • 编写第一个Playwright测试

    创建一个名为tests/example.spec.ts的文件,写入以下代码:

    import { test, expect } from '@playwright/test';
    
    test('has title', async ({ page }) => {
      await page.goto('https://playwright.dev/');
    
      // Expect a title "to contain" a substring.
      await expect(page).toHaveTitle(/Playwright/);
    });
    
    test('get started link', async ({ page }) => {
      await page.goto('https://playwright.dev/');
    
      // Click the get started link.
      await page.getByRole('link', { name: 'Get started' }).click();
    
      // Expects the URL to contain intro.
      await expect(page).toHaveURL(/.*intro/);
    });

    这段代码做了什么呢?

    1. import { test, expect } from '@playwright/test':导入Playwright的测试API。
    2. test:定义一个测试用例。
    3. page:Playwright提供的页面对象,用于与浏览器进行交互。
    4. await page.goto:访问指定的URL。
    5. await expect(page).toHaveTitle:断言页面的标题是否包含指定的文本。
    6. await page.getByRole:根据ARIA role查找元素,并点击它。
    7. await expect(page).toHaveURL:断言页面的URL是否包含指定的文本。
  • 运行Playwright测试

    运行Playwright测试:

    npx playwright test
    # 或者
    yarn playwright test

    Playwright会自动运行所有测试文件,并输出测试结果。

  • Playwright的优势

    • 跨浏览器支持:Playwright支持Chrome、Edge、Firefox、Safari、WebKit等多种浏览器。
    • 跨平台支持:Playwright可以在Windows、macOS、Linux等操作系统上运行。
    • 多语言支持:Playwright支持JavaScript, TypeScript, Python, Java, .NET等多种编程语言。
    • 并发能力强:Playwright的并发能力非常强,可以并行执行多个测试,提高测试效率。
    • 自动等待:Playwright会自动等待元素加载完成,避免了手动添加等待时间的麻烦。
    • 强大的调试工具:Playwright提供了强大的调试工具,可以方便地查看DOM结构、网络请求等信息。
  • Playwright的局限性

    • 上手难度稍高:Playwright的API相对复杂,需要一定的学习成本。
    • 需要安装浏览器:Playwright需要安装浏览器才能运行测试,可能会占用一定的磁盘空间。

代码示例:登录功能的E2E测试

假设我们有一个简单的登录页面,包含用户名输入框、密码输入框和登录按钮。我们来用Cypress和Playwright分别编写E2E测试用例。

  • Cypress版本

    describe('Login Functionality', () => {
      it('should successfully login with valid credentials', () => {
        cy.visit('/login'); // 假设登录页面URL为/login
        cy.get('#username').type('validUser'); // 假设用户名输入框的ID为username
        cy.get('#password').type('validPassword'); // 假设密码输入框的ID为password
        cy.get('#login-button').click(); // 假设登录按钮的ID为login-button
        cy.url().should('include', '/dashboard'); // 假设登录成功后跳转到/dashboard页面
        cy.contains('Welcome, validUser').should('be.visible'); // 假设登录成功后显示欢迎信息
      });
    
      it('should display error message with invalid credentials', () => {
        cy.visit('/login');
        cy.get('#username').type('invalidUser');
        cy.get('#password').type('invalidPassword');
        cy.get('#login-button').click();
        cy.contains('Invalid username or password').should('be.visible'); // 假设登录失败后显示错误信息
      });
    });
  • Playwright版本

    import { test, expect } from '@playwright/test';
    
    test('should successfully login with valid credentials', async ({ page }) => {
      await page.goto('/login'); // 假设登录页面URL为/login
      await page.locator('#username').fill('validUser'); // 假设用户名输入框的ID为username
      await page.locator('#password').fill('validPassword'); // 假设密码输入框的ID为password
      await page.locator('#login-button').click(); // 假设登录按钮的ID为login-button
      await expect(page).toHaveURL(/.*dashboard/); // 假设登录成功后跳转到/dashboard页面
      await expect(page.locator('text=Welcome, validUser')).toBeVisible(); // 假设登录成功后显示欢迎信息
    });
    
    test('should display error message with invalid credentials', async ({ page }) => {
      await page.goto('/login');
      await page.locator('#username').fill('invalidUser');
      await page.locator('#password').fill('invalidPassword');
      await page.locator('#login-button').click();
      await expect(page.locator('text=Invalid username or password')).toBeVisible(); // 假设登录失败后显示错误信息
    });

如何选择?看你的需求!

Cypress和Playwright都是优秀的E2E测试框架,选择哪个取决于你的具体需求。

  • 如果你的项目主要使用JavaScript,对浏览器的支持要求不高,并且追求简单易上手,那么Cypress可能更适合你。
  • 如果你的项目需要支持多种浏览器和操作系统,并且需要更高的并发能力,那么Playwright可能更适合你。
  • 如果你的团队已经熟悉了TypeScript、Python、Java或.NET,那么Playwright的多语言支持可以让你更快地上手。

最佳实践:让你的E2E测试更有效

  • 编写可维护的测试用例:使用清晰的命名,避免重复代码,将公共逻辑提取成函数。
  • 使用数据驱动测试:使用不同的数据来测试相同的场景,提高测试覆盖率。
  • 模拟真实用户行为:尽量模拟真实用户的操作,例如使用键盘输入、鼠标点击等。
  • 集成到CI/CD流程:将E2E测试集成到CI/CD流程中,自动化执行测试,及时发现问题。
  • 不要过度测试:E2E测试的成本较高,不要过度测试,重点关注核心功能和关键流程。
  • 利用Page Object Model(POM):POM是一种设计模式,将页面元素和操作封装成对象,提高代码的可维护性和可重用性。

总结:E2E测试是质量的保障

E2E测试是保证前端应用质量的重要手段。Cypress和Playwright都是非常优秀的E2E测试框架,可以帮助你更好地进行自动化测试。希望今天的讲解能够帮助你更好地理解E2E测试,并选择适合你的测试框架。

记住,代码质量就像你的脸面,一定要好好维护!E2E测试就是你的“美容院”,帮你保持代码的“容光焕发”。 好了,今天的讲座就到这里,大家有什么问题可以随时提问。下次有机会再和大家分享更多有趣的技术知识! 拜拜!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注