
Shardeum 如何根据 unit-tests-todo.md 计划为缺失覆盖的模块补写 Jest 单元测试【免费下载链接】shardeumShardeum is an EVM based autoscaling blockchain项目地址: https://gitcode.com/GitHub_Trending/sh/shardeum如果你接手 Shardeum一个 EVM 兼容、基于动态状态分片的区块链项目的代码维护需要为还没有测试的模块补写 Jest 单元测试仓库根目录的 unit-tests-todo.md 就是现成的任务清单它列出了 90 个当前缺少单元测试的 TypeScript 文件每个文件都有唯一的任务编号#1–#90并按从简单到复杂排序。本文以该清单为起点说明如何从中挑选任务、在test/unit/下按仓库既有模式编写测试文件并用npm test单跑或全量验证结果。如何读懂 unit-tests-todo.md 并定位要测的文件unit-tests-todo.md 的核心信息有三部分总量与分层共 90 个未覆盖文件Simple 30 个、Medium 34 个、Complex 26 个快速索引Tasks #1-30是简单文件常量、类型、导出Tasks #31-64是中等复杂度单一职责模块Tasks #65-90是复杂文件核心系统组件如 EVM 解释器、状态管理、块构建逻辑策略建议文档给出 6 条测试策略其中与动手写测试直接相关的是两条——Use Existing Test Patterns: Follow patterns from existing test files in the codebase for consistency沿用代码库中现有测试文件的模式以及 Mock Dependencies: For complex files, create appropriate mocks for external dependencies为复杂文件的外部依赖创建 mock。文档还给出覆盖目标工具类文件至少 80% 覆盖关键业务逻辑 90% 以上。清单中每个任务行同时给出文件路径和简要描述例如- [ ] **Task #1**: /home/marc/work/shardeum/src/utils/constants.ts - Simple constants file (10 lines) - [ ] **Task #2**: /home/marc/work/shardeum/src/utils/versions.ts - Version reading utility (28 lines)注意路径前缀清单里的/home/marc/work/shardeum/是计划作者本机目录在本仓库中对应的就是src/下的相对路径即 Task #2 对应 src/utils/versions.ts。文档 Notes 部分还给了优先级提示debug/目录下的文件可放低优先级它们是开发工具migration 类文件只需基础验证测试纯导出的index.ts文件可以不写专门测试。选任务时可以先按自己的熟悉程度从 Simple 段挑也可以按文档建议直接指定编号或整个章节来认领任务如 Task #31, #35, #40。环境准备Node 版本要求package.json 中engines指定node: 20.19.3安装依赖必须用npm ci而不是npm install这一点在 CLAUDE.md 中明确强调Install dependencies (use npm ci, not npm install)npm ciCLAUDE.md 还要求提交前跑 lint 与格式检查npm run lint、npm run format-check这两个命令在写完测试后同样适用见验证环节。了解 Jest 的运行配置补写测试前先了解 jest.config.js 的关键设置它们决定了测试文件写在哪里、如何被收集module.exports { preset: ts-jest, testEnvironment: node, testTimeout: 5000000, // the more node involve in testing, the higher the timeout requires verbose: true, roots: [rootDir/test/unit,rootDir/test/testCases], setupFiles: [rootDir/test/unit/setup.ts], testMatch: [**/__tests__/**/*.(ts|tsx|js), **/?(*.)(spec|test).(ts|tsx|js)], transform: { ^.\\.(ts|tsx)$: ts-jest, }, moduleNameMapper: { ^(\\.{1,2}/.*)\\.js$: $1, }, resetMocks: true, clearMocks: true, }与写新测试直接相关的几点单元测试入口是test/unit/目录roots配置测试文件名需匹配*.test.ts等模式CLAUDE.md 的 Testing 一节也说明Test files should follow*.test.tspattern且 Unit tests in/test/unit/test/unit/setup.ts 只有一行有效代码jest.mock(../../src/index.ts, () ({}))即把主入口 mock 成空对象。这是防止测试里 import 到src/index.ts时拉起整个应用的关键设置——仓库中现有测试文件顶部普遍有一条注释 dont import index files, import the specific files you need写新测试时同样要直接 import 目标模块的具体文件而不是src的聚合入口resetMocks: true和clearMocks: true意味着每个测试间 mock 状态会被重置。这是 test/unit/src/utils/versions.test.ts 这类测试采用先jest.resetModules()再在beforeEach里用jest.doMock注册依赖 mock最后用require载入被测模块写法的原因。给带外部依赖的模块写测试时可以沿用这个模式。测试文件的命名与目录约定仓库现有单元测试目录结构与源码一一对应test/unit/src/下按src/的目录树镜像组织。例如src/utils/constants.ts 的测试是 test/unit/src/utils/constants.test.ts[src/evm_v2/memory.ts] 的测试是 test/unit/src/evm_v2/memory.test.ts需要 mock 实现时放在对应目录的__mocks__/下如 src/shardeum/mocks/debugRestoreAccounts.ts 被 src/shardeum/debugRestoreAccounts.ts 相关测试使用。因此给清单中某个任务补测试时测试文件放到test/unit/src/源文件相对路径.test.ts。实战示例为 Task #2src/utils/versions.ts补写测试以 Simple 段中的 Task #2 为例说明从读源码到测试通过的完整流程。第 1 步读被测模块确定导出内容与依赖。src/utils/versions.ts 导出readOperatorVersions()它通过fs.readFileSync读取 CLI/GUI 两个 package.json 文件路径常量来自FilePaths.CLI_PACKAGE/FilePaths.GUI_PACKAGE并用shardeum-foundation/lib-types的Utils.safeJsonParse解析版本。依赖涉及文件系统属于 todo 清单策略中需要 mock 外部依赖的情况。第 2 步参考同一目录下已有的测试模式。test/unit/src/utils/versions.test.ts 就是该模块的测试文件其结构是仓库内带依赖 mock 的单测标准写法// Mock fs module jest.mock(fs) // Mock lib-types jest.mock(shardeum-foundation/lib-types) describe(versions, () { let mockReadFileSync: jest.Mock let mockSafeJsonParse: jest.Mock beforeEach(() { jest.clearAllMocks() // Clear the module cache to ensure fresh imports jest.resetModules() // Set up mocks mockReadFileSync jest.fn() mockSafeJsonParse jest.fn((data) JSON.parse(data)) // Apply mocks jest.doMock(fs, () ({ readFileSync: mockReadFileSync })) jest.doMock(shardeum-foundation/lib-types, () ({ Utils: { safeJsonParse: mockSafeJsonParse } })) }) describe(readOperatorVersions, () { it(should read both CLI and GUI versions successfully, () { const mockCLIPackage JSON.stringify({ version: 1.2.3 }) const mockGUIPackage JSON.stringify({ version: 4.5.6 }) mockReadFileSync.mockImplementation((path) { if (path FilePaths.CLI_PACKAGE) return Buffer.from(mockCLIPackage) if (path FilePaths.GUI_PACKAGE) return Buffer.from(mockGUIPackage) throw new Error(Unexpected path: ${path}) }) // Import the function after mocks are set up const { readOperatorVersions } require(../../../../src/utils/versions) const result readOperatorVersions() expect(result).toEqual({ operatorCLIVersion: 1.2.3, operatorGUIVersion: 4.5.6 }) // ... }) }) })注意其中的要点mock 在beforeEach中用jest.doMock注册配合全局resetMocks/clearMocks配置被测模块用require在 mock 生效之后才加载测试覆盖了两个文件都读取成功单个文件读取失败返回空字符串JSON 解析失败package.json 缺少 version 字段等分支这些分支都来自被测函数自身的处理逻辑。对更简单的模块如 Task #1 的常量文件 src/utils/constants.ts则不需要任何 mock直接断言导出值即可参考 test/unit/src/utils/constants.test.tsimport { zeroAddressStr, emptyCodeHash, zeroAddressAccount } from ../../../../src/utils/constants describe(constants, () { it(should be a valid ethereum zero address, () { expect(zeroAddressStr).toBe(0x0000000000000000000000000000000000000000) }) })第 3 步按同样模式补写你认领的任务。无论哪个任务流程都是读源文件确认导出和依赖 → 在test/unit/src/对应位置新建*.test.ts→ 有外部依赖就按versions.test.ts的模式 mock没有就直接断言。验证测试CLAUDE.md 的 Essential Commands 一节给出两条命令# 只跑某一个测试文件path/to/test.ts 换成实际路径 npm test -- test/unit/src/utils/versions.test.ts # 跑全部测试 npm test两点说明package.json中配置了pretest: npm run compile所以每次执行npm test包括单文件都会先执行tsc -p .编译 TypeScript。新测试文件如果 import 了不存在的导出会在这一步或 ts-jest 转换时报错提交前再跑 CLAUDE.md 要求的代码质量检查npm run lint npm run format-check判断测试是否完成单文件命令的 Jest 输出显示该文件所有用例通过随后全量npm test不因为你新增的文件而引入失败。unit-tests-todo.md 中建议的工具类 80%、关键逻辑 90% 覆盖目标是文档给出的方向性建议仓库的普通npm test脚本未带--coverage参数如需量化覆盖情况需要自行在 Jest 命令上加 coverage 参数仓库中只有test:smoke等集成脚本默认带--coverage且它们运行的是多节点集成测试不适合作为补单元测试的验证手段。限制与注意事项清单中的路径带有/home/marc/work/shardeum/前缀落到本仓库时统一去掉只保留src/...部分测试中不要 importsrc/index.ts等聚合入口——test/unit/setup.ts 已将其 mock 为空对象直接 import 具体源文件即可不要动test/testCases/下的内容当作单元测试roots虽然同时包含该目录但那里是集成/冒烟测试如 test/testCases/transactionPoC.test.ts且 test/README.md 说明其运行需要json-rpc-server在后台运行等前置条件与补单元测试是两个任务若你在 Simple 段认领了纯导出index.ts文件Task #9–#18 一类可按 todo 清单 Notes 的说法跳过或只做最基础的导出存在性验证debug/目录任务可放低优先级。按 todo 清单的建议顺序推进即可先 Simple类型定义、常量、工具函数再 Medium单一职责模块如 precompiles、storage最后 ComplexEVM 解释器、状态管理等核心实现。每完成一个任务回到 unit-tests-todo.md 勾选对应的- [ ]保持计划与实际进度一致。【免费下载链接】shardeumShardeum is an EVM based autoscaling blockchain项目地址: https://gitcode.com/GitHub_Trending/sh/shardeum创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考