写点什么

前端自动化测试及 Karma 介绍

用户头像
devpoint
关注
发布于: 2 小时前
前端自动化测试及 Karma 介绍

在前端开发中,大部分时间都是使用人肉加上 console.log 或者 debuger 进行测试,效率及测试质量都是因人而异,加上 JavaScript 语言本身缺少类型检查,编译期间无法定位到错误,还有常见兼容性问题,都是影响前端开发常见问题。为提高开发效率,减少或者避免人工干预,就需要编写测试用例进行自动化测试。在文章《JavaScript单元测试的“抹茶”组合:Mocha和Chai》介绍了 JavaScript 的单元测试,本文再来介绍一下自动化测试及工具 Karma。


Karma 为前端自动化测试提供了跨浏览器测试的能力,它集成了像 Jasmine(基于 BDD 的测试框架),PhantomJS(无界面的浏览器) 这些测试套件。还有一些其他有用的功能,比如生成代码覆盖率的报告等。


  • TDD(Test Drivin Development) 是测试驱动开发,强调的是一种开发方式,以测试来驱动整个项目,即先根据接口完成测试编写,然后在完成功能时要不断通过测试,最终目的是通过所有测试。

  • BDD(Behavior Drivin Development) 行为驱动开发,可以理解为是 TDD 的分支,即也是测试驱动,但 BDD 强调的是写测试的风格,即测试要写得像自然语言,运用一些比如 expectshould 等跟自然语言相近的断言,让项目的各个成员甚至产品都能看懂测试,甚至编写测试。

简介

Karma - Spectacular Test Runner for Javascript(基于 node.js 的 Javascript 测试运行环境)


Karma 是由 Google 团队开发的一套前端测试运行框架,karma 会启动一个 web 服务器,将 js 源代码和测试脚本放到 PhantomJS 或者 Chrome 上执行。


On the AngularJS team, we rely on testing and we always seek better tools to make our life easier. That's why we created Karma - a test runner that fits all our needs.


该工具可用于测试所有主流 Web 浏览器,也可集成到 CI 工具,也可和其他代码编辑器(例如 VsCode)一起使用。这个测试工具的一个强大特性就是,它可以监控(Watch)文件的变化,然后自行执行,通过 console.log 显示测试结果。主要提供以下功能:


  • 提供真实环境,可以配置各种 chrome、firefox 等各种浏览器环境或者 Phantomjs 等无头浏览器环境

  • 可控制自动化测试流程,比如编辑器保存时自动全部全部测试用例

  • 强大适配器,可以在 karma 上面配置 jasminemocha等单元测试框架。

  • 配置方便

安装

npm install karma -g
复制代码

测试框架

Jasmine(基于 TDD 的测试框架)

jasmine 是一个行为驱动开发(BDD)测试框架, 一个 JavaScript 测试框架,它不依赖于浏览器、dom 或其它 JavaScript 框架,其语法十分简单。

分组 describe()

describe 的用于群组相关的测试,接受两个参数:stringfunction


  • string 是这个测试套件的标题

  • function 就是实现这个测试套件。可以嵌套多个 Distribution


describe("a suite", function () {    //这是一个测试分组    it("with an expactation", function () {        expect(true).toBe(true);    });    //可以添加多个测试});
复制代码
测试 it()

it 代表具体的测试,当其中所有的断言都为 true 时,则该测试通过;否则测试失败


describe("a suit is just a function", function () {    var a = 10;    it("and here is a test", function () {        var a = true;        expect(a).toBe(true);    });});
复制代码
期望 expect()

通过链式 Matcher 方法来比较实际值是否和预期值一致,如果一致就是测试通过。


desribe('the "toBe" matcher compares with "===" ', function () {    it("positive expect", function () {        expect(true).toBe(true);    });
it("negative expect", function () { expect(false).not.toBe(true); });});
复制代码
Matchers

都是作为期望的链式调用而使用,用于比较期望值和实际值。其中可以使用 not 进行期望结果的否定。


每个匹配方法在期望值和实际值之间执行逻辑比较,它负责告诉 jasmine 断言的真假,从而决定测试的成功或失败。


  • 肯定断言 expect(true).toBe(true);

  • 否定断言 expect(false).not.toBe(true);


jasmine 有很丰富的匹配方法,而且可以自定义匹配方法。 内置的匹配方法有:


  • toBe()


describe("included matchers", function () {    it('"toBe" matcher compares width === ', function () {        const a = 12;        const b = a;        expect(a).toBe(b);        expect(a).not.toBe(null);    });});
复制代码


  • toEqual()


describe("'toEqual' matcher", function () {    it("适合简单的文本和变量", function () {        const a = 12;        expect(a).toEqual(12);    });
it("也适用于对象的深度比较", function () { const foo = { a: 12, b: 34, }; const bar = { a: 12, b: 34, }; expect(foo).toEqual(bar); });});
复制代码


  • toMatch()


it("'toMatch' matcher 是使用正则表达式", function () {    const message = "foo bar baz";
expect(message).toMatch(/bar/); expect(message).toMatch("bar"); expect(message).not.toMatch(/quux/);});
复制代码


  • toBeDefined()


it("'toBeDefined' matcher 是将期望和undefined进行比较", function () {    const a = {        foo: "foo",    };
expect(a.foo).toBeDefined(); expect(a.bar).not.toBeDefined();});
复制代码


  • toBeNull()


it("'toBeNull' matcher 是将期望和null进行比较", function () {    const a = null;    const foo = "foo";
expect(null).toBeNull(); expect(a).toBeNull(); expect(foo).not.toBeNull();});
复制代码


  • toBeTruthy()


it("'toBeTruthy' matcher 是进行Boolean转换后与true进行比较", function () {    const a,        foo = "foo";
expect(foo).toBeTruthy(); expect(a).not.toBeTruthy();});
复制代码


  • toContain()


describe("'toContain' matcher", function () {    it("适用于数组的寻值", function () {        const a = ["foo", "bar", "baz"];
expect(a).toContain("bar"); expect(a).not.toContain("quux"); });
it("也使用于字符串内找单词", function () { const a = "foo bar baz";
expect(a).toContain("bar"); expect(a).not.toContain("quux"); });});
复制代码


  • toBeLessThan()


it("'toBeLessThan' matcher 进行小于的数值期望比较", function () {const pi = 3.1415926,e = 2.78;


expect(e).toBeLessThan(pi);expect(pi).not.toBeLessThan(e);
复制代码


});


  • toThrowError()


it("'toThrowError' matcher 用于测试特定抛出异常", function () {    const foo = function () {        throw new TypeError("foo bar baz");    };
expect(foo).toThrowError("foo bar baz"); expect(foo).toThrowError(/bar/); expect(foo).toThrowError(TypeError); expect(foo).toThrowError(TypeError, "foo bar baz");});
复制代码

PhantomJS(无界面的浏览器)

PhantomJS 是由 Ariya Hidayat 创建的,支持 JavaScript API 的无界面、运行在服务端的 WebKit 环境。


  • 无界面网站测试

  • 屏幕快照

  • 页面操作自动化

  • 网络监控

基于 Jasmine 实例

要使用 Karma 对代码进行单元测试,首先需要安装一系列的相关插件。新建一个名为 karm-test 的目录,并安装相关的插件:


npm install karma jasmine-core karma-jasmine karma-phantomjs-launcher -D
复制代码


接下来对工程进行初始化:


karma init
复制代码


之后会弹出一些选项,其中包含了一些初始化的配置工作,使用上下方向键可以在配置项之间进行切换。


初始化完成之后,会在项目中生成一个 karma.conf.js 文件,这个文件就是 Karma 的配置文件。配置文件比较简单,能够比较轻松的看懂,这里对原始的配置文件进行简单的修改,结果如下:


module.exports = function (config) {    config.set({        // base path that will be used to resolve all patterns (eg. files, exclude)        basePath: "",
// frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ["jasmine"],
// list of files / patterns to load in the browser files: ["./src/**/*.js", "./test/**/*.spec.js"],
// list of files to exclude exclude: [],
// preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: {},
// test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ["progress"],
// web server port port: 9876,
// enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes autoWatch: false,
// start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ["PhantomJS"],
// Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: true,
// Concurrency level // how many browser should be started simultaneous concurrency: Infinity, });};
复制代码


然后创建一个 src 目录和一个 test 目录,在其中分别创建 index.js index.spec.js 文件。要做的测试内容比较简单,对 index.js 中的两个函数(一个加法函数,一个乘法函数)进行测试。


src/index.js 文件如下:


// 加法函数function add(x){    return function(y){        return x + y;    }}// 乘法函数function multi(x){    return function(y){        return x * y + 1;    }}
复制代码


test/index.spec.js 文件如下:


describe("运算功能单元测试",function(){    it("加法函数测试",function(){        const add5 = add(5)        expect(add5(5)).toBe(10)    });
it("乘法函数测试",function(){ const multi5 = multi(5) expect(multi5(5)).toBe(25) })})
复制代码


单测的代码写好后,就可以使用 karma start 来运行单元测试。由于乘法代码中有错误,因此测试结果是这样的:



将乘法函数的代码改为正常,再次启用 karma start 进行测试:


希望能够对你有所帮助,谢谢。

发布于: 2 小时前阅读数: 2
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

专注前端开发,用技术创造价值!

评论

发布
暂无评论
前端自动化测试及 Karma 介绍