模块化开发之后,非常容易的进行单元测试。但前端单元测试因为需要浏览器支持,在操作上还是有一定的成本的。不过,目前已经有一套比较通用的做法。

在了解模块化单元测试之前,需要了解以下项目

1下载

使用 coolie demo 命令下载本 demo。

  1. coolie demo 11

2编写源代码

新建一个 coolie-demo11 目录。

任务是:写两个模块用于计算圆形和方形的面积、周长。

新建 src 目录,用于存放我们的原始模块。

  1. .
  2. ├── readme.md
  3. └── src
  4. ├── circle.js
  5. └── square.js
  6. 1 directory, 3 files

2.1circle.js

  1. /**
  2. * 计算圆的面积、周长
  3. * @author ydr.me
  4. * @create 2016-04-08 23:35
  5. */
  6. /**
  7. * 圆的面积
  8. * @param radius {Number} 半径
  9. * @returns {number}
  10. */
  11. exports.getArea = function (radius) {
  12. return Math.PI * radius * radius;
  13. };
  14. /**
  15. * 圆的周长
  16. * @param radius {Number} 半径
  17. * @returns {number}
  18. */
  19. exports.getCircumference = function (radius) {
  20. return 2 * Math.PI * radius;
  21. };

2.2square.js

  1. /**
  2. * 计算方形的面积、周长
  3. * @author ydr.me
  4. * @create 2016-04-08 23:35
  5. */
  6. /**
  7. * 方形的面积
  8. * @param width {Number} 宽
  9. * @param height {Number} 高
  10. * @returns {number}
  11. */
  12. exports.getArea = function (width, height) {
  13. return width * height;
  14. };
  15. /**
  16. * 方形的周长
  17. * @param width {Number} 宽
  18. * @param height {Number} 高
  19. * @returns {number}
  20. */
  21. exports.getCircumference = function (width, height) {
  22. return 2 * (width + height);
  23. };

3安装测试模块

新建一个 package.json

  1. {
  2. "name": "coolie-demo11",
  3. "version": "0.0.1"
  4. }

然后安装模块

  1. npm install -D karma karma-coverage karma-jasmine karma-chrome-launcher karma-coolie

初始化单元测试配置文件 karma.config.js。这里直接复制这个文件即可

  1. /**
  2. * karma 测试配置文件
  3. * @author ydr.me
  4. * @create 2016-04-20 21:15
  5. */
  6. 'use strict';
  7. module.exports = function (config) {
  8. config.set({
  9. // base path that will be used to resolve all patterns (eg. files, exclude)
  10. basePath: './',
  11. // frameworks to use
  12. // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  13. // 单元测试框架
  14. frameworks: ['jasmine', 'coolie'],
  15. client: {},
  16. // list of files / patterns to load in the browser
  17. files: [
  18. {
  19. // 加载 src 下的原始文件,但不直接引入,使用模块加载器引入
  20. pattern: './src/**',
  21. included: false
  22. },
  23. {
  24. // 加载 src 下的原始文件,但不直接引入,使用模块加载器引入
  25. pattern: './test/**',
  26. included: false
  27. },
  28. {
  29. // 加载 test 下的入口文件,但不直接引入,使用模块加载器引入
  30. pattern: './test/main.js',
  31. included: true
  32. }
  33. ],
  34. // list of files to exclude
  35. include: [],
  36. exclude: [],
  37. // preprocess matching files before serving them to the browser
  38. // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  39. preprocessors: {
  40. // 原始模块,需要测试覆盖率
  41. './src/**.js': ['coverage']
  42. },
  43. // optionally, configure the reporter
  44. // 覆盖率报告
  45. coverageReporter: {
  46. reporters: [{
  47. type: 'text-summary'
  48. }]
  49. },
  50. // test results reporter to use
  51. // possible values: 'dots', 'progress'
  52. // available reporters: https://npmjs.org/browse/keyword/karma-reporter
  53. // 报告类型
  54. reporters: ['progress', 'coverage'],
  55. // web server port
  56. port: 9876,
  57. // enable / disable colors in the output (reporters and logs)
  58. colors: true,
  59. // level of logging
  60. // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
  61. logLevel: config.LOG_INFO,
  62. // enable / disable watching file and executing tests whenever any file changes
  63. autoWatch: false,
  64. // start these browsers
  65. // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
  66. browsers: ['Chrome'],
  67. // Continuous Integration mode
  68. // if true, Karma captures browsers, runs the tests and exits
  69. singleRun: false,
  70. // Concurrency level
  71. // how many browser should be started simultaneous
  72. concurrency: Infinity,
  73. customLaunchers: {
  74. Chrome_travis_ci: {
  75. base: 'Chrome',
  76. flags: ['--no-sandbox']
  77. }
  78. },
  79. // plugins
  80. plugins: ['karma-*']
  81. });
  82. };

这个配置文件基本不需要改动,主要的地方已经用中文注释了。

4测试入口文件 test/main.js

我们需要将所有的 src 模块在这个入口模块里引入并导出。

  1. (function (__karma__, coolie) {
  2. var tests = [];
  3. for (var file in __karma__.files) {
  4. if (__karma__.files.hasOwnProperty(file)) {
  5. if (/\/test\.[^/]*\.js$/i.test(file)) {
  6. tests.push(file);
  7. }
  8. }
  9. }
  10. coolie.use(tests);
  11. coolie.callback(function () {
  12. __karma__.start.call();
  13. });
  14. })(window.__karma__, coolie);

5测试文件

5.1test/test.circle.js

  1. /**
  2. * test circle
  3. * @author ydr.me
  4. * @create 2016-04-09 00:07
  5. */
  6. var circle = require('../src/circle');
  7. describe('circle.js', function () {
  8. // 圆面积
  9. it('.getArea', function () {
  10. // 半径为 1 的圆
  11. expect(circle.getArea(1)).toEqual(Math.PI);
  12. });
  13. // 圆周长
  14. it('.getCircumference', function () {
  15. // 半径为 1 的圆
  16. expect(circle.getCircumference(1)).toEqual(2 * Math.PI);
  17. });
  18. });

5.2test/test.square.js

  1. /**
  2. * test square
  3. * @author ydr.me
  4. * @create 2016-04-09 00:07
  5. */
  6. var square = require('../src/square');
  7. describe('square.js', function () {
  8. // 方形面积
  9. it('.getArea', function () {
  10. // 边长为 1 的正方形
  11. expect(square.getArea(1, 1)).toEqual(1);
  12. });
  13. //// 方形周长
  14. //it('.getCircumference', function () {
  15. // // 边长为 1 的正方形
  16. // expect(square.getCircumference(1, 1)).toEqual(4);
  17. //});
  18. });

6单元测试

6.1webstorm 配置

单元测试(demo11) - 图6

  • 1:选择单元测试框架 karma
  • 2:填写名称“unit test”或者其他
  • 3:在下拉框里选择 karma.config.js
    保存之后就可以玩了。

单元测试(demo11) - 图7

从左到右:

  • 左:单元测试按钮
  • 中:单元测试调试模式按钮
  • 右:单元测试覆盖率测试按钮

6.2单元测试

点击单元测试按钮。启动之后会在后台自动打开浏览器。测试完成会显示结果。

单元测试(demo11) - 图8

6.3覆盖率测试

上面的test.square.js故意漏点一点代码没有被测试,来看看覆盖率是否正确。点击单元测试覆盖率测试按钮,覆盖率测试。

单元测试(demo11) - 图9

如上图:

  • 绿色:已进行覆盖率测试
  • 红色:未进行覆盖率测试

7小结

至此 11 个 demo 已经全部看完了,覆盖了传统工程(coolie-demo2)、多模块工程(coolie-demo7)、单页面工程(coolie-demo9)和复合工程(coolie-demo10),涉及到了前端的方方面面。

愿 coolie 如你所想。

原文: https://coolie.ydr.me/guide/unit-test