【无标题】

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


提示:以下是本篇文章正文内容,下面案例可供参考

一、前端要学的测试课

1.前端要学的测试

         a.Jest入门;

        b.TDD实战;

        c.BDD实战;

2.前端工程化的一部分

        a.前端自动化测试;

        b.高质量代码设计;

        c.高质量代码实现;

3.前端自动化测试的例子

Vue、Echarts、React、Ant-Design...这些都有使用到自动化测试。

4.前端为什么需要自动化测试?

        a.改需求十,代码重构:导致修复时间长,成本高;

        b.自动化测试,修复时间少,难度低;

5.课程涵盖内容

学习安排:

a. 第一章 课程介绍

b. 第二章 Jest基础

c. 第三章 Jest进阶

d. 第四&六 React 测试

e. 第五&七章 Vue测试

f. 第八章 前端自动化测试的思考总结

6.前置技能

7.学习收获

a. 彻底入门前端自动化测试

b. 根据项目完成测试方案选型

c. 主流前端测试工具使用

d. 完成前端系动画测试项目落地

e. 形成多维度前端架构思维

二、Jest前端自动化测试框架基础入门

1.自动化测试背景及原理

前端自动化测试产生的背景及原理

作为一名前端开发者,每天都会遇到各种各样的bug,比如安全性的bug,逻辑bug,性能bug,展示bug等,在日常开发过程种想要不出bug几乎是不可能的。

每当遇到复杂的业务场景或对代码进行修补的时候出现bug其实是非常正常的事情,bug本身并不可怕,可怕的是把bug真正的带到线上。

所以为了了防止bug上线,可以做些比如codeview的整合,通过测试同学的测试,帮助发现代码潜在的问题,或者通过灰度发布这样的机制帮助在代码上线之前进行局部的验证,这些方法都可以很好的帮助降低bug上线的概率。

但是对于前端来说还有没有更好的办法降低代码种bug出现的频率呢?是有的,一些简单错误可以通过以下几种工具来规避:

TypeScript、Flow、EsLint、StyleLint...

他们都可以帮助提高前端代码质量,减少bug数量,当然这还不够,还可以使用前端自动化测试工具来进一步避免bug的产生。

说到自动化测试,在后端自动化测试已经很普遍被应用了,当时在前端领域目前被普及的情况并不是很好,隐藏学习前端测试刻不容缓

常见测试种类:

a. 单元测试

b. 集成测试

c. end To end 端到端测试

d. 回归测试

e. 性能测试

f. 压力测试

为了更好的理解,接下来进入代码环节

        a.新建文件夹(mkdir lesson1)

        b.打开新建的文件夹(cd lesson1)

        c.创建文件(touch math.js) 

function add(a,b){
    return a +b;
}

function minus(a,b){
    return a - b;
}

创建文件(touch index.html), 引入math.js

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>math.js</title>
        <script src="math.js"></script>
    </head>    
    <body></body>
</html>

创建文件(touch math.test.js) 

 

let result = add(3,7);
let expected = 10;

if(result !== expected){
    throw Error(`3+7应该等于${expected},结果却是${result}`)
}

result = minus(3,3)
expected = 0;

if(result !== expected){
    throw Error(`3-3应等于${expected},结果却是${result}`)
}

直接打开页面在浏览器的控制台,输入math.test.js中的测试代码并执行

a.index.html已经引入了math.js这个函数库,可以通过直接在控制台执行的方式调用 

b.测试过程中若是修改了源代码,需要刷新页面再执行代码

我们写的测试的例子基本上都是一个套路,就是先预期一个结果,然后在执行计算出真正的结果,然后两个结果进行比较是否相同,如果相同就可以通过,如果不相同就抛出异常错误信息。

优化测试代码,单独封装一个expect函数,方便使用:

function expect(result){
    return {
        toBe:function(actual){
        if(result !== actual){
            throw Error('预期值和实际值不相等')
        }
    }
 }
}
expect(add(3,3)).toBe(6);
expect(minus(6,3)).toBe(3);

2.前端自动化测试框架

在实际项目中只有except和test两个方法显然是不够的,同时还有很多自动化测试机制需要集成。

现在业界已经有很多前端自动化测试框架,一些框架里面集成了非常多的方法和机制供选用,在使用过程中的可以方便快捷的进行项目级别的前端自动化测试了。

目前业界主流的几个前端自动化测试框架包括 Jasmine、Mocha+Chai、Jest。

一个好的前端自动化测试框架应该在以下几个方面比较突出:

a.性能好

b.功能丰富

c.易用性高

Jest优势:

a.速度快(在编辑过程中可以自动运行修改部分的测试代码) 

b. API简单

c.易配置

e.隔离性好

f.监控模式

g.IDE整合

h.快照Snapshot

i.多项目并行

j.覆盖率报告快速生成

k.Mock丰富

m.支持扩展性强,如:Babel、TypeScript、Node.js、React、angular、Vue

3.使用Jest修改自动化测试样例

接下来开始使用Jest,在这之前需要提前安装好Node环境

        1.新建文件夹(mkdir lesson2)

        2.进入新建的目录(cd lesson2)

        3.初始化npm包管理环境(npm init)

        4.一路回车后可以看到目录下生成一个文件———package.json

        5.安装Jest(npm i jest@24.8.0 -D)

                *-D表示只有在开发的时候才会运行测试用例

        6.安装好后将上节代码复制过来并作如下修

math.js作为node模块到处

function add(a,b){
    return a+b;
}
function minus(a,b) {
    return a -b;
}

function multi(a,b){
    return a*b;
}

module.exports = {
    add,
    minus,
    multi
}

math.test.js中math.js作为node模块导入并使用

const math = require('./math');
const {
    add,minus,multi
} = math;

test('测试加法3+7',()=>{
    expect(add(3,3)).toBe(6)
})

test('测试减法6-3',()=>{
    expect(minus(6,3)).toBe(3)
})

test('测试乘法3*3',()=>{
    expect(multi(3,3)).tiBe(9)
})

修改配置package.json

{
    ...
    "script":{
        "test":"jest --watchALL"
    },
    ...
}

--watchAll表示监听所有测试用例,当有发生变化时,自动运行jest重跑所有测试用例 

控制台运行npm run test 结果如下:

>lesson2@1.0.0 test
> jest

 PASS ./math.test.js
    测试加法3+7 (4ms)
    测试减法 6-3
    测试乘法 3*3(1ms)
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        5.468s
Ran all test suites.

 若是测试代码写错,结果如下:

>lesson@1.0.0 test
>jest

FAIL ./math.test.js
  √ 测试加法 3 + 7 (6ms)
  √ 测试减法 6 - 3 (1ms)
  × 测试乘法 3 * 3 (7ms)

  ● 测试乘法 3 * 3
    exprct(received).toBe(expected) //Object.is equality
    Expected: 3
    Received:9
        15 |
        16 | test('测试乘法 3 * 3', () => {
        > 17 |   expect(multi(3,3)).toBe(3);
         |                      ^
        18 | });
        at Object.<anonymous> (math.test.js:17:22)
Test Suites: 1 failed, 1 total
Tests:       1 failed, 2 passed, 3 total
Snapshots:   0 total
Time:        4.258s
Ran all test suites.

 为什么math中的方法必须导出来呢?

因为Jest在前端项目中帮助外面完成两类内容

        1.单元测试(模块测试)

        2.集成测试(多个模块测试)

因此必须要以模块的方式来使用

不论时按照CommonJS还是Es Module 改造,都需要符合Jest才能进行自动化测试

 但是这样的花在html文件中使用会产生报错:

Uncaught ReferenceError: module is not defined

可以小改造以下(math.js)

...
try{
    module.exports={
        add,minus,multi
    }
} catch (a) {}

 这种报错一般是不会出现在项目中的,现在的项目基本都是模块花编码

4.Jest的简单配置

jest有默认配置,下面来自定义配置,在这之前需要生成配置文件,运行npx jest --init

// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html

module.exports = {
  // All imported modules in your tests should be mocked automatically
  // automock: false,

  // Stop running tests after `n` failures
  // bail: 0,

  // Respect "browser" field in package.json when resolving modules
  // browser: false,

  // The directory where Jest should store its cached dependency information
  // cacheDirectory: "C:\\Users\\AImooc-Oliver\\AppData\\Local\\Temp\\jest",

  // Automatically clear mock calls and instances between every test
  clearMocks: true,

  // Indicates whether the coverage information should be collected while executing the test
  // collectCoverage: false,

  // An array of glob patterns indicating a set of files for which coverage information should be collected
  // collectCoverageFrom: null,

  // The directory where Jest should output its coverage files
  coverageDirectory: "coverage",

  // An array of regexp pattern strings used to skip coverage collection
  // coveragePathIgnorePatterns: [
  //   "\\\\node_modules\\\\"
  // ],

  // A list of reporter names that Jest uses when writing coverage reports
  // coverageReporters: [
  //   "json",
  //   "text",
  //   "lcov",
  //   "clover"
  // ],

  // An object that configures minimum threshold enforcement for coverage results
  // coverageThreshold: null,

  // A path to a custom dependency extractor
  // dependencyExtractor: null,

  // Make calling deprecated APIs throw helpful error messages
  // errorOnDeprecated: false,

  // Force coverage collection from ignored files using an array of glob patterns
  // forceCoverageMatch: [],

  // A path to a module which exports an async function that is triggered once before all test suites
  // globalSetup: null,

  // A path to a module which exports an async function that is triggered once after all test suites
  // globalTeardown: null,

  // A set of global variables that need to be available in all test environments
  // globals: {},

  // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
  // maxWorkers: "50%",

  // An array of directory names to be searched recursively up from the requiring module's location
  // moduleDirectories: [
  //   "node_modules"
  // ],

  // An array of file extensions your modules use
  // moduleFileExtensions: [
  //   "js",
  //   "json",
  //   "jsx",
  //   "ts",
  //   "tsx",
  //   "node"
  // ],

  // A map from regular expressions to module names that allow to stub out resources with a single module
  // moduleNameMapper: {},

  // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
  // modulePathIgnorePatterns: [],

  // Activates notifications for test results
  // notify: false,

  // An enum that specifies notification mode. Requires { notify: true }
  // notifyMode: "failure-change",

  // A preset that is used as a base for Jest's configuration
  // preset: null,

  // Run tests from one or more projects
  // projects: null,

  // Use this configuration option to add custom reporters to Jest
  // reporters: undefined,

  // Automatically reset mock state between every test
  // resetMocks: false,

  // Reset the module registry before running each individual test
  // resetModules: false,

  // A path to a custom resolver
  // resolver: null,

  // Automatically restore mock state between every test
  // restoreMocks: false,

  // The root directory that Jest should scan for tests and modules within
  // rootDir: null,

  // A list of paths to directories that Jest should use to search for files in
  // roots: [
  //   "<rootDir>"
  // ],

  // Allows you to use a custom runner instead of Jest's default test runner
  // runner: "jest-runner",

  // The paths to modules that run some code to configure or set up the testing environment before each test
  // setupFiles: [],

  // A list of paths to modules that run some code to configure or set up the testing framework before each test
  // setupFilesAfterEnv: [],

  // A list of paths to snapshot serializer modules Jest should use for snapshot testing
  // snapshotSerializers: [],

  // The test environment that will be used for testing
  // testEnvironment: "jest-environment-jsdom",

  // Options that will be passed to the testEnvironment
  // testEnvironmentOptions: {},

  // Adds a location field to test results
  // testLocationInResults: false,

  // The glob patterns Jest uses to detect test files
  // testMatch: [
  //   "**/__tests__/**/*.[jt]s?(x)",
  //   "**/?(*.)+(spec|test).[tj]s?(x)"
  // ],

  // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
  // testPathIgnorePatterns: [
  //   "\\\\node_modules\\\\"
  // ],

  // The regexp pattern or array of patterns that Jest uses to detect test files
  // testRegex: [],

  // This option allows the use of a custom results processor
  // testResultsProcessor: null,

  // This option allows use of a custom test runner
  // testRunner: "jasmine2",

  // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
  // testURL: "http://localhost",

  // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
  // timers: "real",

  // A map from regular expressions to paths to transformers
  // transform: null,

  // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
  // transformIgnorePatterns: [
  //   "\\\\node_modules\\\\"
  // ],

  // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
  // unmockedModulePathPatterns: undefined,

  // Indicates whether each individual test should be reported during the run
  // verbose: null,

  // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
  // watchPathIgnorePatterns: [],

  // Whether to use watchman for file crawling
  // watchman: true,
};

 常见npx jest --coverage可以查看覆盖率 

 PASS  ./math.test.js
  √ 测试加法 3 + 7 (13ms)
  √ 测试减法 6 - 3 (1ms)
  √ 测试乘法 3 * 3 (1ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 math.js  |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.569s
Ran all test suites.

 不仅在控制台有,在根目录也生成了相应文件:

.
|-- clover.xml
|-- coverage-final.json
|-- lcov-report
|   |-- base.css
|   |-- block-navigation.js
|   |-- index.html
|   |-- math.js.html
|   |-- prettify.css
|   |-- prettify.js
|   |-- sort-arrow-sprite.png
|   `-- sorter.js
`-- lcov.info

1 directory, 11 files

 Jest/lesson2/coverage/lcov-report/index.html 可以直接访问:

 

 可以修改配置package.json

{
...
"script":{
        "coverage":"jest --coverage"
    }
}

之后运行 npm run coverage,也是一样的效果

 修改 Jest\lesson2\jest.config.js 中的 coverageDirectory 可以指定生成目录名称

 一般前端项目中都是使用 ESModule 的语法,按 ESModule 改一下:

math.js

function add(a,b) {
  return a + b;
}

function minus(a,b) {
  return a - b;
}

function multi(a,b) {
  return a * b;
}

export {
  add,
  minus,
  multi
}

math.test.js

 

import {
  add,
  minus,
  multi
} from './math'

test('测试加法 3 + 7', () => {
  expect(add(3,3)).toBe(6);
});
 
test('测试减法 6 - 3', () => {
  expect(minus(6,3)).toBe(3);
});
 
test('测试乘法 3 * 3', () => {
  expect(multi(3,3)).toBe(9);
});

 改完代码之后,运行 jest 会有报错产生,这是因为 jest 是运行在 node 环境,并不能直接识别 ESModule 的语法,这就要用到 babel 了

安装babel相关依赖

npm i @babel.core@7.4.5 @babel/preset-env@7.4.5 -D

在根目录新建babel配置文件.babelrc

{
    "presets":[
        [
            "@babel/preset-evn",{   
            "targets":{
                "node":"current"
            }
        }
        ]
    ]
}

再次运行 jest ,成功! 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值