美文网首页
Jest - 安装和拆卸 Setup and Teardown

Jest - 安装和拆卸 Setup and Teardown

作者: 小黄人get徐先生 | 来源:发表于2019-08-25 11:27 被阅读0次

通常在编写测试时,您有一些设置工作需要在测试运行前完成,还有一些完成工作需要在测试运行后完成。Jest提供了帮助函数来处理这个问题。

为许多测试重复设置

如果很多测试有需要重复去做的工作,你可以使用 beforeEachafterEach

例如,假设有几个测试与 city 数据库交互。你有一个 initializeCityDatabase() 方法必须在每次测试之前调用,以及一个方法 clearCityDatabase() 必须在每次结束之后调用。你可以如下这样做:

beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

beforeEachafterEach 可以处理异步代码,方式和测试异步代码是一样的,他们可以接收一个done参数或返回一个 promise。例如,如果 initializeCityDatabase() 当 city 数据库初始化完成后返回一个 resolved 状态的 promise,我们希望返回这个 promise:

beforeEach(() => {
  return initializeCityDatabase();
});
一次性设置

有时候,你仅仅需要在文件的开头安装一次。挡在设置异步的时候,这个尤其麻烦,所以你不能内联地完成它。Jest 提供了 beforeAllafterAll 来处理这种情况。

例如,如果 initializeCityDatabaseclearCityDatabase 返回 promises,并且这个 city 数据库可以在测试之间被复用,那么我们的测试代码可以修改成这样:

beforeAll(() => {
  return initializeCityDatabase();
});

afterAll(() => {
  return clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});
范围

默认情况下,beforeafter 块应用到文件中的每个测试。你可以使用 describe 块将测试组织到一起。当他们都在一个 describe 块里,这个 beforeafter 块仅仅作用于 describe 块内的测试。

例如,假设我们不仅有一个 city 数据库,而且还有一个 food 数据库。我们可以为不同测试做不同的安装:

// 应用到文件中的所有测试
beforeEach(() => {
  return initializeCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

describe('matching cities to foods', () => {
  // 仅仅应用到 describe 块中的测试
  beforeEach(() => {
    return initializeFoodDatabase();
  });

  test('Vienna <3 sausage', () => {
    expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
  });

  test('San Juan <3 plantains', () => {
    expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
  });
});

注意,最外层的 beforeEach 是先于 describe 块里的 beforeEach 执行的。它可能有助于说明所有钩子的执行顺序。

beforeAll(() => console.log('1 - beforeAll'));
afterAll(() => console.log('1 - afterAll'));
beforeEach(() => console.log('1 - beforeEach'));
afterEach(() => console.log('1 - afterEach'));
test('', () => console.log('1 - test'));
describe('Scoped / Nested block', () => {
  beforeAll(() => console.log('2 - beforeAll'));
  afterAll(() => console.log('2 - afterAll'));
  beforeEach(() => console.log('2 - beforeEach'));
  afterEach(() => console.log('2 - afterEach'));
  test('', () => console.log('2 - test'));
});

// 1 - beforeAll
// 1 - beforeEach
// 1 - test
// 1 - afterEach
// 2 - beforeAll
// 1 - beforeEach
// 2 - beforeEach
// 2 - test
// 2 - afterEach
// 1 - afterEach
// 2 - afterAll
// 1 - afterAll

// 记住 before 和 after 作用于每个测试(上面有两个 test),然后就是如上面所说,外层的 beforeEach 在内层的 beforeEach 之前执行
describe 块和 test 块执行顺序

在一个测试文件中,在执行任何真正的测试之前,Jest 先执行所有 describe 处理程序。这也就是我们在 describe 块中把安装和拆卸写在 before*after* 处理程序的原因。一旦 describe 块完成,默认情况下Jest将按照在收集阶段遇到的顺序连续运行所有测试,等待每个测试完成并被整理,然后再继续。

考虑以下演示性测试文件和输出:

describe('outer', () => {
  console.log('describe outer-a');

  describe('describe inner 1', () => {
    console.log('describe inner 1');
    test('test 1', () => {
      console.log('test for describe inner 1');
      expect(true).toEqual(true);
    });
  });

  console.log('describe outer-b');

  test('test 1', () => {
    console.log('test for describe outer');
    expect(true).toEqual(true);
  });

  describe('describe inner 2', () => {
    console.log('describe inner 2');
    test('test for describe inner 2', () => {
      console.log('test for describe inner 2');
      expect(false).toEqual(false);
    });
  });

  console.log('describe outer-c');
});

// describe outer-a
// describe inner 1
// describe outer-b
// describe inner 2
// describe outer-c
// test for describe inner 1
// test for describe outer
// test for describe inner 2
通用建议

如果一个测试失败,第一件应该做的事情就是,测试作为 唯一测试运行的时候,是否失败。在 jest 中运行仅仅单个测试(only one test)是简单的 - 仅仅需要临时将 test 改完 test.only

test.only('this will be the only test that runs', () => {
  expect(true).toBe(false);
});

test('this test will not run', () => {
  expect('A').toBe('A');
});

如果您有一个测试在作为较大的套件的一部分运行时经常失败,但在单独运行时不会失败,那么很有可能来自其他测试的内容会干扰这个测试。通常可以通过清除 beforeEach 之前的一些共享状态来解决这个问题。如果不确定是否某些共享状态被修改了,还可以尝试 beforeEach 记录数据。

相关文章

网友评论

      本文标题:Jest - 安装和拆卸 Setup and Teardown

      本文链接:https://www.haomeiwen.com/subject/uvlhectx.html