前端项目中写单元测试其实很简单

2322 篇文章 2 订阅
2188 篇文章 14 订阅

2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)_软件测试刷题小程序-CSDN博客文章浏览阅读3.4k次,点赞86次,收藏15次。你知不知道有这么一个软件测试面试的刷题小程序。里面包含了面试常问的软件测试基础题,web自动化测试、app自动化测试、接口测试、性能测试、自动化测试、安全测试及一些常问到的人力资源题目。最主要的是他还收集了像阿里、华为这样的大厂面试真题,还有互动交流板块……_软件测试刷题小程序​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502icon-default.png?t=N7T8https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502

一、关于自动化测试

1、测试分类

自动化测试类型常分为以下三种,各有优缺点:

  • 单元测试(Unit Test)

    • 对项目中低耦合的工具类库和公共子组件进行测试,较为简单,能在一定程度上保障代码质量

  • 集成测试(Integration Test)

    • 对于耦合度较高的函数/组件对外暴露的接口进行测试,能较大程度保障产品质量,但开发成本高

  • UI测试(UI Test)

    • 前端中UI变动大,适合人工检查

了解测试术语

  • 1、TDD(测试驱动开发)

  • 2、BDD(行为驱动开发)

  • 3、测试覆盖率

  • 4、快照测试

  • 5、模拟函数

  • 6、断言

2、单元测试框架

  • Jest[1]:是一个广受欢迎的单元测试框架,简单易用,功能强大。

  • Vitest[2]:它由 Vue / Vite 团队成员开发和维护,在 Vite 的项目集成它会非常简单,而且速度非常快。

  • Mocha:一个灵活的测试框架,需要各种插件来配合使用。

  • Karma:能在真实的浏览器中测试,可配置其他单元测试框架

  • Jasmine:功能全面的测试框架,相对复杂、不够灵活

测试框架太多,且各有优势,大多数写法相差不多。

我们这里选择Jest来分享,其他测试框架可以自行了解。

3、单元测试适用的测试对象有哪些?

  • 1、常见工具类函数

  • 2、公共子组件

  • 3、接口请求数据

二、给项目配置Jest

1、安装

yarn add -D jestnpm install jest -D

2、配置(非必需)

如果你想获得更多的jest配置,可以增加配置文件。

比如项目中的Jest,默认不显示测试覆盖率和测试报告等,想要支持,就需要我们将Jest的配置文件暴露出来,只需要执行yarn test --initnpx jest --init

然后根据需求选择对应的配置,最后会在根目录下生成jest.config.js文件

图片

image.png

根据提示选择即可,这里我们选择JsDom环境,需要代码测试覆盖率报告,自动清除每个单元测试之间的模拟调用和实例。

执行完成后,发现在项目根目录下多了一个jest.config.js文件,里面包含了各种配置说明

module.exports = { 
    // 是否显示覆盖率报告 
    collectCoverage: true, 
    // 告诉 jest 文件测试要求的阈值,单位为百分比
    // coverageThreshold: {
    //   global: {
    //      statements: 90, // 每行
    //        functions: 80, // 每个函数
    //        branches: 90 // 分支覆盖率
    //    }
    // }
}

此时再次执行单元测试,发现显示了测试覆盖率

图片

image.png

用浏览器打开coverage目录下的index.html,可以看到此时页面显示了测试报告

图片

image.png

3、配置快速执行命令

package.json

{
  "scripts": {
    "start": "node index.js",
    "test": "jest",
    "coverage": "jest --coverage"
  }
}

执行命令启动单元测试yarn testyarn coverage

4、项目配置

一般通过脚手架生成的项目,已经默认配置了测试框架,比如React的项目配置了JestVue3.x项目默认配置了Vitest

  • Jest默认支持Commonjs

    • 如果你的项目不支持ESM,需要安装@babel/core, @babel/preset-env进行转译。

    • 如果你的项目需要支持TS,可以@types/jest@babel/preset-typescript

执行yarn test发现报错,是因为需要配置babel

图片

image.png

配置babel

安装插件,在根目录下新建.babelrc文件

// .babelrc
{
    "plugins": [
       [
        "@babel/plugin-syntax-jsx"
       ]
     ],
     "presets": [ "@babel/preset-env", "@babel/preset-react" ]
}

注意

  • 如何支持或忽略.css文件

  • 如何忽略单行、函数或文件、目录

5、快速上手单元测试

比如我们有sum.js

export function sum(a, b){
    return a + b;
}
export function mins(a, b){
    return a - b;
}

为这个函数写测试文件

import { sum, mins } from './sum'
it(`should add 1 + 2 to equal 3`, () => {
    expect(sum(1, 2)).toBe(3);
});
test(`mins 2 - 1 to equal 1`, () => {
    expect(min(2, 1)).toBe(1);
})

入门很简单,只需要针对每个函数做一些预期的校验即可,当不小心改动了源代码导致输出的结果和预期不符,将会测试不通过,这样就保证了代码功能的稳定。

describe、test预留字段基本没有区别,描述方式不同,一个it should,另一个test action

三、项目中如何开始写单元测试

写单元测试要考虑清楚几点:

  • 测试的主要目的不是证明代码的正确,而是为了发现错误。

  • 测试代码,只考虑外部接口,不考虑内部实现

  • 充分考虑数据的边界条件

  • 对重点、核心代码重点测试

  • 减少测试代码数量,避免无用功

  • 基于需求写单元测试

1、在项目根目录下新建tests目录,将单元测试文件放在其中,测试文件命名xx.test.js,优点是可以更好的管理测试文件,缺点是不好找到源文件

2、在对应文件的目录下新建__test__目录,测试文件放置其中,优点就是容易找到执行文件,但不容易过滤和管理

1、给工具函数写单元测试

给工具函数写测试函数是单元测试很重要的一个场景,我们以金额千分位格式化处理函数为例,通过单元测试发现问题。

// 将数字千分位格式化后返回对应的字符串
export function getThousandFormatNum(num) {
    const str = num + '';
    const reg = str.indexOf('.') > -1 ? /(\d)(?=(\d{3})+.)/g : /(\d{1,3})(?=(\d{3})+(?:$|.))/g;
    return str.replace(reg, '$1,');
}

单元测试

import { getThousandFormatNum } from './common'

describe('getThousandFormatNum', () => {
    // 常规数字格式化
    it('should return a string with thousand format', () => {
      expect(getThousandFormatNum(1000)).toBe('1,000');
      expect(getThousandFormatNum(1000000)).toBe('1,000,000');
      expect(getThousandFormatNum(123456789)).toBe('123,456,789');
    });
    
     // 格式化后和本身相同的数字
    it('should return the same number if it is not greater than 999', () => {
      expect(getThousandFormatNum(0)).toBe('0');
      expect(getThousandFormatNum(999)).toBe('999');
    });
    
    // 格式化负数
    it('should handle negative numbers correctly', () => {
      expect(getThousandFormatNum(-1000)).toBe('-1,000');
      expect(getThousandFormatNum(-1000000)).toBe('-1,000,000');
      expect(getThousandFormatNum(-123456789)).toBe('-123,456,789');
    });
    // 格式化带小数的数字
    it('should handle decimal numbers correctly', () => {
      expect(getThousandFormatNum(1234.56)).toBe('1,234.56');
      expect(getThousandFormatNum(1234567.89)).toBe('1,234,567.89');
    });
});

执行单元测试

图片

image.png

2、给组件写单元测试(快照测试)

前端主要就是组件,但业务组件变动比较频繁,所以倾向于给公共组件或组件库增加单元测试,防止组件扩展或变更导致业务Bug。

我们以APP.js组件为例,写单元测试,并生成快照。

function App() {
  return (
    <div className="App">
        <HashRouter basename="/">
          <div style={{marginBottom: 20}}>
            <Link style={{marginRight: 20}} to="/">Home更新版本1</Link>
            <Link to="/about">About更新版本123</Link>
          </div>
          <Suspense fallback={<div>Loading...</div>}>
            <Routes>
              <Route path="/" element={<AFunction />}></Route>
              <Route path="/about" element={<BFunction />} />
            </Routes>
          </Suspense>
        </HashRouter>
    </div>
  );
}

export default App;

App.js写单元测试

import { render, screen, act } from '@testing-library/react';
import App from './App';

test('renders learn react link', async () => {
  let tree;
  await act(async () => {
    tree = render(<App />);
  })
  const linkElement = screen.getByText(/About更新版本123/i);
  expect(linkElement).toBeInTheDocument();
  expect(tree).toMatchSnapshot();
});

当我们改动App.js,单元测试发现上个版本的快照更新了,就会报错,提醒检查,如果更改没问题,可以执行u更新快照

图片

image.png

3、模拟函数(Mock)

Mock是单元测试中很重要的一部分,他一般在下面场景中使用

  • 模拟数据

  • 模拟接口请求

  • 模拟定时器,比如setTimout 1小时,那每次测试花费一小时就疯了

  • 组件使用Redux怎么测试

在组件中,经常有一些引用的变量

const mock = jest.fn();  
mock.mockReturnValue(42);  
mock(); // 42  
  
mock.mockReturnValue(43);  
mock(); // 43

模拟接口请求

test('async test', async () => {  
    const asyncMock = jest.fn().mockResolvedValue(43);  // Promise
    await asyncMock(); // 43  
});

模拟函数有很多,在实际使用过程中需要各种结合使用,这里仅展示了最简单的使用。

4、常用断言方法

在工具函数测试过程中,我们常常要判断变量类型和值,测试框架往往提供了判断方法,下面是Jest一些常见的判断,更多可以查阅官网[3]

toBe:判断测试结果为某个值

not:否定判断

test('the best flavor is not coconut', () => {  
    expect(bestLaCroixFlavor()).toBe('coconut');  
});
test('the best flavor is not coconut', () => {  
    expect(bestLaCroixFlavor()).not.toBe('coconut');  
});

toEqual:检测引用类型,递归检查属性和属性值

toEqual会调用Object.is方法,toBe ===

const can1 = {  
    flavor: 'grapefruit',  
    ounces: 12,  
};  
const can2 = {  
    flavor: 'grapefruit',  
    ounces: 12,  
};  
  
describe('the La Croix cans on my desk', () => {  
    test('have all the same properties', () => {  
        expect(can1).toEqual(can2);  // true
    });  
    test('are not the exact same can', () => {  
        expect(can1).not.toBe(can2);  // true
    });  
});

toMatch:匹配字符串规则,正则匹配

describe('an essay on the best flavor', () => {  
    test('mentions grapefruit', () => {  
        expect(essayOnTheBestFlavor()).toMatch(/grapefruit/); 
        expect(essayOnTheBestFlavor()).toMatch(new RegExp('grapefruit'));  
    });  
});

toBeTruthy:匹配if条件为真

drinkSomeLaCroix();  
if (thirstInfo()) {  
    drinkMoreLaCroix();  
}

四、查看单元测试的结果

单元测试完成后,执行测试命令

yarn test 或 npx jest

1、测试覆盖率解读

图片

image.png

  • Stmts (Statements):语句覆盖率,即被测试覆盖的代码语句的百分比。在你的代码中,92.85% 的语句被测试覆盖。

  • Branch:分支覆盖率,即被测试覆盖的条件分支的百分比。在你的代码中,100% 的分支被测试覆盖。

  • Funcs (Functions):函数覆盖率,即被测试覆盖的函数的百分比。在你的代码中,83.33% 的函数被测试覆盖。

  • Lines:行覆盖率,即被测试覆盖的代码行数的百分比。在你的代码中,100% 的行被测试覆盖。

  • Uncovered Line:未覆盖的行号。这一列列出了未被测试覆盖的代码行的行号范围。

2、测试信息解读

图片

image.png

  • Test Suites: 2 passed, 2 total:这表示你有 2 个测试套件,其中所有的 2 个测试套件都通过了。

  • Tests: 8 passed, 8 total:这表示你一共运行了 8 个测试,其中所有的 8 个测试都通过了。

  • Snapshots: 1 total:这表示1个快照测试(Snapshot Testing)。

  • Time: 2.703 s:这表示测试运行的时间为 2.703 s 秒。

3、参考

  • Jest官网[4]

  • Jest实践指南[5]

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 759968159,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值