zoukankan      html  css  js  c++  java
  • 单元测试(Jest 和 Mocha)

     Vue CLI 拥有通过 Jest 或 Mocha 进行单元测试的内置选项。

    • Jest 是功能最全的测试运行器。它所需的配置是最少的,默认安装了 JSDOM,内置断言且命令行的用户体验非常好。不过你需要一个能够将单文件组件导入到测试中的预处理器。我们已经创建了 vue-jest 预处理器来处理最常见的单文件组件特性,但仍不是 vue-loader 100% 的功能。

    • mocha-webpack 是一个 webpack + Mocha 的包裹器,同时包含了更顺畅的接口和侦听模式。这些设置可以帮助我们通过 webpack + vue-loader 得到完整的单文件组件支持,但这本身是需要很多配置的。  

      测试运行器就是运行测试的程序。

    用 Jest 测试单文件组件

     Vue 的单文件组件在它们运行于 Node 或浏览器之前是需要预编译的。我们推荐两种方式完成编译:

      1. 通过一个 Jest 预编译器

      2. 直接使用 webpack

     vue-jest 预处理器支持基本的单文件组件功能,但是目前还不能处理样式块和自定义块,这些都只在 vue-loader 中支 持。如果你依赖这些功能或其它 webpack 特有的配置项,那么你需要基于 webpack + vue-loader 进行设置。

      1. 安装 Jest

      首先安装 Jest 和 Vue Test Utils:

      $ npm install --save-dev jest @vue/test-utils

      然后在 package.json 中定义一个单元测试的脚本。

      // package.json
      {
        "scripts": {
          "test": "jest"
        }
      }

       2. 在 Jest 中处理单文件组件

         安装和配置 vue-jest 预处理器(告诉 Jest 如何处理 *.vue 文件):

      npm install --save-dev vue-jest

      接下来在 package.json 中创建一个 jest 块:

      {
        // ...
        "jest": {
          "moduleFileExtensions": [
            "js",
            "json",
            // 告诉 Jest 处理 `*.vue` 文件
            "vue"
          ],
          "transform": {
            // 用 `vue-jest` 处理 `*.vue` 文件
            ".*\.(vue)$": "vue-jest"
          }
        }
      }

     注意:vue-jest 目前并不支持 vue-loader 所有的功能,比如自定义块和样式加载。还有,诸如代码分隔等webpack 特有的功能也是不支持的。如果要使用这些不支持的特性,需要用 Mocha + webpack 来进行测试。

       3. 处理-webpack-别名

      如果你在 webpack 中配置了别名解析,比如把 @ 设置为 /src 的别名,那么你也需要用 moduleNameMapper 选项为 Jest 增加一个匹配配置:

      {
        // ...
        "jest": {
          // ...
          // 支持源代码中相同的 `@` -> `src` 别名
          "moduleNameMapper": {
            "^@/(.*)$": "<rootDir>/src/$1"
          }
        }
      }

       4. 为 Jest 配置 Babel

      安装 babel-jest(在测试中使用ES6特性):

      npm install --save-dev babel-jest

      接下来,在 package.json 的 jest.transform 里添加一个入口,来告诉 Jest 用 babel-jest处理 JavaScript 测试文件:

      {
        // ...
        "jest": {
          // ...
          "transform": {
            // ...
            // 用 `babel-jest` 处理 js
            "^.+\.js$": "<rootDir>/node_modules/babel-jest"
          }
          // ...
        }
      }

      注意:默认情况下,babel-jest 会在其安装完毕后自动进行配置。但也需要再次配置 babel-jest。

      • 开启babel-preset-env,同时告诉 babel-preset-env 面向我们使用的 Node 版本。

      • 为了仅在测试时应用这些选项,把它们放到一个独立的 env.test 配置项中 。

      .babelrc 文件示例:

      {
        "presets": [["env", { "modules": false }]],
        "env": {
          "test": {
            "presets": [["env", { "targets": { "node": "current" } }]]
          }
        }
      }

       5. 放置测试文件

      Jest 推荐在被测试代码的所在目录下创建一个 tests 目录,也可以为测试文件随意设计自己习惯的文件结构。

       6. 测试覆盖率

      Jest 可以被用来生成多种格式的测试覆盖率报告。

      扩展你的 jest 配置 (通常在 package.json 或 jest.config.js 中) 的 collectCoverage 选项,然后添加 collectCoverageFrom 数组来定义需要收集测试覆盖率信息的文件。

      {
        "jest": {
          // ...
          "collectCoverage": true,
          "collectCoverageFrom": ["**/*.{js,vue}", "!**/node_modules/**"]
        }
      }

      这样就会开启默认格式的测试覆盖率报告。可以通过 coverageReporters 选项来定制它们。

    {
      "jest": {
        // ...
        "coverageReporters": ["html", "text-summary"]
      }
    }

       7. 测试规范示例

      import { mount } from '@vue/test-utils'
      import Component from './component'
    ​
      describe('Component', () => {
        test('is a Vue instance', () => {
          const wrapper = mount(Component)
          expect(wrapper.isVueInstance()).toBeTruthy()
        })
      })

     

    用 Mocha 和 webpack 测试单文件组件

      通过 webpack 编译所有的测试文件然后在测试运行器中运行。好处是支持 webpack 和 vue-loader 所有的功能。

       1. 设置 mocha-webpack

      首先要做的是安装测试依赖:

      npm install --save-dev @vue/test-utils mocha mocha-webpack

      接下来我们需要在 package.json 中定义一个测试脚本。

      // package.json
      {
        "scripts": {
          "test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
        }
      }
    • --webpack-config 标识指定了该测试使用的 webpack 配置文件。

    • --require 标识确保了文件 test/setup.js 会在任何测试之前运行,在该文件中设置测试所需的全局环境。

    • 最后一个参数是该测试包所涵盖的所有测试文件的聚合。

       2. 提取 webpack 配置

       暴露 NPM 依赖

         通过 webpack-node-externals 外置所有的 NPM 依赖:

      // webpack.config.js
      const nodeExternals = require('webpack-node-externals')
    ​
      module.exports = {
        // ...
        externals: [nodeExternals()]
      }

      源码表

        源码表在 mocha-webpack 中需要通过内联的方式获取。推荐配置为:

      module.exports = {
        // ...
        devtool: 'inline-cheap-module-source-map'
      }

      IDE 中调试需要添加的配置:

      module.exports = {
        // ...
        output: {
          // ...
          // 在源码表中使用绝对路径 (对于在 IDE 中调试时很重要)
          devtoolModuleFilenameTemplate: '[absolute-resource-path]',
          devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
        }
      }

       3.设置浏览器环境

      Vue Test Utils 需要在浏览器环境中运行。可以在 Node 中使用 jsdom-global 进行模拟:

      npm install --save-dev jsdom jsdom-global

      然后在 test/setup.js 中写入:

      require('jsdom-global')()

      这行代码会在 Node 中添加一个浏览器环境,这样 Vue Test Utils 就可以正确运行了。

       4. 选用一个断言库

      Chai 是一个流行的断言库,经常和 Mocha 配合使用。

      使用 expect 且令其全局可用,这样我们就不需要在每个测试文件里导入它了:

      npm install --save-dev expect

      然后在 test/setup.js 中编写:

      require('jsdom-global')()
    ​
      global.expect = require('expect')

      测试规范示例

      import { shallowMount } from '@vue/test-utils'
      import Counter from '../src/Counter.vue'
    ​
      describe('Counter.vue', () => {
        it('increments count when button is clicked', () => {
          const wrapper = shallowMount(Counter)
          wrapper.find('button').trigger('click')
          expect(wrapper.find('div').text()).toMatch('1')
        })
      })

     

    Mock / Stub

      在做单元测试的时候,要测试的方法需要引用很多外部依赖的对象,比如:(发送邮件,网络通讯,记录Log, 文件系统之类的)。 而我们没法控制这些外部依赖的对象。为了解决这个问题,需要用到 Stub 和 Mock 来模拟这些外部依赖的对象,从而控制它们。

    • Stubs : 通常用于在测试中提供封装好的响应,譬如有时候编程设定的并不会对所有的调用都进行响应。Stubs也会记录下调用的记录,它可以用来记录所有发送的信息或者它发送的信息的数目。(真实对象)

    • Mocks : 针对设定好的调用方法与需要响应的参数封装出合适的对象。(模拟对象)

     stub 使用的状态验证而 mock 使用的是行为验证。如果要基于stub编写状态验证的方法,需要写一些额外的代码来进行验证。而Mock对象用的是行为验证,并不需要写太多的额外代码。

  • 相关阅读:
    leetcode 18 4Sum
    leetcode 71 Simplify Path
    leetcode 10 Regular Expression Matching
    leetcode 30 Substring with Concatenation of All Words
    leetcode 355 Design Twitte
    leetcode LRU Cache
    leetcode 3Sum
    leetcode Letter Combinations of a Phone Number
    leetcode Remove Nth Node From End of List
    leetcode Valid Parentheses
  • 原文地址:https://www.cnblogs.com/yaokai729/p/11468537.html
Copyright © 2011-2022 走看看