如何用 Jest 正确实现这样的测试套件架构?

Posted

技术标签:

【中文标题】如何用 Jest 正确实现这样的测试套件架构?【英文标题】:How to correctly achieve such test suite archtecture with Jest? 【发布时间】:2021-06-16 17:39:36 【问题描述】:

我已经检查了 Jest 文档网站上的所有 guides 和 examples,但没有找到任何可以为我的问题提供答案的内容。

我正在寻找一种模式,它允许我使用 Jest 分别为许多不同的功能(在我的情况下是 getter)运行测试用例。

目前,在我的 example.test.ts 文件中,我有以下内容:

import  getterOne, getterTwo, getterThree, ...  from getters;

describe('test suite', () => 
  beforeAll(async () => 
    //connect to MongoDB
  )

  afterAll(async () => 
    //disconnect from MongoDB
  )

  //request token from DB, to check it
  it('key', async () => 
    const key = await KeysModel.findOne(_id: 'any').lean();
    expect(key).toMatchSnapshot(
      field: expect.any(String),
    );
  );

  /**
   * predefine key and some other things
   * but I can't call key here, because describe doesn't support
   * async/await, as it should be synchronous
   */


  //test separate getterOne with key variable as an argument

  //test separate getterTwo with key variable as an argument

  //test separate getterThree with key variable as an argument
)

但众所周知,我无法在 it 案例中使用已定义的密钥。所以我可以在顶层再次定义 key,但是

ok 是否可以为每个 getter 测试用例重新定义关键变量?如果我有这么多 getter,我会收到 xN 绝对没用的请求。 据我了解,我不能在describe 中使用async/await,因为不支持从“describe”返回 Promise。测试必须同步定义

所以我不是在问,如何编写代码,而是在这种情况下编写依赖测试用例的正确模式是什么?

有人可以举个例子吗?我应该在describe 里面写更多test 还是通常的做法有点不同?

应该使用哪些 Jest 方法以及使用顺序?

目前,我通过 let 关键字声明空变量,并使用它们,如下所示:

describe('test suite', () => 
  beforeAll(async () => 
    //connect to MongoDB
  )

  afterAll(async () => 
    //disconnect from MongoDB
  )

  describe('inside', () => 
    let key;

    beforeAll(async () => 
      key = await KeyModel.findOne();
    )
   
    test('getterOne', async () => 
      const res = await getterOne(key);
      expect(res).toMatchSnapshot(
        id: expect.any(Number)
      );
    );

    //other test with keys..
  
  )
)

它认为是一种好的做法吗?

【问题讨论】:

是否可以为每个 getter 测试用例重新定义关键变量? - 可以,除非您使用 concurrent 测试。 describe 范围内的变量在测试之间共享。这被认为是一种很好的做法。您可以将测试常见的异步操作移至 beforeEach 或 beforeAll。或者,如果一组测试取决于您异步获得的内容,您可以使用多个断言进行一个测试,因为测试应该同步声明并知道何时开始测试 @EstusFlask,谢谢你的评论,它让我比现在更有信心。老实说,我更喜欢将其视为一个答案,尤其是如果您不会羞于分享一些代码示例。 对于您描述的情况,示例将与您在第二个 sn-p 中发布的完全一样,无需添加任何内容,您可以自己回答。由于同步describe 的限制,可能会有不太直接的情况,解决方案会有所不同,例如***.com/questions/61323343/… 和 ***.com/questions/62019169/… 【参考方案1】:

就目前而言,我使用的结构与建议的相同。但我也感谢Estus Flask 为我指明了这个方向。我不使用模型,主要是因为我不仅测试functions,还测试数据库存在和数据持久性。

describe('test suite', () => 
  beforeAll(async () => 
    //connect to MongoDB
  )

  afterAll(async () => 
    //disconnect from MongoDB
  )

  /**
   * another describe stage below
   * with its own after and before and describe stages
   */

)

【讨论】:

以上是关于如何用 Jest 正确实现这样的测试套件架构?的主要内容,如果未能解决你的问题,请参考以下文章

如何用 jest 测试 combineReducers

如何用 jest 测试 redux saga?

如何用 Jest 测试一系列数字?

如何用 jest 测试 nuxt?

如何用 jest 在服务 (NestJS) 中测试模型 (Mongoose)

如何用 jest 测试此 api 中间件是不是处理 fetch 引发的错误?