【问题标题】:Get the current test/spec name in Jest在 Jest 中获取当前的测试/规范名称
【发布时间】:2021-06-15 02:59:33
【问题描述】:

有没有办法从正在运行的测试中获取当前规范名称?

基本上我想保存一个文件,例如。使用函数saveFile(),文件名是规范名。无需手动重新输入测试名称。

【问题讨论】:

    标签: jestjs


    【解决方案1】:

    这对我有用

    console.log(expect.getState().currentTestName);
    

    【讨论】:

    【解决方案2】:

    Jest 存储库中有一个 2 年以上的问题,以提供测试名称,截至 2021 年 2 月没有官方解决方案。一位核心维护者说 none would be available any time soon

    社区提供了解决方法,但是:

    最简单

    expect.getState().currentTestName
    

    这将返回测试的完整路径,从最外面的描述到测试本身,用' ' 分隔(not 最好的分隔符),例如static methods toString。您无法轻易分辨出哪一个是describe 名称,哪一个是test 名称。

    经过一些设置,很快就会被淘汰

    同样的GitHub issue 有这种替代方法,它可以通过jasmine['currentTest'].fullName 在测试中直接访问测试名称,不需要extend。请注意Jasmine will no longer be the default test reported starting in Jest 27

    jest.config.js:

    module.exports = {
        setupFilesAfterEnv: ['./jest.setup.js'],
        
        .................
    };
    

    jest.setup.js:

    // Patch tests to include their own name
    jasmine.getEnv().addReporter({
        specStarted: result => jasmine.currentTest = result,
        specDone: result => jasmine.currentTest = result,
    });
    

    然后,在您的 *.test.js 文件中...

    describe('Test description', () => {
        beforeEach(() => console.log('Before test', jasmine['currentTest'].fullName));
    
        test(...);
    });
    

    【讨论】:

      【解决方案3】:

      我发现唯一可能的方法是使用expect(),它的this 中包含规范名称。做类似的事情

      expect.extend({
        async toSaveFile(data) {
          fs.writeFileSync(`${this.currentTestName}.txt`, data)
          return { pass: true };
        },
      });
      

      允许然后做

      expect().toSaveFile('contents of the file');
      

      这绝对是一个 hack,但这是我能找到的唯一方法来获取对规范名称的引用。还有this.testPath表示测试文件

      【讨论】:

      • 太棒了!很好的发现。我希望开玩笑的时间能记录thisextend 调用中可用的内容。据我所知,this 是最好的“文档”。
      • “唯一可能的方法”?至少有two more ways,一个容易多了。
      • 不知道这已经存在了多久,但有expect.getState().currentTestName
      【解决方案4】:

      问题

      expect.getState().currentTestName 的问题在于它提供了一个连接字符串。

      例如如果是sum.test.js 测试文件:

      import { sum } from "./sum";
      import { sleep } from "./util/sleep";
      
      describe("testing sum", () => {
      
          describe("middle", () => {
      
              test('adds 1 + 1 to equal 2', async () => {
      
                  console.log("TESTNAME", expect.getState().currentTestName)
      
                  await sleep(1000)
      
                  expect(sum(1, 1)).toBe(2);
              });
          })
      
      })
      
      

      它会打印出TESTNAME testing sum middle adds 1 + 1 to equal 2,你无法分辨哪个属于哪个。

      解决方案

      要分离每个测试的名称,您可以这样做:

      步骤 1

      创建自定义环境。这会监听事件并设置变量:

      请注意,如果您使用的是jest-puppeteer,则可以使用PuppeteerEnvironment,而不是NodeEnvironment

      const PuppeteerEnvironment = require("jest-environment-puppeteer")
      
      const NodeEnvironment = require('jest-environment-node');
      
      class CustomEnvironment extends NodeEnvironment {
          constructor(config, context) {
              super(config, context);
              this.testPath = context.testPath;
              this.docblockPragmas = context.docblockPragmas;
          }
      
          getNames(parent) {
              if (!parent) {
                  return [];
              }
      
              if (parent.name === 'ROOT_DESCRIBE_BLOCK') {
                  return [];
              }
      
              const parentName = this.getNames(parent.parent);
              return [
                  ...parentName,
                  parent.name
              ]
          }
      
          async handleTestEvent(event, state) {
              const {name} = event;
      
              if (["test_start", "test_fn_start"].includes(name)) {
                  this.global.testNames = this.getNames(event.test)
              }
          }
      }
      
      module.exports = CustomEnvironment;
      

      第二步

      jest.config.js注册文件:

      
      export default {
      
          // ...
      
          // location of the file above
          testEnvironment: "./src/my-custom-environment.js",
      
      }
      
      

      第 3 步(TypeScript 可选)

      创建global.d.ts 文件:

      declare const testNames: string[]
      

      第四步

      在你的测试中使用它:

      import { sum } from "./sum";
      import { sleep } from "./util/sleep";
      
      describe("testing sum", () => {
      
          describe("middle", () => {
      
              test('adds 1 + 1 to equal 2', async () => {
      
                  console.log("TEST NAMES", testNames)
      
                  await sleep(1000)
      
                  expect(sum(1, 1)).toBe(2);
              });
          })
      
      })
      

      输出:

      TEST NAMES [ 'testing sum', 'middle', 'adds 1 + 1 to equal 2' ]
      

      学分归于:

      【讨论】:

      • 如果 jest 测试并行运行,我认为这将是一个问题
      • 您也可以通过转换(global as any).testNames 来检索值,而不是求助于 global.d.ts
      猜你喜欢
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2012-09-26
      • 2022-12-25
      • 1970-01-01
      相关资源
      最近更新 更多