news 2026/6/10 10:03:14

开发中的测试知识—— 集成测试策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开发中的测试知识—— 集成测试策略

背景问题:
需要对复杂功能进行集成测试。

方案思考:
使用端到端测试和组件集成测试相结合的策略。

具体实现:
端到端测试配置(Playwright):

# 安装 Playwrightnpminstall-D @playwright/test npx playwrightinstall

Playwright 配置:

// playwright.config.jsimport{defineConfig,devices}from'@playwright/test'exportdefaultdefineConfig({testDir:'./tests/e2e',fullyParallel:true,forbidOnly:!!process.env.CI,retries:process.env.CI?2:0,workers:process.env.CI?1:undefined,reporter:'html',use:{baseURL:'http://localhost:3000',trace:'on-first-retry',},projects:[{name:'chromium',use:{...devices['Desktop Chrome']},},{name:'firefox',use:{...devices['Desktop Firefox']},},{name:'webkit',use:{...devices['Desktop Safari']},},],webServer:{command:'npm run dev',url:'http://localhost:3000',reuseExistingServer:!process.env.CI,},})

端到端测试示例:

// tests/e2e/login.spec.jsimport{test,expect}from'@playwright/test'test.describe('Login functionality',()=>{test.beforeEach(async({page})=>{awaitpage.goto('/login')})test('should allow valid user to login',async({page})=>{// 输入用户名awaitpage.locator('input[name="username"]').fill('admin')// 输入密码awaitpage.locator('input[name="password"]').fill('admin123')// 点击登录按钮awaitpage.locator('button[type="submit"]').click()// 验证跳转到主页awaitexpect(page).toHaveURL('/dashboard')awaitexpect(page.locator('.user-info')).toContainText('admin')})test('should show error for invalid credentials',async({page})=>{// 输入错误的用户名和密码awaitpage.locator('input[name="username"]').fill('invalid')awaitpage.locator('input[name="password"]').fill('wrongpass')// 点击登录按钮awaitpage.locator('button[type="submit"]').click()// 验证错误消息显示awaitexpect(page.locator('.error-message')).toBeVisible()awaitexpect(page.locator('.error-message')).toContainText('用户名或密码错误')})test('should validate form inputs',async({page})=>{// 点击登录按钮而不填写任何内容awaitpage.locator('button[type="submit"]').click()// 验证验证错误消息awaitexpect(page.locator('.el-form-item__error')).toHaveCount(2)})})

集成测试示例:

<!-- views/UserManagement.vue --> <template> <div class="user-management"> <el-input v-model="searchTerm" placeholder="搜索用户..." @input="performSearch" /> <el-table :data="filteredUsers" v-loading="loading"> <el-table-column prop="name" label="姓名" /> <el-table-column prop="email" label="邮箱" /> <el-table-column label="操作"> <template #default="{ row }"> <el-button @click="editUser(row)">编辑</el-button> <el-button @click="deleteUser(row.id)" type="danger">删除</el-button> </template> </el-table-column> </el-table> </div> </template> <script setup> import { ref, computed, onMounted } from 'vue' import { useUserStore } from '@/stores/user' const userStore = useUserStore() const searchTerm = ref('') const loading = ref(false) // 获取过滤后的用户 const filteredUsers = computed(() => { if (!searchTerm.value) { return userStore.users } return userStore.users.filter(user => user.name.toLowerCase().includes(searchTerm.value.toLowerCase()) || user.email.toLowerCase().includes(searchTerm.value.toLowerCase()) ) }) // 执行搜索 const performSearch = () => { // 实际项目中可能会调用 API } // 编辑用户 const editUser = (user) => { // 编辑逻辑 } // 删除用户 const deleteUser = async (id) => { await userStore.deleteUser(id) } onMounted(() => { loading.value = true userStore.fetchUsers().finally(() => { loading.value = false }) }) </script>
// tests/integration/UserManagement.test.jsimport{describe,it,expect,beforeEach,vi}from'vitest'import{mount}from'@vue/test-utils'import{createTestingPinia}from'@pinia/testing'importUserManagementfrom'@/views/UserManagement.vue'describe('UserManagement Integration',()=>{letwrapperbeforeEach(()=>{// 创建测试用的 Pinia 实例consttestingPinia=createTestingPinia({createSpy:vi.fn,stubActions:false})// Mock storeconstuserStore=testingPinia.useUserStore()userStore.users=[{id:1,name:'John Doe',email:'john@example.com'},{id:2,name:'Jane Smith',email:'jane@example.com'}]wrapper=mount(UserManagement,{global:{plugins:[testingPinia]}})})it('displays users from store',async()=>{awaitwrapper.vm.$nextTick()// 等待组件更新consttableRows=wrapper.findAll('tbody tr')expect(tableRows).toHaveLength(2)constfirstRowCells=tableRows[0].findAll('td')expect(firstRowCells[0].text()).toContain('John Doe')expect(firstRowCells[1].text()).toContain('john@example.com')})it('filters users based on search term',async()=>{constsearchInput=wrapper.find('input')// 搜索 JohnawaitsearchInput.setValue('John')awaitsearchInput.trigger('input')consttableRows=wrapper.findAll('tbody tr')expect(tableRows).toHaveLength(1)expect(tableRows[0].find('td').text()).toContain('John Doe')})it('deletes user when delete button is clicked',async()=>{constuserStore=wrapper.vm.$pinia.state.value.userexpect(userStore.users).toHaveLength(2)// 点击第一个删除按钮constdeleteButtons=wrapper.findAll('button[type="danger"]')awaitdeleteButtons[0].trigger('click')// 验证 store 中的用户数量减少expect(userStore.users).toHaveLength(1)expect(userStore.users[0].id).toBe(2)})})

模拟 API 服务:

// tests/mocks/server.jsimport{setupServer}from'msw/node'import{http,HttpResponse}from'msw'consthandlers=[http.get('/api/users',()=>{returnHttpResponse.json({code:200,data:[{id:1,name:'John Doe',email:'john@example.com'},{id:2,name:'Jane Smith',email:'jane@example.com'}],total:2})}),http.post('/api/users',async({request})=>{constuserData=awaitrequest.json()returnHttpResponse.json({code:200,data:{...userData,id:Date.now()}})}),http.delete('/api/users/:id',({params})=>{const{id}=paramsreturnHttpResponse.json({code:200,message:`User${id}deleted`})})]exportconstserver=setupServer(...handlers)
// tests/setup.js (更新)import{afterAll,afterEach,beforeAll}from'vitest'import{server}from'./mocks/server'// 开始 mock 服务器beforeAll(()=>server.listen({onUnhandledRequest:'error'}))// 清理请求处理程序afterEach(()=>server.resetHandlers())// 关闭服务器afterAll(()=>server.close())
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 2:01:47

uni-app—— 小程序表单页面键盘弹起布局错乱问题

问题现象 表单页面点击输入框&#xff0c;键盘弹起后&#xff1a;平台表现安卓输入框位置错位&#xff0c;光标飘到其他位置iOS键盘遮挡输入框&#xff0c;看不到输入内容问题原因 当页面同时存在以下三个因素时&#xff0c;容易出现布局错乱&#xff1a; scroll-view float布…

作者头像 李华
网站建设 2026/5/31 20:25:45

什么是Java可重入锁?

大家好&#xff0c;我是锋哥。今天分享关于【什么是Java可重入锁&#xff1f;】面试题。希望对大家有帮助&#xff1b; 什么是Java可重入锁&#xff1f; Java 可重入锁&#xff08;Reentrant Lock&#xff09;是 Java 中的一种高级同步工具&#xff0c;用于控制对共享资源的访…

作者头像 李华
网站建设 2026/6/2 17:49:50

基于MATLAB的三维装箱程序实现(遗传算法+模拟退火优化)

一、核心算法框架 三维装箱问题通过**遗传算法&#xff08;GA&#xff09;全局搜索与模拟退火&#xff08;SA&#xff09;**局部优化结合&#xff0c;解决多约束条件下的最优装箱问题。核心流程如下&#xff1a;数据输入&#xff1a;读取货物尺寸&#xff08;长宽高&#xff09…

作者头像 李华
网站建设 2026/5/9 18:12:39

基于YOLOv8和RepGhost的轻量化目标检测优化与性能提升

文章目录 一、为什么毕设需要RepGhost? 二、RepGhost核心原理:“训练时变强,推理时变快” 1. 幽灵特征生成 2. 重参数化多分支结构 三、实战:给YOLOv8植入RepGhost“轻量化引擎” 环境准备 1. RepGhost模块实现 2. 改造YOLOv8配置文件 3. 训练与推理 训练命令 推理命令 四、…

作者头像 李华
网站建设 2026/6/5 4:22:39

Android 12 on RK3588:ASoC音频驱动与电池管理系统(BMS)协同优化全流程详解

文章目录 前言 一、Android 12音频系统架构深度解析 1.1 整体架构概览 1.2 各层职责详解 1.3 数据流转机制 二、ASoC音频驱动框架核心原理 2.1 ASoC架构设计理念 2.2 三大组件详细分析 Platform驱动 - 数字音频接口的大脑 音频数据传输流程深度解析 Codec驱动 - 模拟世界的桥梁…

作者头像 李华
网站建设 2026/6/6 5:12:33

国家电网Java面试被问:混沌工程在分布式系统中的应用

一、核心理念&#xff1a;从电力系统可靠性工程借鉴 1.1 混沌工程与电力系统可靠性的共鸣 关键点&#xff1a;将电力行业的“N-1准则”、“黑启动演练”思想引入分布式系统 text 复制 下载 电力系统 vs 分布式系统&#xff1a; • N-1准则&#xff08;电力&#xff09; ↔ …

作者头像 李华