您现在的位置是:首页 >技术交流 >前端实现单元测试(代码版)网站首页技术交流

前端实现单元测试(代码版)

清羽_ls 2023-06-10 12:00:02
简介前端实现单元测试(代码版)

Jest使用

  • 下载
    • npm install --save-dev jest ts-jest ts-node @jest/globals @types/jest
      • 在nodejs中支持ts
  • ts执行报错
    • npx ts-jest config:init
  • jest 会自动运行 sum.test.js 文件,其默认匹配规则

    匹配 test 文件夹下的 .js 文件(.jsx .ts .tsx 也可以)
    匹配所有后缀为 .test.js 或 .spec.js 的文件(.jsx .ts .tsx 也可以)
    可以通过根目录下的 jest.config.js 文件自定义测试文件匹配规则

  • package.json
    "scripts": {
      "test": "jest --watchAll", //跑测试用例使用
      "test-c": "jest --coverage" //查看测试用例有哪些代码没有覆盖到
    }
    

使用流程

Jest 解析

  • 匹配器

    toBe使用 Object.is来进行精准匹配的测试
    test(‘two plus two is four’, () => {
    expect(2 + 2).toBe(4);
    });

  • toEqual 递归检查对象或数组的每个字段。

    test(‘对象赋值’, () => {
    const data = {one: 1};
    data[‘two’] = 2;
    expect(data).toEqual({one: 1, two: 2});
    });

  • 可以使用与匹配相反的 not 来进行测试

    test(‘adding positive numbers is not zero’, () => {
    for (let a = 1; a < 10; a++) {
    for (let b = 1; b < 10; b++) {
    expect(a + b).not.toBe(0);
    }
    }
    });

  • 真值

    代码中的undefined, null, and false有不同含义,若你在测试时不想区分他们,可以用真值判断。 Jest提供helpers供你使用。
    toBeNull 只匹配 null
    toBeUndefined 只匹配 undefined
    toBeDefined 与 toBeUndefined 相反
    toBeTruthy 匹配任何 if 语句为真
    toBeFalsy 匹配任何 if 语句为假

  • 数字

    大多数的比较数字有等价的匹配器。

    test(‘two plus two’, () => {
    const value = 2 + 2;
    expect(value).toBeGreaterThan(3);
    expect(value).toBeGreaterThanOrEqual(3.5);
    expect(value).toBeLessThan(5);
    expect(value).toBeLessThanOrEqual(4.5);
    // toBe and toEqual are equivalent for numbers
    expect(value).toBe(4);
    expect(value).toEqual(4);
    });

  • 对于比较浮点数相等,使用 toBeCloseTo 而不是 toEqual,因为你不希望测试取决于一个小小的舍入误差。

    test(‘两个浮点数字相加’, () => {
    const value = 0.1 + 0.2;
    //expect(value).toBe(0.3); 这句会报错,因为浮点数有舍入误差
    expect(value).toBeCloseTo(0.3); // 这句可以运行
    });
    });

  • 字符串
    您可以检查对具有 toMatch 正则表达式的字符串︰

    test(‘there is no I in team’, () => {
    expect(‘team’).not.toMatch(/I/);
    });

    test(‘but there is a “stop” in Christoph’, () => {
    expect(‘Christoph’).toMatch(/stop/);
    });

  • 数组和可迭代对象

    你可以通过 toContain来检查一个数组或可迭代对象是否包含某个特定项:

    const shoppingList = [
    ‘diapers’,
    ‘kleenex’,
    ‘trash bags’,
    ‘paper towels’,
    ‘milk’,
    ];

    test(‘shoppingList数组中包含milk’, () => {
    expect(shoppingList).toContain(‘milk’);
    expect(new Set(shoppingList)).toContain(‘milk’);
    });

  • 例外

    若你想测试某函数在调用时是否抛出了错误,你需要使用 toThrow。

    function compileAndroidCode() {
    throw new Error(‘you are using the wrong JDK!’);
    }

    test('compiling android goes as expected', () => {
      expect(() => compileAndroidCode()).toThrow();
      expect(() => compileAndroidCode()).toThrow(Error);
      // You can also use a string that must be contained in the error message or a regexp
      expect(() => compileAndroidCode()).toThrow('you are using the wrong JDK');
      expect(() => compileAndroidCode()).toThrow(/JDK/);
      // Or you can match an exact error message using a regexp like below
      expect(() => compileAndroidCode()).toThrow(/^you are using the wrong JDK$/); // Test fails
      expect(() => compileAndroidCode()).toThrow(/^you are using the wrong JDK!$/); // Test pass
    });
    

code

  • jest.config.js

    • 配置
    /** @type {import('ts-jest').JestConfigWithTsJest} */
    
    module.exports = {
      preset: 'ts-jest',
      testEnvironment: 'node',
      testMatch: [
        // glob 格式
        // '**/__tests__/**/*.[jt]s?(x)',
        '**/__test__/**/*.[jt]s?(x)',//指定文件夹,其他tests文件夹不测试
        // '**/?(*.)+(spec|test).[jt]s?(x)',
      ],
      // 正则表达式格式,与 testMatch 互斥,不能同时声明
      // testRegex: '(/__tests__/.*|(\.|/)(test|spec))\.[jt]sx?$',
    };
    
    
  • utils/index.tsx

    • 需要测试的函数
    export function toDigit(num): string {
      if (!num) {
        return '-';
      }
      const numArr = (`${num}`).split('.');
      num = numArr[0];
      let result = '';
      while (num.length > 3) {
        result = `,${num.slice(-3)}${result}`;
        num = num.slice(0, num.length - 3);
      }
      if (num) {
        result = num + result;
      }
      if (numArr.length === 1) {
        return `${result}.00`;
      } else if (numArr[1].length === 2) {
        return `${result}.${numArr[1]}`;
      } else {
        return `${result}.${numArr[1]}0`;
      }
    }
    
    
  • __test__/toDigit.test.ts

    • 编写单测, expect断言
import { describe, test, expect } from '@jest/globals';
import { toDigit } from '../src/utils/index';

const arr: number[] = [2344513099.66, 53450000, 0];

describe('utils toDigit test', () => {
  test('toDigit test 1', () => {
    expect(toDigit(arr[0])).toBe('2,344,513,099.66');
  });
  test('toDigit test 2', () => {
    expect(toDigit(arr[1])).toBe('53,450,000.00');
  });
  test('toDigit test 3', () => {
    expect(toDigit(arr[2])).toBe('-');
  });
});
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。