zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    python爬取动态网页数据,详解
    几行代码轻松搞定python的sqlite3的存取
    14、Iterator跟ListIterator的区别
    13、Java菜单条、菜单、菜单项
    12、借助Jacob实现Java打印报表(Excel、Word)
    11、借助POI实现Java生成并打印excel报表(2)
    10、借助POI实现Java生成并打印excel报表(1)
    9、JcomboBox下拉框事件监听
    8、单选按钮(JRadioButton)和复选框(JCheckBox)
    java swing 添加 jcheckbox复选框
  • 原文地址:https://www.cnblogs.com/lilala-world/p/7410708.html
Copyright © 2011-2022 走看看