• JavaScript单元测试工具-Jest


    标注:

    首先这并不是一篇完整的关于Jest的教程,只是个人在接触jest学习的一点随手笔记,大部分内容都是对官方文档的一些翻译。

    ------------------------------------------------------------------------------------------------------------------------------------------

    What's Jest

    Jest是Facebook开发的一个对javascript进行单元测试的工具,之前仅在其内部使用,后开源,并且是在Jasmine测试框架上演变开发而来,使用了我们熟知的expect(value).toBe(other)这种断言格式。Jest提供零配置测试平台,即是一种即用型的工具。这将会使得工程师编写更多的测试,创建更稳定和更健康的代码库。

    Getting Start

    第一个Jest测试Demo

    通过npm安装

    $ npm install jest --save-dev
    

    编辑一个待测试的sum.js文件如下:

    function sum(a, b) {
        return a + b;
    }
    module.exports = sum;

    编辑一个测试文件sum.test.js

    注意:关于这个测试文件的位置,建议是对每个组件新建一个__test__文件夹,然后文件命名是name.test.js,用于存放测试文件。

    const sum = require('./sum');
        
    test('adds 1 + 2 to equal 3', ()=> {
        expect(sum(1, 2)).toBe(3);
    });

    接着在package.json文件里添加测试命令

    "scripts:" {
        "test": "jest"
    }

    最后,运行 npm test命令后jest将会打印如下信息

    PASS ./sum.test.js
    ✓ adds 1 + 2 to equal 3 (5ms)
    

    至此,第一个测试Demo完成了。

    Using Matchers

    Jest使用matchers来使用不同的方式测试你的结果。

    Common Matchers

    最简单的测试方式就是测试一个值是否全等

    test('2加2等于4', ()=> {
        expect(2 + 2).toBe(4);
    });

    在上述代码中,expect(2+2)返回一个“期望”对象,通常我们不会对这个期望对象进行匹配,而是由matchers完成,在这里.toBe(4)便是这个matchers,当Jest运行时,它会跟踪所有失败的matchers以便打印正确的错误信息给我们。

    toBe使用 === 来测试全等于,如果我们想检查一个对象object中的值,使用toEqual来替代,toEqual递归遍历检查对象或数组里的每一个领域。

    "use strict";
        
    test('object assigenment', ()=> {
        let data = { one: 1};
        data['two'] = 2;
        expect(data).toEqual({ one: 1, two: 2 });
    })

    注意:官网的例子是没有使用的"use strict";,然后npm test的时候就会报出一条错误
    SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

    使用not可以测试一个matchers的反向规则:

    test('adding positive numbers is not zero', () => {
        for (let a = 1; a < 10; a++) {
            for (let b = 1; b < 10; b++) {
                expect(a + b).not.toBe(0);
            }
        }
    });

    Truthiness

    在测试的时候,有时候我们需要在undefinednullfalse进行区别,但是我们又不想去了解他们的不同点,Jest也会帮助我们得到我们想要的结果。

    • toBeNull 检查是否为null

    • toBeUndefined 检查是否为undefined

    • toBeDefined 与toBeUndefined的相反

    • toBeTruthy 检查任何通过if显示转换是否为true

    • toBeFalsy 检查任何通过if显示转换是否为false

    如下:

    test('null', () => {
        let n = null;
          expect(n).toBeNull();
          expect(n).toBeDefined();
          expect(n).not.toBeUndefined();
          expect(n).not.toBeTruthy();
          expect(n).toBeFalsy();
    });
    
    test('zero', () => {
          let z = 0;
          expect(z).not.toBeNull();
          expect(z).toBeDefined();
          expect(z).not.toBeUndefined();
          expect(z).not.toBeTruthy();
          expect(z).toBeFalsy();
    });

    Numbers

    比较数字的大多数方法都有其对应的matchers

    • toBeGreaterThan 大于

    • toBeGreaterThanOrEqual 大于等于

    • toBeLessThan 小于

    • toBeLessThanOrEqual 小于等于

    test('two plus two', () => {
        let value = 2 + 2;
        expect(value).toBeGreaterThan(3);
        expect(value).toBeGreaterThanOrEqual(3.5);
        expect(value).toBeLessThan(5);
        expect(value).toBeLessThanOrEqual(4.5);
    
        // toBe and toEqual 对于number类型作用是一样的
        expect(value).toBe(4);
        expect(value).toEqual(4);
    });

    对于浮点数的测试,使用toBeCloseTo来替代toEqual,因为我们不会让一个测试依赖于一个微小的舍入型错误。

    test('adding floating point numbers', () => {
        let value = 0.1 + 0.2;
        expect(value).not.toBe(0.3);    // It isn't! Because rounding error
        expect(value).toBeCloseTo(0.3); // This works.
    });

    Strings

    使用toMatch对字符串进行正则表达式匹配

    test('there is no I in team', () => {
        expect('team').not.toMatch(/I/);
    });
    
    test('but there is a "stop" in Christoph', () => {
        expect('Christoph').toMatch(/stop/);
    })

    Arrays

    使用toContain对数组内的特定项进行匹配测试

    let shoppingList = ['diapers', 'kleenex', 'trash bags', 'paper towels', 'beer'];
    
    test('the shopping list has beer on it', () => {
        expect(shoppingList).toContain('beer');
    });

    Exceptions

    使用toThrow对一个特定函数调用时候抛出的错误进行测试

    function compileAndroidCode() {
        throw new ConfigError('you are using the wrong JDK');
    }
    
    test('compiling android goes as expected', () => {
        expect(compileAndroidCode).toThrow();
        expect(compileAndroidCode).toThrow(ConfigError);
    
        // You can also use the exact error message or a regexp
        expect(compileAndroidCode).toThrow('you are using the wrong JDK');
        expect(compileAndroidCode).toThrow(/JDK/);
    });

    Testing Asynchronous Code

    在javascript程序中,会经常见到一些异步执行的代码,当我们有这些异步执行的代码时,Jest需要知道当前这个代码测试是否已经完成,然后才能转向另一个测试。Jest提供了一些方法来处理这种问题。

    Callbacks

    最常用的异步测试模式便是callbacks

    列如,我们有一个fetchData(callback)方法,当callback(data)方法调用的时候,我们会获取一些data数据,并且想测试返回的数据是否只是一个字符串uyun

    默认情况下下,Jest在所有的代码执行完之后便会完成测试,这意味这些测试不再会按计划的工作下去。

    // Don't do this!
    test('the data is uyun', () => {
        function callback(data) {
            expect(data).toBe('uyun');
        }
    
        fetchData(callback);
    });

    问题是,测试希望一旦fatchData成功后才能完成,并在其之前调用回调。

    这里有另一种形式修复这个测试的问题,在这个测试方法里使用一个参数为done的回调参数,而不是放置一个空参数,Jest要等到done被调用后才会结束此次测试。

    test('the data is uyun', done => {
        function callback(data) {
            expect(data).toBe('uyun');
            done();
        }
    
        fetchData(callback);
    });

    如果done()没被调用,测试即失败了,这时候我们也会得到我们想要的错误结果了。

    Promises

    如果我们的代码中使用到了Promises ,这里有一个简单的异步测试处理方法。只是我们的测试中返回一个promise,并且Jest会等待这个promise解析完成,如果rejected了,这个测试便会自动视为失败。如下:

    test('the data is uyun', () => {
        return fetchData().then(data => {
            expect(data).toBe('uyun');
        });
    });

    注意:一定要确保返回了Promise,如果省略了这步,你的测试将会在fetchData完成之前首先结束掉。

    Async/Await

    如果代码中使用到asyncawait,可以这样做。编写一个异步测试,仅需要在测试方法前面使用async关键词,然后传递给测试函数即可。如下:

    test('the data is uyun', async () => {
        const data = await fetchData();
        expect(data).toBe('uyun');
    });

    在这个例子中,asyncawait等同于promises方法的一种语法糖实现方式。

    Jest使用者:Jest被各种规模的团队用于测试Web应用程序,node.js服务,移动应用程序和API。

  • 相关阅读:
    1144 The Missing Number (20分)
    1145 Hashing
    1146 Topological Order (25分)
    1147 Heaps (30分)
    1148 Werewolf
    1149 Dangerous Goods Packaging (25分)
    TypeReference
    Supervisor安装与配置()二
    谷粒商城ES调用(十九)
    Found interface org.elasticsearch.common.bytes.BytesReference, but class was expected
  • 原文地址:https://www.cnblogs.com/lilala-world/p/7410708.html
Copyright © 2020-2023  润新知