【问题标题】:Can I run jest tests as regular js files?我可以将 jest 测试作为常规 js 文件运行吗?
【发布时间】:2020-03-10 15:50:40
【问题描述】:

Jest 使用 describeitexpect 而您不必使用 require 它们。这没关系,因为如果你有一个名为test.spec.js 的测试文件,你永远不会通过发出命令node test.spec.js 直接执行它。

我想使用 node 作为标准 js 文件来执行它,而不必使用 jest 的 cli 或 npm test。有可能吗?

例如,我将转换以下文件:

// taken from documentation
const user = require('./users.js')
it('works with promises', () => {
  expect.assertions(1);
  return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
});

类似

var {describe, it, expect} = require('jest-primitives') 
const user = require('./users.js')
it('works with promises', () => {
  expect.assertions(1);
  return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
});

所以它是一个自包含的js文件,可以只使用节点运行。

jest 提供的全局变量的完整列表在here 中给出。

【问题讨论】:

  • Jest 使用了一些魔法来简化测试。它取代了标准的 nodejs 模块解析,因此它可以支持具有复杂 webpack 设置的项目,并支持转译。它还对少数全局对象的原型进行修补,这是有争议的。即使你管理了你想要的,你很可能至少绕过了 jest 替换 nodejs 模块的解决方案。这将导致与标准笑话测试不同的行为。
  • 出于好奇,除了您没有使用jest cli 运行测试之外,您的第一个和第二个示例之间有什么区别?无论哪种方式,您都必须安装jest,因此如果您将jest cli 排除在外,这并不是说您没有安装额外的依赖项。
  • 我想了解 jest 使用其原始全局函数所做的“魔法”。一种方法是看看在不使用jest cli 的情况下复制有多容易,这就是这个问题。
  • 一个实际用途可能是您不能像“破解”常规 js 一样“破解” jest js 文件(例如,使用测试框架本身改进或自定义某些功能)文件(例如,我可以将 jest 的 it 函数包装在我自己的 it 函数中,该函数运行一些自定义代码(例如,将测试名称记录到文件中,将测试函数包装在另一个函数中),然后调用 jest 的 it 函数)
  • 听起来你在问同样的问题。你看过jest.runCLI吗? stackoverflow.com/questions/50827216/…

标签: javascript node.js jasmine jestjs


【解决方案1】:

技术上可行吗?是的。

你应该吗?可能不是。 (但有更好的方法 - tl;博士使用tape

背景

Jest 是test harness

Jest 并不是唯一使用describe()it() 的测试工具。这些是behavior-driven development (BDD) 的典型测试关键字。您还会发现它们与Mocha 和其他人一起使用。

describe()it() 是与测试工具交互的函数,分别告诉它添加测试套件和测试用例。然后测试工具运行测试用例,收集结果,格式化结果并输出它们。

为什么你不应该用 Jest 做这个

一般来说,您应该尽可能地习惯性地使用技术。这使其他人更容易阅读、理解和使用您的技术。

特别是,以这种方式使用 Jest 将是自我实现的、hacky、错误的,并且对于不熟悉您的代码的任何人来说通常都难以理解。话虽如此,应该是可以的。

你可以如何用 Jest 来尝试

Jest 在他们的 Jest monorepo 中定义了 runner 包。一个是Circus,另一个是Jasmine2

Circus exports describe(), it() and some other keywords,虽然这些对我们来说并不是真正有用的,因为这些函数只是在内部创建测试套件和测试用例,而不向我们公开它们或给我们运行它们的方法。

Jasmine2 exports an executable function 其中returns a Promise of a test resultcode for jasmineAsyncInstall 在 env 或全局中创建大部分关键字,您也许可以使用这些关键字。

您想要在这里做的是定义 it()describe() 函数,或者全局地,作为导出(如果您想在问题的代码示例中使用它们),或者通过定义它们在主模块的范围内。这些功能应该注册测试用例和测试套件。您可能想要跟踪测试用例并稍后运行它们,或者立即运行它们并跟踪测试结果。

现在的问题在于确定测试模块何时完成运行。也就是说,当所有describe()it() 都已执行(无论测试用例本身是否已执行)以及任何其他事件代码(不在任何块中的代码)时。没有很好的方法来处理这个问题,这就是它可能再次变得糟糕的地方。最简单的方法可能是给process.on('exit' 添加一个监听器。

为什么没关系

测试工具通常只是一个测试运行者和一个报告者。特别是,Jest 只是组件的集合,所有这些都是可配置的。

如果我们只是从 Jest 中提取一个函数和一个变量,我们真的可以说我们仍在使用它吗?为什么我们甚至想要?真的没有理由在这里使用 Jest。如果你不喜欢它运行测试的方式,你应该使用不同的测试工具而不是尝试修改它。如果你喜欢记者,开玩笑exports a package containing only the reporter

使测试文件可运行的更好方法

使用taptape。这些旨在按照您想要的方式运行,并且是可配置的。

例子:

const test = require('tape');
const MyClass = require('../src/my-class');

test('MyClass.doSometing should be true', (t) => {
    const result = MyClass.doSomething();

    if (result === true) {
      t.pass('The test passed! Hooray! Our class MyClass is seemingly error-free!');
    } else {
      t.fail('Oh noes. Our test has failed. Why am I such a bad programmer....?');
    }

    t.end();
});

【讨论】:

    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2021-10-02
    • 2014-01-31
    • 1970-01-01
    • 2018-09-11
    • 2021-11-22
    相关资源
    最近更新 更多