Jasmine

2024-06-27 16:53:12 394
Jasmine 是一个无依赖、行为驱动开发(BDD)风格的 JavaScript 测试框架,旨在为开发者提供简洁而强大的测试工具。它支持面向浏览器和 Node.js 环境的测试,并以其直观的语法和全面的功能受到广泛欢迎。

特点

  1. 无依赖:Jasmine 不依赖其他任何 JavaScript 库或框架,开箱即用。
  2. 行为驱动开发:采用 BDD 风格,使得测试用例的编写和阅读更加自然和直观。
  3. 内置断言库:内置丰富的断言方法,无需额外安装第三方断言库。
  4. 异步测试支持:通过 done 回调和 async/await 支持异步代码测试。
  5. Mock 和 Spies:内置 Mock 和 Spies 功能,用于模拟函数和对象的行为,方便测试。
  6. 钩子功能:提供 beforeAll、afterAll、beforeEach 和 afterEach 钩子,用于测试前后的设置和清理工作。

使用场景

  1. 单元测试:验证单个模块或函数的功能是否正确。
  2. 集成测试:测试多个模块之间的交互和集成情况。
  3. 端到端测试:确保应用程序的各个部分能够一起正常工作。
  4. 异步代码测试:测试回调、Promise 和 async/await 等异步操作的正确性。

安装方式

使用 npm 安装 Jasmine:

npm install --save-dev jasmine

初始化 Jasmine 配置:

npx jasmine init

使用示例

基础测试

创建一个 example.spec.js 文件:

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

运行测试:

npx jasmine

异步测试

describe("Async suite", function() {
  it("should support async execution of test preparation and expectations", function(done) {
    setTimeout(function() {
      expect(true).toBe(true);
      done();
    }, 1000);
  });
});

使用 Mock 和 Spies

describe("A spy", function() {
  let foo, bar = null;

  beforeEach(function() {
    foo = {
      setBar: function(value) {
        bar = value;
      }
    };

    spyOn(foo, 'setBar');
    foo.setBar(123);
  });

  it("tracks that the spy was called", function() {
    expect(foo.setBar).toHaveBeenCalled();
  });

  it("tracks all the arguments of its calls", function() {
    expect(foo.setBar).toHaveBeenCalledWith(123);
  });
});

钩子示例

describe("Hooks", function() {
  beforeAll(function() {
    // 在所有测试用例之前运行一次
  });

  afterAll(function() {
    // 在所有测试用例之后运行一次
  });

  beforeEach(function() {
    // 在每个测试用例之前运行
  });

  afterEach(function() {
    // 在每个测试用例之后运行
  });

  it("should run this test", function() {
    // 测试代码
  });
});

常用 API 介绍

  1. describe(description, function):定义一个测试套件,将相关的测试用例分组。

    describe("A suite", function() {
      // tests
    });
    
  2. it(description, function):定义一个测试用例。

    it("contains spec with an expectation", function() {
      expect(true).toBe(true);
    });
    
  3. expect(actual):断言一个值,与各种匹配器结合使用。

    expect(actual).toBe(expected);
    
  4. beforeAll(function):在所有测试用例之前运行一次。

    beforeAll(function() {
      // setup code
    });
    
  5. afterAll(function):在所有测试用例之后运行一次。

    afterAll(function() {
      // teardown code
    });
    
  6. beforeEach(function):在每个测试用例之前运行。

    beforeEach(function() {
      // setup code
    });
    
  7. afterEach(function):在每个测试用例之后运行。

    afterEach(function() {
      // teardown code
    });
    
  8. spyOn(object, 'method'):创建一个 spy 来跟踪对象方法的调用情况。

    spyOn(foo, 'setBar');
    

高级用法

自定义匹配器

Jasmine 允许创建自定义匹配器以增强测试断言功能:

beforeEach(function() {
  jasmine.addMatchers({
    toBeDivisibleBy: function() {
      return {
        compare: function(actual, expected) {
          const result = {};
          result.pass = (actual % expected) === 0;

          if (result.pass) {
            result.message = `Expected ${actual} to be divisible by ${expected}`;
          } else {
            result.message = `Expected ${actual} to be divisible by ${expected}, but it was not`;
          }

          return result;
        }
      };
    }
  });
});

it("is divisible by 3", function() {
  expect(9).toBeDivisibleBy(3);
});

异步代码测试

除了回调函数,Jasmine 还支持使用 async/await 进行异步测试:

describe("Async suite with async/await", function() {
  it("should support async/await", async function() {
    const result = await new Promise(resolve => {
      setTimeout(() => resolve(true), 1000);
    });

    expect(result).toBe(true);
  });
});

官方资料