前端自动化测试及 Karma 介绍

简介: 在前端开发中,大部分时间都是使用人肉加上 console.log 或者 debuger 进行测试,效率及测试质量都是因人而异,加上JavaScript语言本身缺少类型检查,编译期间无法定位到错误,还有常见兼容性问题,都是影响前端开发常见问题。

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

image.png

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

image.png

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


相关文章
|
2天前
|
测试技术 持续交付
探索软件测试中的自动化测试策略
随着软件开发周期的加速和市场需求的不断增长,传统的手动软件测试方法已难以满足现代软件开发的高效性和准确性要求。本文旨在探讨自动化测试在软件测试中的重要性、实施策略及其对提高软件质量的影响。通过分析自动化测试的优势与挑战,以及提供实用的自动化测试工具和框架选择指南,旨在帮助读者理解并应用自动化测试以提升软件开发效率和产品质量。
|
14天前
|
敏捷开发 测试技术 持续交付
探索软件测试中的自动化与持续集成
在快速迭代的软件开发环境中,自动化测试和持续集成(CI)已成为确保产品质量和加速交付的关键策略。本文将深入探讨自动化测试的基本原理、实施步骤以及它如何与持续集成流程相结合,以提高软件开发的效率和可靠性。我们将通过实际案例分析,展示自动化测试和CI的最佳实践,以及它们如何帮助企业实现更快的市场响应时间和更高的客户满意度。
55 16
|
16天前
|
jenkins 测试技术 持续交付
软件测试中的自动化与持续集成:提升效率与质量的关键
在快节奏的软件开发环境中,自动化测试和持续集成已经成为不可或缺的部分。本文将探讨自动化测试和持续集成的重要性,以及它们如何协同工作以提高软件开发的效率和质量。通过分析自动化测试的策略、工具选择以及持续集成的实践,我们将揭示这些技术如何帮助开发团队快速响应变化,减少错误,并加速产品上市时间。
|
15天前
|
人工智能 前端开发 测试技术
探索软件测试中的自动化框架选择与优化策略####
本文深入剖析了当前主流的自动化测试框架,通过对比分析各自的优势、局限性及适用场景,为读者提供了一套系统性的选择与优化指南。文章首先概述了自动化测试的重要性及其在软件开发生命周期中的位置,接着逐一探讨了Selenium、Appium、Cypress等热门框架的特点,并通过实际案例展示了如何根据项目需求灵活选用与配置框架,以提升测试效率和质量。最后,文章还分享了若干最佳实践和未来趋势预测,旨在帮助测试工程师更好地应对复杂多变的测试环境。 ####
40 4
|
15天前
|
机器学习/深度学习 人工智能 jenkins
软件测试中的自动化与持续集成实践
在快速迭代的软件开发过程中,自动化测试和持续集成(CI)是确保代码质量和加速产品上市的关键。本文探讨了自动化测试的重要性、常见的自动化测试工具以及如何将自动化测试整合到持续集成流程中,以提高软件测试的效率和可靠性。通过案例分析,展示了自动化测试和持续集成在实际项目中的应用效果,并提供了实施建议。
|
17天前
|
前端开发 JavaScript 测试技术
前端测试技术中,如何提高集成测试的效率?
前端测试技术中,如何提高集成测试的效率?
|
21天前
|
机器学习/深度学习 前端开发 测试技术
探索软件测试中的自动化测试框架选择与优化策略####
本文深入探讨了在当前软件开发生命周期中,自动化测试框架的选择对于提升测试效率、保障产品质量的重要性。通过分析市场上主流的自动化测试工具,如Selenium、Appium、Jest等,结合具体项目需求,提出了一套系统化的选型与优化策略。文章首先概述了自动化测试的基本原理及其在现代软件开发中的角色变迁,随后详细对比了各主流框架的功能特点、适用场景及优缺点,最后基于实际案例,阐述了如何根据项目特性量身定制自动化测试解决方案,并给出了持续集成/持续部署(CI/CD)环境下的最佳实践建议。 --- ####
|
21天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
64 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
3天前
|
测试技术 持续交付 API
探索软件测试中的自动化:从新手到专家
在软件开发的世界中,测试是确保产品质量的关键步骤。本文将通过一个初学者的视角,介绍如何从零开始构建自动化测试框架,并逐步深入到更复杂的测试场景。我们将探讨自动化测试的优势、工具选择、以及如何有效地实施和扩展自动化测试策略。无论你是刚入门的软件测试新手,还是希望提升自动化测试技能的开发人员,这篇文章都将为你提供实用的指导和启示。
|
11天前
|
敏捷开发 Java 测试技术
软件测试中的自动化策略与实践
在快速迭代的软件开发周期中,自动化测试是确保产品质量和提升开发效率的关键。本文将深入探讨自动化测试的重要性,介绍实用的自动化测试框架,并通过一个具体的代码示例,说明如何实现一个简单的自动化测试脚本。
36 12