前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端接入单元测试(Node+React)

前端接入单元测试(Node+React)

作者头像
kiki.
修改2023-06-14 17:42:32
3.3K0
修改2023-06-14 17:42:32
举报
文章被收录于专栏:web全栈之路

意义

假如要重构一个老前端框架,并根据其开发一个向后兼容的新框架。此时老框架针对其内部API函数,写了充分的单侧用例。在开发新框架时,直接运行老前端框架的单侧用例,如果所有测试用例都通过,则可快速保证内部api的一致性,快速验证所有功能。

  • 保障代码质量和功能的实现的完整度
  • 提升开发效率,提前发现和定位bug
  • 便于项目维护,后续重构也能快速测试保证功能正常。

主流测试工具比较

框架

断言

仿真

快照

异步测试

Mocha

默认不支持,可配置

默认不支持,可配置

默认不支持,可配置

友好

Ava

默认支持

不支持,需第三方配置

默认支持

友好

Jasmine

默认支持

默认支持

默认支持

不友好

Jest

默认支持

默认支持

默认支持

友好

Karma

不支持,需第三方配置

不支持,需第三方配置

不支持,需第三方配置

不支持,需第三方配置

Mocha

  • Mocha 是生态最好,使用最广泛的单测框架,但是他需要较多的配置来实现它的高扩展性。

Ava

  • Ava 是更轻量高效简单的单测框架,但是自身不够稳定,并发运行文件多的时候会撑爆 CPU。

Jasmine

  • Jasmine 是单测框架的“元老”,开箱即用,但是异步测试支持较弱。

Jest

  • Jest 基于 Jasmine, 做了大量修改并添加了很多特性,同样开箱即用,但异步测试支持良好。

Karma

  • Karma 能在真实的浏览器中测试,强大适配器,可配置其他单测框架,一般会配合 Mocha 或 Jasmine 等一起使用。

每个框架都有自己的优缺点,没有最好的框架,只有最适合的框架。Augular 的默认测试框架就是 Karma + Jasmine,Egg默认测试框架是Mocha,而 React 的默认测试框架是 Jest。node测试框架因为egg内置Mocha,因此不额外引入jest。 Jest 被各种 React 应用推荐和使用。它基于 Jasmine,至今已经做了大量修改并添加了很多特性,同样也是开箱即用,支持断言,仿真,快照等。Create React App 新建的项目就会默认配置 Jest,我们基本不用做太多改造,就可以直接使用。

单元测试

  1. node单元测试 egg单侧语法参考
  • controller测试
代码语言:javascript
复制
const { app, assert } = require('egg-mock/bootstrap');
describe('search test', () => {
 it('search test', () => {
 return app.httpRequest().get('/search').expect(200);
});
it('search test', () => {
 return app.httpRequest().get('/categories').expect(200);
 });
});
  • service测试
代码语言:javascript
复制
const { app, assert } = require('egg-mock/bootstrap');
describe('product service', () => {
 	it('get product category', async () => {
 	const ctx = app.mockContext();
 	const res = await ctx.service.product.getCategoryList();
 	assert(res);
 });
});
  • extend方法测试
代码语言:javascript
复制
const { app, assert } = require('egg-mock/bootstrap');
describe('helper test', () => {
  it('jsonKeysToCase',  () => {
  const ctx = app.mockContext();
  const res = ctx.helper.jsonKeysToCase({
 	List: [{
	ProductId: "25502"
 }]
 }, 3);
assert(res.list[0].productId === '25502');
});
});
  • 页面请求测试
代码语言:javascript
复制
describe('页面拨测', () => {
 it('product test', async() => {
  const ctx = app.mockContext();
  let res= await Promise.all(urls.map(v=> ctx.curl(v)));
  assert(res.every(v=>v.status===200))
 });
});

React单元测试 官方文档

环境安装
  1. 安装依赖
代码语言:javascript
复制
npm i --save-dev jest@27.4.3 
npm i --save-dev babel-jest@27.4.2
npm i --save-dev @testing-library/jest-dom@5.16.5  @testing-library/react@13.4.0
  1. 添加jest.config.js
代码语言:javascript
复制
module.exports = {
  testEnvironment: 'jsdom',
  moduleNameMapper: {
    "\\.(css|scss)$": "identity-obj-proxy"
  },
  testMatch: ["<rootDir>/test/**/*.{spec,test}.{js,ts}"],
  transform: {
    "^.+\\.[t|j]sx?$": "babel-jest"
  },
  // 覆盖率设置
  coverageThreshold:{
    global:{
      statements: 50,
      branches: 50,
      functions: 50,
      lines: 50
    },
    "./src/components/button": {
      branches: 50
    },
  }
}
  1. 添加babel.config.js
代码语言:javascript
复制
module.exports = {
  presets: [
  	'@babel/preset-env',
  	'@babel/preset-react',
  ],
}
  1. package.json添加scrpit "test": "jest --coverage"
单元测试编写
  • 测试业务逻辑
代码语言:javascript
复制
describe('formatDate测试', ()=>{
 it('formate 0 返回 1970-1-1', () => {
 	expect(formatDate(0)).toBe('1970-1-1');
 });
 test('formate -1 返回 1969-12-31', () => {
 	expect(formatDate(0)).toBe('1970-1-1');
 });
 test('two plus two is four', () => {
 	expect(2 + 3).toBe(5);
 });
})
  • 测试异步方法
代码语言:javascript
复制
function fetchData() {
  return new Promise((resolve) => {
 	setTimeout(() => {
 	resolve('Hello world')
 	}, 1000);
  })
}

test('Promise', () => {
  return fetchData().then(data => {
    expect(data).toBe('Hello world')
  })
})
  • 测试react组件,最开始使用Enzyme,后面从React脚手架创建的项目自带React Testing Library(RTL),官方推荐使用RTL
代码语言:javascript
复制
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import Todo from "../../src/components/Todo";
import "@testing-library/jest-dom/extend-expect";
it("components Todo", () => {
  const { getByTestId } = render(<Todo />);
  const todos = getByTestId("todos");
  expect(todos.children.length).toBe(2);
});
  • Mock模块
代码语言:javascript
复制
// fetch.js
import axios from 'axios';
export default {
  async fetchPostsList(callback) {
	  return axios.get('https://jsonplaceholder.typicode.com/posts').then(res => {
		return callback(res.data);
	  })
  }
}
代码语言:javascript
复制
import fetch from '../src/fetch.js'
test('fetchPostsList中的回调函数应该能够被调用', async () => {
  expect.assertions(1);
  let mockFn = jest.fn();
  await fetch.fetchPostsList(mockFn);
  // 断言mockFn被调用
  expect(mockFn).toBeCalled();
})
  • 测试快照用法 如果频繁修改业务代码时,对应的测试用例可能也要修改。那么如何避免这个问题呢?使用Snapshot快照可以解决。 用法:
代码语言:javascript
复制
describe('Demo Basic Simple', () => {
  const childTitleText = 'This is Child Title';
  const ChildNameText = 'Jane Austen';
  test('Test Render', async () => {
  	const ins = render(<Demo />);
  	expect(ins.baseElement).toMatchSnapshot();
  })
 })

快照执行流程:

  • 第一次执行toMatchSnapshot,会将expect中的结果生成一个快照
  • 修改组件保存后,第二次执行toMatchSnapshot,会再次生成快照,和上次快照对比,如果一致,则测试通过,如果不一致,测试不通过,说明组件有改动
  • 更新快照对比结果:npm test – -u

了解测试覆盖率 Statements 语句覆盖率,它其实对应的就是js语法上的语句,js解析成ast数中类型为 statement 。 Branches 分支覆盖率,通俗点理解就是 if/else 这类条件 Functions 函数覆盖率 Lines 行数覆盖率,就是代码执行了多少行

自动化测试

undefined
undefined

对于前端来说,主要关注单元测试、集成测试、E2E测试 集成测试:测试应用中不同模块如何集成,如何一起工作。目的在于,测试经过单元测试后的各个模块组合在一起是否能正常工作。会对组合之后的代码整体暴露在外接口进行测试,查看组合后的代码工作是否符合预期。 E2E测试:端到端测试, 聚焦于用户和 web 之间的交互,把 web 当作一个黑盒,站在用户的角度,模拟用户的操作,判断每次操作的结果是否符合预期。有些人也把UI自动化测试称为E2E测试

undefined
undefined

可以看出,单元测试是整个测试组合的基石,

  • QTA自动化测试 http://qta.woa.com/marketnode/autotest/task/105307/history 优点: 可以作为任务定时去执行,可以和蓝盾配合使用 缺点:需要添加项目和任务,执行时间长,node没有对应的mocha库,需要额外安装jest库
  • TestOne DWT 前端自动化测试 http://testone.woa.com/dwt/tiyan#/docs/getStarted 可视化查询测试结果,可结合蓝盾插件和质量红线做流水线测试,整个配置比较重,耗时,目前项目缺少测试用例,可在后续集成。
  • orange-ci跑单元测试 优点:配置简单,和现有的工作流集成在一起,可以在构建前执行测试用例,执行效率高…

总结

  • node项目可以利用egg自带的测试工具,针对controller, service, extend, helper等模块编写单元测试,特别是controller重要的路由需要做单元测试;
  • 控制台和其他React项目可以利用jest工具,针对方法、组件、模块去做单元测试,特别是组件,可以利用快照功能避免多次修改测试用例。
  • 单元测试是测试流程的基础部分,粒度最高成本最低,对于提升前端质量有重要作用。
参考

使用Enzyme和React Testing Library测试React Hooks https://cloud.tencent.com/developer/article/1651156

点击加入群聊【小程序/前端交流】,一起学习交流:663077768

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 意义
  • 主流测试工具比较
  • Mocha
  • Ava
  • Jasmine
  • Jest
  • Karma
  • 单元测试
  • 自动化测试
  • 总结
  • 点击加入群聊【小程序/前端交流】,一起学习交流:663077768
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档