前端实现端到端测试(代码版)

news2024/12/22 18:57:41

端到端测试框架选取

  • playwright 、 cypress 、 selenium 对比

cypress使用

  • 下载 cypress
    • npm install cypress --save-dev
  • package.json
    • npm run cypress:open
    {
      "scripts": {
        "cypress:open": "cypress open"
      }
    }
    

使用流程

  • 入门官方文档
  1. npm run cypress:open

  2. 左侧端测试,右侧组件测试,点击左侧在这里插入图片描述

  3. 选择你需要的浏览器,点击开始在这里插入图片描述

  4. 自动打开浏览器,点击左侧specs(测试文件菜单),点击内容区域.cy.ts文件
    在这里插入图片描述

  5. 左侧是测试执行栏,会有每个指令的详细信息以及成功失败,箭头可以点开看详细信息. 右侧是内容显示栏会有页面显示在这里插入图片描述

code

  • 每次it测试,触发窗口大小变化,然后登录,第一次会正常执行,然后保存登录状态,cy.session再次触发,如果登录过,会直接跳过
  • 指令解析
    • cy.visit 访问地址
    • cy.origin 如果登录地址会先跳到一个login登录链接,登录完成再次回到业务链接时,域变化,需要加origin指令
    • cy.get 得到dom元素, id class都支持
      • dom元素后可以 click 点击 , type 填充内容, each 循环dom列表, first 第一个儿子等.
  • cypress/support/commands.ts
    • // Cypress.Commands.add(‘login’, (email, password) => { … })
      • 登录方法可以封装成全局方法
  • cypress/e2e/home-cypress.cy.ts
    describe('template spec', () => {
      beforeEach(() => {
        cy.viewport(2000, 1000);
        cy.session('mySession', () => {
          cy.visit('https://xxxx');
          cy.get('#account').type('xxxx');
          cy.get('#password').type('xxxx');
          cy.get('.btn-login').click();
        });
      });
      it('login done', () => {
        cy.origin('https://xxxx', () => {
          cy.visit('https://xxxx/xxx');
          cy.on('uncaught:exception', (e) => {
            // 控制台报错会让测试停止,需要添加这段
            return false;
          });
          // cy.wait(500)  等待时间 , 直接写wait或者 get第二个参数填写timeout
          cy.get('.ls-workstation-sidebar-avatar-name', { timeout: 30 * 1000 }).should('contain', '刘胜');
          cy.get('.ant-pro-form-collapse-button', { timeout: 30 * 1000 }).each(($el, index, $list) => {
            // $el is a wrapped jQuery element
            cy.wrap($el).click();
          });
          cy.get('#contractNo', { timeout: 30 * 1000 }).type('PH0038417');
          const btnEles = cy
            .get('button.ant-btn-primary', { timeout: 30 * 1000 })
            .first()
            .click();
        });
      });
    });
    

selenium使用

  • npm install selenium-webdriver
  • npm install chromedriver --save
  • npm下载以外还可以手动下载浏览器

使用流程

  • 官方入门指南
  • 写js文件, 用node执行此文件
  • 会自动打开谷歌,然后自动执行代码

code

  • 指令解析
    • driver.get 导航到url
    • driver.findElement(By.css()) dom元素, by.css里可以是id class
      • sendKeys 填充内容, click点击, getText 得到文本内容
    • driver.findElements dom元素列表
  • tests/home-selenium.js
    const {By, Builder, until} = require('selenium-webdriver');
    const assert = require("assert");
    
    const driver = new Builder().forBrowser('chrome').build();
    
    (async function () {
    
            // 导航到某个网站
            await driver.get('https://xxx/xxx');
            driver.findElement(By.css('#account')).sendKeys('ddd');
            driver.findElement(By.css('#password')).sendKeys('aaa');
            await driver.findElement(By.css('.btn-login')).click();
    
            const avatarName = await driver.wait(
              until.elementLocated(By.className('ls-sidebar-avatar-name')),
              30000,
            );// 等待得到这个dom,超时时间30000ms
            const avatarText = await avatarName.getText();
            assert(avatarText === '清羽', 'login done');// 断言
    
            const contractNoEle = await driver.wait(until.elementLocated(By.css('#contractNo')), 30000);
            contractNoEle.sendKeys('PC00398414');
            const collapseEles = await driver.findElements(By.css('.ant-pro-form-collapse-button'));
            for (const ele of collapseEles) {
              ele.click();
            }
    
            const btnEles = await driver.findElements(By.css('button.ant-btn-primary'));
            let index = 0;
            for (const ele of btnEles) {
              if (index == 0) {
                ele.click();
              }
              index++;
            }
        // 关闭浏览器
        // await driver.quit();
    })();
    

playwright

  • 下载
    • tnpm init playwright@latest
  • 官方插件
    • Playwright Test for VSCode 插件

使用流程

  • 官方入门文档
  1. 使用官方插件测试, 选中home.spec.ts点击三角执行,会打开WebDriver(需勾选show browser),然后可以看到自动化测试页面
    - 在这里插入图片描述
    • 不勾选,使用无头浏览器测试,勾选后测试会打开WebDriver

      • 在这里插入图片描述
    • WebDriver

      • 在这里插入图片描述
    1. 指令执行测试
    • 测试文件
    • npx playwright test example.spec.ts
    • 在特定浏览器上运行测试
      • npx playwright test home.spec.ts --project=‘chromium’
        • 测试报告在这里插入图片描述
      • codegen在浏览器中运行并执行操作。Playwright 将为用户交互生成代码。
        • npx playwright codegen home.spec.ts

code

  • 指令解析
    • test.beforeEach 每次子test执行之前会执行一下
    • page.locator(“#account”) 得到dom元素
      • fill 快速填充, click点击, filter 过滤 , first 第一个儿子
    • async await 异步变同步
  • tests/home.spec.ts
    test.describe("workstation login", () => {
      test.beforeEach(async ({ page }) => {
        await page.goto(
          "https://xxxx/xxx"
        );
      });
    
      test("login", async ({ page }) => {
        await page.locator("#account").fill("xxx");
        await page.locator("#password").fill("xxx");
        await page.locator(".btn-login").click();
        const avatarName = await page.locator(
          ".lzd-workstation-sidebar-avatar-name"
        );
        expect(avatarName).toContainText("万物");
    
        await page.locator('div').filter({ hasText: /^Expand$/ }).first().click();
        await page.locator('div').filter({ hasText: /^Expand$/ }).first().click();
    
        await page.locator("#contractNo").first().fill("PC09038414");
        await page.locator("button.ant-btn-primary").first().click();
    
      });
    });
    
  • playwright.config.ts
    • 配置文件
    import { defineConfig, devices } from '@playwright/test';
    
    /**
     * Read environment variables from file.
     * https://github.com/motdotla/dotenv
     */
    // require('dotenv').config();
    
    /**
     * See https://playwright.dev/docs/test-configuration.
     */
    export default defineConfig({
      testDir: './tests', // 测试目录
      expect: {
        /**
         * expect()应等待满足条件的最长时间
         * 例如,在'await expect(locator).toHaveText()'
         */
        timeout: 20 * 1000,
      },
      timeout: 30 * 1000, // 每个测试用例超时
      globalTimeout: 60 * 1000, // 总超时
      fullyParallel: true,
      /* Fail the build on CI if you accidentally left test.only in the source code. */
      forbidOnly: !!process.env.CI,
      /* Retry on CI only */
      retries: process.env.CI ? 2 : 0,
      /* Opt out of parallel tests on CI. */
      workers: process.env.CI ? 1 : undefined,
      /* Reporter to use. See https://playwright.dev/docs/test-reporters */
      // reporter: 'html',
      reporter: [['html', { outputFolder: './playwrightTests', open: 'always' }]], // 测试报告
      /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
      use: {
        /* Base URL to use in actions like `await page.goto('/')`. */
        // baseURL: 'http://127.0.0.1:3000',
    
        /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
        // trace: 'on-first-retry',
        launchOptions: {
          headless: false, // 不是无头模式
        },
        contextOptions: {
          viewport: {
            // 窗口视野大小
            width: 1400,
            height: 900,
          },
        },
      },
      /* Configure projects for major browsers */
      projects: [
        {
          name: 'chromium',
          use: { ...devices['Desktop Chrome'] },
        },
    
        {
          name: 'firefox',
          use: { ...devices['Desktop Firefox'] },
        },
    
        {
          name: 'webkit',
          use: { ...devices['Desktop Safari'] },
        },
    
        /* Test against mobile viewports. */
        // {
        //   name: 'Mobile Chrome',
        //   use: { ...devices['Pixel 5'] },
        // },
        // {
        //   name: 'Mobile Safari',
        //   use: { ...devices['iPhone 12'] },
        // },
    
        /* Test against branded browsers. */
        // {
        //   name: 'Microsoft Edge',
        //   use: { ...devices['Desktop Edge'], channel: 'msedge' },
        // },
        // {
        //   name: 'Google Chrome',
        //   use: { ..devices['Desktop Chrome'], channel: 'chrome' },
        // },
      ],
    
      /* Run your local dev server before starting the tests */
      // webServer: {
      //   command: 'npm run start',
      //   url: 'http://127.0.0.1:3000',
      //   reuseExistingServer: !process.env.CI,
      // },
    });
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一本通 3.4.5 最小生成树

1348:【例4-9】城市公交网建设问题 【题目描述】 有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点&…

SQL Server基础 第四章 select定制查询(select中的各种查询筛选条件)

本章主要介绍 select 语句查询数据的基本用法,其中包括查询指定字段信息、条件查询等。 目录 1、比较运算符、逻辑运算符 (1)查询phone大于500且不是单县的 (2)查询地址为烟台或者单县但是phone要大于666的 &#…

IMX6ull 之 HelloWorld Led点灯

一 GPIO点灯,嵌入式的helloworld 1 何为GPIO? GPIO只是一个CPU内提供的一种功能外设,CPU外部的I/O引脚会被赋予一种功能(GPIO、UART、I2C等);该功能由CPU内外设提供,具体是什么功能由IOMUX…

刷题笔记4-22

目录 1.Java:(a,b)>Math.abs(a-3)-Math.abs(b-3); 2.字符解释 3.C语言二维数组中a[i]表示ai的地址,而a[i]又可以表示为*(ai) 4.二维数组在传参时,必须给定列 5.软件开发:观察者模式 6.建…

shell脚本控制

shell脚本编程系列 处理信号 Linux利用信号与系统中的进程进行通信,通过对脚本进行编程,使其在收到特定信号时执行某些命令,从而控制shell脚本的操作。 Linux信号 shell脚本编程会遇到的最常见的Linux系统信号如下表所示: 在默…

【ros】6.ros激光雷达SLAM(建图定位)

百行业为先 ,万恶懒为首。——梁启超 文章目录 :smirk:1. 激光SLAM:blush:2. 二维激光SLAM:satisfied:3. 三维激光SLAM 😏1. 激光SLAM SLAM(同步定位与地图构建)是一种机器人感知技术,用于在未知环境中同时确定机器人…

java调用webservicer的方法

对于使用 Webservicer的方式,一般采用 Java API调用的方式。Webservicer是一个运行在浏览器中的客户端程序,它可以通过 Webservicer的接口来访问服务器上的服务。 使用 Java调用 Webservicer有两种方式: 下面是一个简单的例子: 2、…

零基础,零成本,部署一个属于你的大模型

前言 看了那么多chatGPT的文章,作为一名不精通算法的开发,也对大模型心痒痒。但想要部署自己的大模型,且不说没有算法相关的经验了,光是大模型占用的算力资源,手头的个人电脑其实也很难独立部署。就算使用算法压缩后的…

数据结构和算法学习记录——小习题-二叉树的遍历二叉搜索树

目录 二叉树的遍历 1-1 1-2 1-3 二叉搜索树 2-1 2-2 2-3 2-4 答案区 二叉树的遍历 1-1 假定只有四个结点A、B、C、D的二叉树,其前序遍历序列为ABCD,则下面哪个序列是不可能的中序遍历序列? .ABCD .ACDB .DCBA .DABC 1-2 对于…

最精简:windows环境安装tensorflow-gpu-2.10.1

Tensorflow 2.10是最后一个在本地windows上支持GPU的版本 1. 通过.whl文件方式安装2.创建anaconda虚拟环境3.安装对应的cuda与cudnn版本,local不必装cuda和cudnn4. 测试tensorflow gpu是否可用 1. 通过.whl文件方式安装 .whl文件的下载地址: tensorflow…

windows下使用vite创建vue项目

windows下使用vite创建vue项目 1 下载安装配置NodeJS1.1 下载1.2 安装1.3 配置1.4 npm镜像加速配置1.6 设置环境变量 2 Vite简单介绍3 Vite创建vue项目3.1 vite创建vue项目的命令3.2 vite创建vue项目步骤 1 下载安装配置NodeJS 1.1 下载 下载地址:https://nodejs.…

全注解下的SpringIoc 续2-bean的生命周期

spring中bean的生命周期 上一个小节梳理了一下Spring Boot的依赖注入的基本知识,今天来梳理一下spring中bean的生命周期。 下面,让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分: #mermaid-svg-GFXNEU…

数据分类分级 数据识别-识别日期类型数据

前面针对数据安全-数据分类分级方案设计做了分析讲解,具体内容可点击数据安全-数据分类分级方案设计,不再做赘述 上面图片是AI创作生成!如需咒语可私戳哦! 目录 前言需求日期格式代码日期类型数据对应正则表达式前言 要做数据分类分级,重要的是分类分级模版的合理性和数…

一致性 Hash 算法 及Java TreeMap 实现

1、一致性 Hash 算法原理 一致性 Hash 算法通过构建环状的 Hash 空间替线性 Hash 空间的方法解决了这个问题,整个 Hash 空间被构建成一个首位相接的环。 其具体的构造过程为: 先构造一个长度为 2^32 的一致性 Hash 环计算每个缓存服务器的 Hash 值&…

「C/C++」C++对已有的类进行扩充

博客主页:何曾参静谧的博客 文章专栏:「C/C」C/C学习 目录 相关术语一、 继承二、组合 相关术语 继承:继承父类后可以拥有父类对应的属性和方法。 组合:将类作为成员对象,基类可以直接调用派生类对应的属性和方法。 一…

MySQL_第08章_聚合函数

第08章_聚合函数 讲师:尚硅谷 - 宋红康(江湖人称:康师傅) 官网: http://www.atguigu.com 我们上一章讲到了 SQL 单行函数。实际上 SQL 函数还有一类,叫做聚合(或聚集、分组)函…

59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境

文章目录 59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境59.1 软件介绍59.2 配置环境59.2.1 关闭防火墙并取消开机自启动59.2.2 修改SELINUX为disabled59.2.3 创建组和用户59.2.4 创建数据盘59.2.4.1 方法一:在root权限下使用fdisk进行磁盘管理5…

JVM笔记 —— 垃圾回收(GC)详解

一、垃圾回收的分类 针对HotSpot JVM的实现,它里面的GC其实准确分类只有两大种: Partial GC:部分收集模式 Young GC:只收集年轻代的GCOld GC:只收集老年代的GC。只有CMS中有这个模式。Mixed GC:收集整个年轻代以及部分…

mybatis的基本使用和理解

mybatis的基本使用和理解 Lombok的使用(使用注解的方式将实体类中的get、set、构造函数代替) Lombok是一个Java库,能自动插入编辑器并且构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或equals方法&#xff0…

Vue3 + TS4.8踩坑之配置husky问题env: sh\r: No such file or directory

一、基本情况: 硬件环境:MacOS 10.14.6 背景:用vue3官方npm init vuelatest初始化创建的vue3 ts4.8项目。 二、问题和解决方案: 问题1:git commit的时候提示:env: sh\r: No such file or directory 原…