nodejs / nodejs/node

test_runner: `t.after` should respect `the first-in-last-out` principle like Golang's defer

未关闭
#55,853 11 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

feature request test_runner
主要语言
JavaScript
星标
122k
派生
37.3k
平均合并
4 天 2 小时
30 天内合并 PR
283

描述

Version

v22.10.0

Platform

No response

Subsystem

No response

What steps will reproduce the bug?
1. Create a test file
import fs from 'node:fs'
import path from 'node:path'
import test from 'node:test'

test('basic', async (t) => {
    const testDir = path.join(import.meta.dirname, 'logs')

    fs.mkdirSync(testDir, { recursive: true })

    t.after(() => {
        console.log('remove test dir')
        fs.rmdirSync(testDir, { recursive: true })
    })

    fs.writeFileSync(path.join(testDir, 'test.log'), 'hello world!')

    t.after(() => {
        console.log('remove test file')
        fs.unlinkSync(path.join(testDir, 'test.log'))
    })

    // do staff...
})
How often does it reproduce? Is there a required condition?

None

What is the expected behavior? Why is that the expected behavior?

t.after should follow the first-in, last-out principle

According to the above code, the file should be deleted first, then the directory

What do you see instead?
✖ basic (7.4021ms)
  Error: ENOENT: no such file or directory, unlink 'project\folder\logs\test.log'
      at Object.unlinkSync (node:fs:1871:11)
      at TestContext.<anonymous> (file:///path/to/test.test.mjs:19:12)
      at TestHook.runInAsyncScope (node:async_hooks:211:14)
      at TestHook.run (node:internal/test_runner/test:934:25)
      at TestHook.run (node:internal/test_runner/test:1225:18)
      at TestHook.run (node:internal/util:543:20)
      at node:internal/test_runner/test:853:20
      at async Test.runHook (node:internal/test_runner/test:851:7)
      at async after (node:internal/test_runner/test:893:9)
      at async Test.run (node:internal/test_runner/test:942:7) {
Additional information

the first-in-last-out principle is more reasonable and practical. It is useful in many scenarios.

I'm not sure why it was designed in the form of a queue. Is there anything special about it?

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

使用提供的测试用例复现该行为,然后从 node:internal/test_runner 的堆栈帧跟踪清理流程,尤其是 TestHook.run 和 after。当回调按注册顺序的逆序执行,从而使文件先于其目录被删除,并且覆盖所报告的顺序时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
testing-qa
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
55/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。