JEST:是否有一种解决方案可以仅针对已更改/受影响的文件运行测试?

Deb*_*der 12 javascript unit-testing jestjs

Jest 在这方面给出的解决方案很少。我已经尝试了大多数解决方案,例如--findRelatedTests,,--onlyChanged--changedSince但每种解决方案都存在一些缺点。我认为--changedSince这是最适合我的。

jest --changedSince=origin/master --coverage
Run Code Online (Sandbox Code Playgroud)

它主要涵盖基本场景,例如运行与更改的源文件相对应的测试文件。但它不能处理少数情况,例如删除源文件(例如a.js)并且在另一个文件(例如)中使用(导入)same(),它不会对任何文件运行测试(a.jsb.jsa.jsb.js。它似乎没有对导入它的父文件运行测试。

是否有一个干净的解决方案可以处理所有场景,例如文件重命名/删除、动态导入、对导入的父模块运行测试或更改源文件时可能发生的任何其他影响?

Pou*_*aei 13

快速回答:不。

长答案:是的,但它不是那么干净或直接。

我通过三个步骤实现了这一目标。

步骤1:

您可以通过一些脚本来实现这一点。首先,您需要通过 Git 获取所有已更改文件的列表。

这可以通过如下函数来实现:

const util = require("util")
const exec = util.promisify(require("child_process").exec)

const detectChangedFiles = async () => {
    try {
        const { stdout, stderr } = await exec("git diff origin/master --name-only")

        if (stderr) {
            throw new Error(stderr)
        }

        return stdout.replace(/\n/g, " ").replace(/client\//g, " ")

    } catch (error) {
        console.log(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

第2步:

其次,您想要获得这些文件的相关测试列表,如下所示:

 const findRelatedTests = async () => {
    const changedFiles = await detectChangedFiles()

    try {
        const { stdout, stderr } = await exec(`jest --listTests --findRelatedTests ${changedFiles}`)

        if (stderr) {
            throw new Error(stderr)
        }

        if (!stdout) {
            console.log('No tests found for the changed files :)')
        } else {
            return stdout.replace(/\n/g, " ")
        }

    } catch (error) {
        console.log(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

步骤 3:

最后,您希望将所有这些测试提供给 jest 来运行;

const runRelatedTests = async () => {
    const relatedTests = await findRelatedTests()

    if (relatedTests) {
        try {
            const { stdout, stderr } = await exec(`jest --ci --coverage ${relatedTests}`)

            if (stderr) {
                throw new Error(stderr)
            }
        } catch (error) {
            console.log(error)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这种实现的局限性之一是我总是与主分支进行比较,这不是一个好的假设。在特殊情况下,人们可能会选择与另一个分支合并。

这可以通过几种方式来处理;

  1. 如果您正在运行 cli,请将参数传递给 cli 并在脚本中使用它
  2. 如果您在像 Gitlab 这样的管道中运行并假设这是 MR/PR,请考虑使用一些可用的环境变量(在本例中为CI_MERGE_REQUEST_TARGET_BRANCH_NAME

  • @pauya-ataei 我认为你的脚本与 `--changedSince` 选项做同样的事情。在步骤2中,如果文件被删除或重命名,则无法检测到相关的测试文件。 (2认同)