基于React项目下的组件单元测试 - Go语言中文社区

基于React项目下的组件单元测试


什么是单元测试?

一般测试分成几个类型:单元测试、集成测试、功能测试。集成测试和功能测试不赘述。单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作,这里的单元是程序工作的最小工作单位。单元测试应该仅仅依赖输入,不依赖多余的环境,如果你的单元测试依赖很多环境,那么你可能需要的是集成测试。

单元测试又可以根据开发模式分成以下两类:

TDD, TDD指的是Test Drive Development,很明显的意思是测试驱动开发,也就是说我们可以从测试的角度来检验整个项目。大概的流程是先针对每个功能点抽象出接口代码,然后编写单元测试代码,接下来实现接口,运行单元测试代码,循环此过程,直到整个单元测试都通过。
BDD指的是Behavior Drive Development,也就是行为驱动开发。行为驱动开发是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作。主要是从用户的需求出发,强调系统行为。BDD最初是由Dan North在2003年命名,它包括验收测试和客户测试驱动等的极限编程的实践,作为对测试驱动开发的回应。
目前我接触到的项目都是BDD,国内的前端项目对单元测试重视程度没有那么高,TDD这种先编写单元测试的模式应用并不多。

但是但是,我真的想说,高覆盖率的单元测试,可以保证每次上线bug率大大降低,也是代码重构的基础。很多老项目,开发人员离职、新接手的人员不敢重构,慢慢称为团队负担、又不能下线,就是因为没有单元测试,改一点都怕出现不可测的bug。

单元测试框架选择

1.测试用例在node环境下运行,不依赖于浏览器,建议选用Jest + Enzyme

Jest 是 Facebook 发布的一个开源的、基于 Jasmine 框架的 JavaScript 单元测试工具。提供了包括内置的测试环境 DOM API 支持、断言库、Mock 库等,还包含了 Spapshot Testing、 Instant Feedback 等特性。

Enzyme是Airbnb开源的 React 测试类库,提供了一套简洁强大的 API,并通过 jQuery 风格的方式进行DOM 处理,开发体验十分友好。不仅在开源社区有超高人气,同时也获得了React 官方的推荐。

2.测试用例依赖于浏览器环境,建议选用Karma + Jasmine + Enzyme

Karma 是一个用来搜索测试文件、编译它们然后运行断言的测试器,Angular团队作品。

Jasmine 是一个断言库,它仅仅问“我们得到我们期待的东西了么?”。它提供类似describe,expect 和 it的函数,也提供监听一个函数或方法有没有被触发的监听器。

我这里选用的是node环境下的Jset + Enzyme进行的前端组件测试用例的开发和使用

环境数据

  • nodejs v8.16.0
  • npm 6.4.1
  • 依赖版本
    "@babel/core": "^7.9.0",
    "@babel/plugin-transform-runtime": "^7.9.0",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.9.4",
    "babel-loader": "^8.0.5",
    "jest": "^25.1.0",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "chai": "^4.2.0",
    

执行及结果

Demo.test.jsx示例代码

在这里插入图片描述

执行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MR6HrOSa-1585295902034)(quiver-image-url/8F7701A9849A10F4230A4809F945FF83.jpg =686x191)]

问题总结

1. Plugin/Preset files are not allowed to export objects,only functions.

  • 原因:babel版本冲突不兼容的问题
  • 解决方案:
    • 升级babel到babel7.0
      • 将所有有关babel的包都升级为7.0版本
        "@babel/core": "^7.2.2",
        "@babel/preset-env": "^7.3.1",
        "@babel/preset-react": "^7.0.0",
        "babel-loader": "^8.0.5",
        
      • 并且修改.babel文件
        { "presets":["@babel/react","@babel/env",]}
        
    • 降级到babel6.0版本
      "babel-core": "^6.26.3",
      "babel-preset-env": "^1.7.0",
      "babel-preset-react": "^6.24.1",
      "babel-loader": "^7.1.5",
      
      • 对应修改.babelrc文件
      { "presets": ["react", "env"]}
      

这里我选择的是升级babel到babel7.0

我当前的项目中在结合babel升级过程中遇到的问题进行了总结,解决的具体问题以及方案,在Error: Requires Babel “^7.0.0-0”, but was loaded with “6.26.3”. If you are sure you have a compatible version of @babel/core, #11337, 整理如下:

  • babel-upgrade插件安装
    # npx lets you run babel-upgrade without installing it locally 
    npx babel-upgrade --write
    # or install globally and run 
    npm install babel-upgrade -g
    babel-upgrade --write
    

这个安装完成之后,package.json文件依赖已经更新,而且按照新版的babel7.+的内容结合你本地的.babelrc已存在的内容进行了更新。

  • install && run
    npm install
    npm start
    

在npm run start的时候,遇到了一个棘手的问题,

ERROR in ./client/index.jsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: [BABEL] /Users/resource/BeiKe/pikachu-static-front-owner/client/index.jsx: The 'polyfill' option has been removed. Use the 'corejs'option to polyfill with `core-js` via @babel/runtime. (While processing: "/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/plugin-transform-runtime/lib/index.js")
    at _default (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/plugin-transform-runtime/lib/index.js:144:13)
    at /Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/helper-plugin-utils/lib/index.js:19:12
    at /Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/core/lib/config/full.js:199:14
    at Generator.next (<anonymous>)
    at Function.<anonymous> (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/core/lib/gensync-utils/async.js:26:3)
    at Generator.next (<anonymous>)
    at step (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/gensync/index.js:254:32)
    at evaluateAsync (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/gensync/index.js:284:5)
    at Function.errback (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/gensync/index.js:108:7)
    at errback (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/core/lib/gensync-utils/async.js:70:18)
    at async (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/gensync/index.js:183:31)
    at onFirstPause (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/gensync/index.js:209:13)
    at Generator.next (<anonymous>)
    at cachedFunction (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/core/lib/config/caching.js:68:46)
    at cachedFunction.next (<anonymous>)
    at loadPluginDescriptor (/Users/resource/BeiKe/pikachu-static-front-owner/node_modules/@babel/core/lib/config/full.js:235:43)
ℹ 「wdm」: Failed to compile.

编译失败!原因是.babelrc中的两个corejs冲突了。corejs3.0+对应的是babel7.0+的版本。

Remove the polyfill option from @babel/plugin-transform-runtime.
移除前我的.babelrc:

{
  "presets": [
    "@babel/preset-react",
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": {
          "chrome": 48,
          "ie": 9,
          "browsers": [
            "> 1%",
            "last 5 versions"
          ]
        }
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 2,
        "helpers": true,
        "polyfill": true,
        "regenerator": true,
        "moduleName": "babel-runtime"
      }
    ],
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-object-rest-spread"
  ]
}

移除后我的.babelrc:

{
  "presets": [
    "@babel/preset-react",
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": {
          "chrome": 48,
          "ie": 9,
          "browsers": [
            "> 1%",
            "last 5 versions"
          ]
        }
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-object-rest-spread"
  ]
}

然后npm run start,正常运行。

重新jest
在这里插入图片描述

参考:https://www.npmjs.com/package/babel-upgrade

2.当组件中引入了图片或者css文件,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ns8BcwyF-1585295902040)(quiver-image-url/C1664B6CD073AF290832F1AA255887CE.jpg =618x139)]
在这里插入图片描述

3.npm包提供的module格式问题

 FAIL  test/product.test.jsx
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/resource/BeiKe/pikachu-static-front-owner/node_modules/glue-redux/es/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import _defineProperty from 'babel-runtime/helpers/defineProperty';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      1 | 
      2 |
    > 3 | import { createGlue, gluePair } from 'glue-redux';
        | ^
      4 | import confirmLoan from './confirmLoan';
      5 | import Certification from './certification';
      6 |

      at Runtime.createScriptFromCode (../../.nvm/versions/node/v8.16.0/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:1059:14)
      at Object.<anonymous> (client/glue/glue.js:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        9.061s
Ran all test suites.
  • 原因:是glue-redux旧版本在包的导出格式有问题。
  • 解决方案:
    • 修改glue-redux的文件指向cj模块:
      import { createGlue, gluePair } from 'glue-redux';
      
      修改为:
      import { createGlue, gluePair } from 'glue-redux/cj';
      
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_21895821/article/details/105143495
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢