如何在 Jest 中的 beforeAll / beforeEach 和测试之间共享数据?

2024-02-25

我们使用 jest 来测试我们的 API,并且有相当复杂的场景。我们使用beforeAll函数为每个测试设置通用辅助变量,有时设置租户分离,在其他情况下我们使用beforeEach为测试设置租户分离的函数,并为测试租户提供一些默认配置,...

例如,测试可能像这样(如您所见,我们使用 TypeScript 来编写测试,以防万一):

let apiClient: ApiClient;
let tenantId: string;

beforeAll(async () => {
    apiClient = await getClientWithCredentials();
});

beforeEach(async () => {
    tenantId = await createNewTestTenant();
});

describe('describing complex test scenario', () => {
    it('should have some initial state', async () => {
        await checkState(tenantId);
    });

    it('should have some state after performing op1', async () =>{
        await op1(tenantId);
        await checkStateAfterOp1(tenantId);
    });

    it('should have some state after performing op2', async () =>{
        await op2(tenantId);
        await checkStateAfterOp2(tenantId);
    });

    it('should have some state after performing op1 and op2', async () =>{
        await op1(tenantId);
        await op2(tenantId);
        await checkStateAfterOp1AndOp2(tenantId);
    });

    it('the order of op1 and op2 should not matter', async () =>{
        await op2(tenantId);
        await op1(tenantId);
        await checkStateAfterOp1AndOp2(tenantId);
    });    
});

describe('another similar complex scenario', () => {
    // ... you see where this is going
});

问题是,共享这些初始化的变量的最佳方式是什么beforeAll and beforeEach? - 如果使用以下命令执行上述测试,则​​有效--runInBand选项,其中“...在当前进程中串行运行所有测试...”

但当并行执行时,它开始随机失败,主要是指tenantId未定义。鉴于这些测试是 ~200 个类似测试的一部分,因此全部都通过了。同时,这取决于机器。具有 8 核/16 线程的构建代理只有 50-60% 通过测试。我使用四核 CPU 的同事大约有 80% 通过了测试,而对于使用双核 CPU 的我来说,有时只有 1-2 个测试失败,其他时候大约有 10 个测试失败。显然这取决于并行度。

我发现了 2 个 GitHub 问题,人们提到了使用的可能性this共享上下文(不再起作用)或将所有内容封装在describe:

  • https://github.com/facebook/jest/issues/3553 https://github.com/facebook/jest/issues/3553
  • https://github.com/facebook/jest/issues/3673 https://github.com/facebook/jest/issues/3673

所以我尝试了一个非常幼稚的方法:

describe('tests', () => {
    let apiClient: ApiClient;
    let tenantId: string;

    beforeAll(async () => {
        apiClient = await getClientWithCredentials();
    });

    beforeEach(async () => {
        tenantId = await createNewTestTenant();
    });

    describe('describing complex test scenario', () => {
        it('should have some initial state', async () => {
            await checkState(tenantId);
        });

        it('should have some state after performing op1', async () =>{
            await op1(tenantId);
            await checkStateAfterOp1(tenantId);
        });

        it('should have some state after performing op2', async () =>{
            await op2(tenantId);
            await checkStateAfterOp2(tenantId);
        });

        it('should have some state after performing op1 and op2', async () =>{
            await op1(tenantId);
            await op2(tenantId);
            await checkStateAfterOp1AndOp2(tenantId);
        });

        it('the order of op1 and op2 should not matter', async () =>{
            await op2(tenantId);
            await op1(tenantId);
            await checkStateAfterOp1AndOp2(tenantId);
        });    
    });

    describe('another similar complex scenario', () => {
        // ... you see where this is going
    });
});

但这似乎并没有任何效果。 我真的很想并行运行测试,但我在文档中找不到任何相关内容。也许我不知道我应该寻找什么?


这对你有用吗?

describe('tests', () => {
    let apiClient: ApiClient;
    let tenantIds: {id: string, used: boolean}[];

    const findUnusedTenantId = () => {
      const tenant = tenantIds.find(a => !a.used);
      tenant.used = true; 
      return tenant.id
    }

    beforeAll(async () => {
        apiClient = await getClientWithCredentials();
    });

    beforeEach(async () => {
        const id = await createNewTestTenant();
        tenantIds.push({id, used: false})
    });

    describe('describing complex test scenario', () => {
        let tenantId: string
        it('should have some initial state', async () => {
            tenantId = fineUnusedTenantId();
            await checkState(tenantId);
        });

        it('should have some state after performing op1', async () =>{
            await op1(tenantId);
            await checkStateAfterOp1(tenantId);
        });

        // ...
    });
    describe('next scenario', () => {
        let tenantId: string
        it('first test', async () => {
            tenantId = fineUnusedTenantId();
            await checkState(tenantId);
        });

你可能想要一个 afterAll 钩子来清理数据库

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Jest 中的 beforeAll / beforeEach 和测试之间共享数据? 的相关文章

随机推荐

  • Clojure 测试框架的优势?

    您更喜欢哪一个 为什么 各自的优点和缺点是什么 在什么情况下 每个人都比其他人更胜一筹 我对 midje 与 clojure test 特别感兴趣 但也可以随意提出其他 Clojure 测试框架 也可以看看Clojure 的最佳单元测试框架
  • 在静态方法中在 UIView 上用清晰的颜色绘制(切一个洞)

    我有一个iPhone应用程序 我需要实现以下方法 UITextView textView UITextView withCuttedRect CGRect r 此方法必须剪切 填充 UIColor clearColor 矩形r from U
  • 在同一套接字上并行调用 send/recv 是否有效?

    我们可以在同一个套接字上从一个线程调用 send 并从另一个线程调用 receive 吗 我们可以从同一套接字上的不同线程并行调用多个发送吗 我知道好的设计应该避免这种情况 但我不清楚这些系统 API 的行为方式 我也找不到同样的好的文档
  • 表单不提交动态生成的输入(jQuery)

    您好 我正在尝试为我的表单动态生成一些输入 但它没有发布生成的新输入 到目前为止我一直在四处搜索 我唯一能找到的就是使表单成为body 标签 并且在我的应用程序的设计中这是不可能的 所以有人可能知道会发生什么以及如何解决它 不 它不适用于
  • 如何在 Visual Studio Code 中显示 Jupyter Notebook 中的所有输出?

    在 VS Code 中的 Jupyter Notebook 中 当我运行在某个时刻打印大量输出的代码时 剩余的输出将被抑制并显示一条消息 显示更多 在文本编辑器中打开原始输出数据 如何使所有输出可见 我认为你在这里使用内部构建是正确的设置
  • Flink:处理数据早于应用程序水印的键控流

    我正在使用带有运动源和事件时间键控窗口的 F link 该应用程序将监听实时数据流 窗口 事件时间窗口 并处理每个键控流 我有另一个用例 我还需要能够支持某些关键流的旧数据的回填 这些将是事件时间 鉴于我正在使用水印 这会成为一个问题 因为
  • Azure Functions - Blob 流动态输入绑定

    我正在 azure 上运行一个 C 函数 它需要从容器中获取文件 唯一的问题是输入文件的路径每次都会 可能 不同 并且输入文件的数量将从 1 到大约 4 或 5 不等 因此 我不能只使用默认的输入 blob 绑定据我所知 我的选择是给予容器
  • 通过Ajax发送FormData + js变量

    我有这个 Ajax 来发送多个图像 btn on click function var formData new FormData form1 0 var path php upload adm prodpictures php ajax
  • 如何转到 Eclipse 中的“下一个出现”

    在 Eclipse 中 您可以打开 标记出现次数 然后它将突出显示当前范围内给定变量的每次出现 那太好了 但我真的很想从一次这样的事件转移到下一次 到目前为止 我已经找到了两个关于如何执行此操作的建议 但都没有奏效 首先有这样的帖子 Ecl
  • 使用 configparser 添加注释

    我可以使用 python 中的 ConfigParser 模块使用 add section 和 set 方法创建 ini 文件 请参阅示例http docs python org library configparser html http
  • 调试 $rootScope:infdig

    这是一个常见问题 已达到 5 次 digest 迭代 流产 观察者在最近 5 次迭代中被解雇 文档 https docs angularjs org error https docs angularjs org error rootScop
  • 自动更新 HTML 画布宽度和高度属性

    我想将 HTML5 画布与 Flexbox 结合使用 当用户调整窗口大小时 我需要自动设置 canvas width 和 canvas height 我尝试使用 jQuery 来实现 cnvs attr width cnvs width c
  • “Google_Exception”,消息为“经过身份验证后无法添加服务”

    我正在使用 Oauth 2 0 开发带有 Google Analytics 的 WP 插件 我所有的身份验证和数据提取都工作正常 除了这个问题 第一次获得新的 Google 授权代码 例如 4 xbSbg 并进行身份验证 然后尝试调用new
  • 我可以在 AngularJS 中要求通用父指令吗

    子指令是否可以在不确切知道父指令是什么的情况下需要父指令 而只是知道它 实现了一个接口 例如
  • 如何多次重用相同的代码 - html/css

    我想为每个按钮重复使用模式两次 按钮代码 function popUp model const pop up model document getElementById model pop up model classList toggle
  • TypeScript 合并通用数组

    我想要一个对象的通用对象数组 但是 它生成联合类型 如何获得一种合并对象类型 喜欢 key string boo string foo string type PluginType
  • 在 C# 中使用 xsi:nil="true" 反序列化 XML 元素

    我正在尝试反序列化 XML 文件XmlSerializer in C 随后的目标类是使用 xsd 实用程序自动生成的 System CodeDom Compiler GeneratedCodeAttribute xsd 4 0 30319
  • 从 OLE 二进制字符串解析 MathType MTEF 数据

    需要将 MS WORD 2003 或更低版本中的 MathType 方程转换为 MathML 以便在网络上很好地呈现 MathType 的内置函数 Publish to MathPage 可以很好地完成这项工作 但我想将方程转换过程集成到我
  • 带有 React 和 Node 的 google 应用引擎:生产设置

    我使用 React js 和 Node js Express 创建一个网站 我使用 Google App Engine 和 Google Datastore 作为数据库 在我的本地机器上一切正常 React 前端能够访问 Node js 提
  • 如何在 Jest 中的 beforeAll / beforeEach 和测试之间共享数据?

    我们使用 jest 来测试我们的 API 并且有相当复杂的场景 我们使用beforeAll函数为每个测试设置通用辅助变量 有时设置租户分离 在其他情况下我们使用beforeEach为测试设置租户分离的函数 并为测试租户提供一些默认配置 例如