roblox-ts-jest-jack
v0.1.6
Published
## 项目概述
Readme
Roblox-TS-Jest-Jack
项目概述
Roblox-TS-Jest-Jack 是一个同时支持本地 Node 环境和 Roblox 环境的 Jest 测试框架,为 Roblox-TS 项目提供完整的单元测试覆盖方案。
*.jack.ts支持在双环境同时运行*.spec.ts仅支持在 Roblox 运行
特性
- 双环境测试架构:本地开发与 Roblox 运行时验证
- 以
SKIP_LOCAL标签跳过本地测试 - 全面的边界测试覆盖:包含数百个边界情况测试用例
- 环境差异自动处理:自动适配JavaScript和Lua的行为差异
测试覆盖率
当前测试状态:
- Roblox环境: 783/783 测试全部通过 ✅
- 本地环境: 773/785 测试通过(12个被跳过)✅
- 边界测试: 新增数百个边界情况测试用例,覆盖8+核心模块
安装
安装依赖
npm install roblox-ts-jest-jack配置 Jest config
创建 jest.config.cjs:
const baseConfig = require("roblox-ts-jest-jack/jest.config.cjs");
module.exports = {
...baseConfig,
// 自定义配置
};使用方法
本地测试
# 运行所有测试
npx jest
# 监视模式下运行测试
npx jest --watchRoblox 环境测试
推荐使用 jest-lua-companion-cli , 在本地环境同样可以发起 roblox 测试.
运行Roblox测试的正确流程:
# 1. 先编译项目
npm run compile
# 2. 运行Roblox测试
npm run testRoblx测试用例编写
注意 roblox 测试的偏差: Jest Lua Deviations
// src/server/testable/__tests__/calculator.jack.ts
import { describe, expect, it } from "@rbxts/jest-globals";
import { Calculator } from "../calculator";
describe("计算器测试", () => {
const calculator = new Calculator();
it("加法测试", () => {
expect(calculator.add(1, 2)).toBe(3);
expect(calculator.add(-1, 1)).toBe(0);
expect(calculator.add(0, 0)).toBe(0);
});
// 边界情况测试示例
describe("边界情况测试", () => {
it("应该处理大数运算", () => {
const bigNum = 1e308;
expect(calculator.add(bigNum, 1)).toBe(bigNum);
});
it("应该处理极小数运算", () => {
const smallNum = 1e-323;
expect(calculator.add(smallNum, smallNum)).toBe(smallNum * 2);
});
});
});设置忽略标记
使用 LOCAL_SKIP 标记可以在本地环境中跳过特定测试:
it("LOCAL_SKIP 这个测试在本地环境中会被跳过", () => {
// 测试内容
});vsc 调试
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Current Jest File (Corrected Path)",
"type": "node",
"request": "launch",
"runtimeExecutable": "node", // 明确是 node
"runtimeArgs": ["${workspaceFolder}/node_modules/jest/bin/jest.js"],
"args": [
"--runInBand",
"--config=${workspaceFolder}/jest.config.cjs",
"--no-cache",
"--runTestsByPath",
"${file}"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"sourceMaps": true,
"skipFiles": ["<node_internals>/**", "node_modules/**"]
},
{
"name": "Attach to Jest",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true,
"sourceMaps": true,
"skipFiles": ["<node_internals>/**", "node_modules/**"]
}
]
}技术解决方案
项目通过以下技术解决了环境差异问题:
- Polyfill:模拟 Roblox 特有函数和方法
- Mock Jest Globals: 在本地修改
jest globals对象, 以模拟 Jest Lua Deviations - 环境适配:自动处理JavaScript和Lua的行为差异
- 模运算差异:Lua风格 vs JavaScript风格的
%运算符行为 - 字符串操作:
string.sub的边界行为差异 - 数组操作:稀疏数组和NaN处理的差异
- 浮点数精度:极小数处理的环境差异
- 模运算差异:Lua风格 vs JavaScript风格的
边界测试覆盖
项目包含全面的边界情况测试,覆盖以下8个主要类别:
- 空值/边界值处理:空数组、空字符串、零值等
- 类型边界:极大数、极小数、NaN、Infinity等
- 索引边界:数组越界、字符串超范围访问等
- 运算边界:除零、模运算、溢出等
- 控制流边界:空循环、嵌套结构、异常退出等
- 函数边界:无参数、大量参数、递归深度等
- 对象边界:空对象、动态属性、原型链等
- 循环边界:边界值、浮点步长、复杂控制等
常见问题
为什么需要两种测试环境?
- 本地测试提供快速反馈循环
- 本地测试可以进行断点调试
- Roblox 测试确保在真实环境中的兼容性
如何处理 Roblox 特有功能?
- 对于简单功能,通过 polyfill 模拟
- 对于复杂功能,考虑使用依赖注入或接口
如何优化测试性能?
- 将大型测试套件分解为较小的模块
- 优先在本地环境测试,减少 Roblox 测试次数
模运算行为差异如何处理?
- 项目自动检测环境并适配不同的模运算行为
- 边界测试使用在两个环境中都一致的正数情况
已解决的环境差异
以下问题已通过polyfill和环境适配解决:
- ✅ 模运算差异:JavaScript vs Lua的
%运算符行为 - ✅ 字符串边界:
string.sub的边界情况处理 - ✅ 数组稀疏性:稀疏数组的size计算差异
- ✅ NaN格式化:join操作中NaN的大小写差异
- ✅ 浮点精度:极小数运算的环境差异处理
剩余局限性
已知问题(影响较小)
- 位运算的细微差异
- 部分数组特殊方法的完全兼容性
- 模板字符串的高级功能
- 复杂的this绑定场景
- 字符串gmatch的解构支持
- 负数模运算
测试通过率:
- Roblox环境:100% (783/783)
- 本地环境:98.5% (773/785,12个跳过)
许可证
本项目采用 MIT 许可证
Credits
- https://github.com/littensy
- https://github.com/littensy/charm-example
- https://github.com/roblox-ts/roblox-ts
