Karma入门

作者: 宁静的夜 | 来源:发表于2017-05-10 21:56 被阅读1618次

    最近学习Vue框架,想尝试编写Vue单元测试时,发现官方推荐了这个工具。自己也是新入坑,下面的内容可能存在错误,还请斧正。

    本文中的例子代码下载

    什么是Karma

    网上搜索一番后,了解到Karma就是一个测试运行器。个人理解就是把我们测试过程中编写的测试用例,通过它调用浏览器来运行这些测试用例,然后再汇集测试结果,生成测试报告。

    安装

    Karma依赖NodeJsNPM包管理工具,安装前建议先将这两个工具升级到最新版本。如果需要使用多个版本的NodeJs,建议使用NVM来管理NodeJs版本。

    首先新建一个目录来执行整个过程

    $ mkdir karma-intro
    
    $ cd karma-intro
    

    如无特殊说明,下面的所有命令都是在karma-intro根目录下执行的。

    安装karma(强烈建议使用yarn代替npm安装包,速度真的快很多)

    $ yarn add karma
    

    运行 karma

    $ node_modules/.bin/karma start
    

    每次启动karma如果都输入node_modules/.bin/karma这么长一串的话,肯定会很不爽。可以通过全局安装karma-cli

    $ yarn global add karma-cli
    

    现在,我们便可以在命令行里直接调用karma命令了,它会自动调用项目里的karma版本。

    $ karma start
    

    配置

    安装好Karma之后,我们需要配置它来使用,直接运行命令karma init可以开启配置向导。根据自己的需要配置。通过tab键可以看到每个问题的答案选项

    $ karma init
    # 选择测试框架,这里我选择mocha
    Which testing framework do you want to use ?
    Press tab to list possible options. Enter to move to the next question.
    > mocha
    
    # 是否引入Require.js,不需要
    Do you want to use Require.js ?
    This will add Require.js plugin.
    Press tab to list possible options. Enter to move to the next question.
    > no
    
    # 选择使用的浏览器,可以使用无头浏览器PhantomJS,不过需要单独安装PhantomJS
    # 这里也可以选择多个浏览器,测试用例将在多个浏览器里执行
    # 这里我只选择了Chrome
    Do you want to capture any browsers automatically ?
    Press tab to list possible options. Enter empty string to move to the next question.
    > Chrome
    >
    
    # 告诉需要执行的测试用例的代码路径,支持正则
    What is the location of your source and test files ?
    You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
    Enter empty string to move to the next question.
    > test/*.js
    10 05 2017 15:00:08.723:WARN [init]: There is no file matching this pattern.
    
    >
    
    # 上面指定的路径中需要排除在外的文件
    Should any of the files included by the previous patterns be excluded ?
    You can use glob patterns, eg. "**/*.swp".
    Enter empty string to move to the next question.
    >
    
    # 是否观察文件的变化
    Do you want Karma to watch all the files and run the tests on change ?
    Press tab to list possible options.
    > yes
    
    
    Config file generated at "/Users/linliang/Src/frontend/karma-intro/karma.conf.js".
    

    命令运行完成后,我们可以看到在当前目录下生成了karma.conf.js文件。同时,根据我们的配置情况,package.json里也多了一些依赖项。如我的package.json里,就多了

      "devDependencies": {
        "karma-chrome-launcher": "^2.1.1",
        "karma-mocha": "^1.3.0"
      }
    

    因为我们选择的是使用mocha框架和chrome,所以自动添加了这两个Karma插件。

    安装新增加的插件

    # 自动安装新添加到依赖里的karma插件
    $ yarn
    
    # 安装mocha框架
    $ yarn add mocha
    

    编写第一个测试用例

    基本的配置文件和依赖都准备就绪后,让我们来尝试编写第一个测试用例。创建

    test/hello.js

    describe('A spec suite', function() {
        it('contains a passing spec', function() {
            console.log("Hello Karma");
        });
    });
    

    测试用例的内容很简单,就是打印一个Hello Karma信息。

    注意: 这里的测试用例文件保存路径就是在我们初始化配置文件时指定的

    # 告诉需要执行的测试用例的代码路径,支持正则
    What is the location of your source and test files ?
    You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
    Enter empty string to move to the next question.
    > test/*.js
    10 05 2017 15:00:08.723:WARN [init]: There is no file matching this pattern.
    

    因此测试用例的保存位置必须满足上面的配置,不然的话Karma会找不到测试文件。
    当然,也可以手动修改karma.conf.js文件的files部分来指定。

    // list of files / patterns to load in the browser
    files: [
      'test/*.js'
    ],
    

    如果你的配置文件和我不一样,那么测试用例的文件的保存位置也要做相应的改动。

    运行测试用例

    浏览器上运行测试用例

    为了运行测试用例,我们需要先运行Karma

    $ karma start
    10 05 2017 15:37:19.619:INFO [karma]: Karma v1.7.0 server started at http://0.0.0.0:9876/
    10 05 2017 15:37:19.623:INFO [launcher]: Launching browser Chrome with unlimited concurrency
    10 05 2017 15:37:19.632:INFO [launcher]: Starting browser Chrome
    10 05 2017 15:37:21.287:INFO [Chrome 57.0.2987 (Mac OS X 10.12.4)]: Connected on socket 5ojH0YX9XIbllG7TAAAA with id 51036312
    

    可以看到它会打开Chrome浏览器,并自动打开了如下图的页面


    Karma主页

    我们点击页面绿色条右侧的DEBUG按钮,同时打开浏览器的控制台,就可以看到测试用例已经执行

    Karma测试页

    从上图可以看到,浏览器运行了hello.js文件,输出了结果

    命令行运行测试用例

    上面运行测试用例感觉有点麻烦,有没有简单点的方法呢?答案是有的,保留运行karma start命令的窗口不关闭,新打开一个窗口直接执行命令

    $ karma run
    LOG: 'Hello Karma'
    Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.01 secs / 0.001 secs)
    

    运行特定的测试用例

    karma run默认情况下会一次运行所有找到的测试用例,当我们的测试用例越来越多时,有时候为了方便测试,我们可能需要运行特定的测试用例,那该怎么办呢?

    $ karma run -- --grep 'A spec suite'
    

    上面命令中第一个--表示后面的选项--grep 'A spec suite'是传递给测试框架的选项,我们这里就是指mocha
    相当于执行

    $ mocha --grep 'A spec suite'`
    

    表示只运行匹配特定字符串A spec suite的测试用例。

    ES6转换

    现在基本都流行用ES6语法,但是目前的浏览器对ES6语法的支持并不全,为了兼容性,我们一般会用Babel把ES6语法转换成ES5,以便浏览器能够兼容。那么我们的Karma运行的测试用例怎么调用Babel做语法转换呢?

    让我们创建一个使用了ES6箭头函数的测试用例

    test/es6.js

    describe('ES6 spec', function() {
        it('es6 arrows feature ', function() {
             var add = (x, y) => x + y
             console.log(add(3,1))
        });
    });
    

    运行该测试用例

    $ karma run -- --grep 'ES6 spec'
    LOG: 4
    Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.009 secs / 0.002 secs)
    

    再打开浏览器,运行测试用例,我们可以看到浏览器里运行的es6.js文件。

    es6.js

    由于现在的Chrome浏览器已经支持90%的ES6的语法特性,所以这个测试用例能运行成功,没有问题。但是如果浏览器不支持,那么这个测试用例就会运行失败。

    PS
    本来想找一个Chrome不支持的ES6特性来做例子,可是发现好像除了importexport外,其它的ES6特性Chrome都支持了。而importexport又涉及到打包构建的问题(后面会提到),所以这里只好选择箭头函数这个例子将就看了。

    现在,让我们假设Chrome浏览器不支持箭头函数,那我们来看该如何配置,让Karma自动把es6.js文件转换成浏览器支持的语法再去调用浏览器。首先,安装下面的包

    $ yarn add karma-babel-preprocessor
    
    $ yarn add babel-preset-env
    

    创建.babelrc,配置babel的预转换格式,

    .babelrc

    {
      "presets": ["env"]
    }
    

    修改karma.conf.js,编辑preprocessors部分,让所有的js文件都先用babel转换一下。

    preprocessors: {
        "test/*.js": ['babel']
    },
    

    配置好之后,我们再用浏览器里查看运行的es6.js文件,可以看到箭头函数已经转换成了ES5的写法

    es6.js转换后

    集成webpack

    现在,让我们看看下面的测试用例,引入了第三方库lodash

    test/use_lodash.js

    import _ from 'lodash'
    describe('Use lodash suite', function() {
        it('fill array', function() {
            var array = [1, 2, 3]
            _.fill(array, 'a')
            console.log(array)
        });
    });
    

    运行该测试用例

    $ karma run -- --grep 'lodash'
    Chrome 57.0.2987 (Mac OS X 10.12.4) ERROR
      Uncaught ReferenceError: require is not defined
      at test/use_lodash.js:3
    

    查看浏览器运行的use_lodash.js文件,我们可以看到它被转换成了

    'use strict';
    
    var _lodash = require('lodash');
    
    var _lodash2 = _interopRequireDefault(_lodash);
    
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
    
    describe('Use lodash suite', function () {
        it('fill array', function () {
            var array = [1, 2, 3];
            _lodash2.default.fill(array, 'a');
            console.log(array);
        });
    });
    

    虽然已经转换成了ES5语法,但是由于引入了第三方库lodash,浏览器是没法识别require指令的。

    因此我们需要使用打包工具webpack来将第三库一起打包出来,让浏览器可以运行。关于webpack的使用,可以参考我之前写的《webpack使用入门》。

    这里主要讲怎么让karma使用webpack,首先我们需要安装

    $ yarn add webpack
    
    $ yarn add karma-webpack
    

    然后,修改karma.conf.js, 同样修改preprocessors部分,添加webpack

    preprocessors: {
        "test/*.js": ['babel', 'webpack']
    },
    

    运行

    $ karma run -- --grep 'lodash'
    LOG: ['a', 'a', 'a']
    Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.01 secs / 0.002 secs)
    

    配置webpack

    我们也可以对webpack进行配置,如我们前面对Karma调用babel的功能,也完全可以在webpack里面配置,交给webpack来处理。只需要在karma.conf.js添加webpack选项即可进行配置。详情可以参考Karma webpack

    更多关于Karma的配置,可以参考

    相关文章

      网友评论

        本文标题:Karma入门

        本文链接:https://www.haomeiwen.com/subject/mxcntxtx.html