> ## Documentation Index
> Fetch the complete documentation index at: https://niceeval.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 隐藏测试判分：让判据文件进缓存 fingerprint

> 用 loadText 在模块顶层读入隐藏测试、跑测脚本等判据文件，文件内容进入 fingerprint：改一字节自动重跑，不靠人工 --rerun。

沙箱 coding 题常用一份隐藏测试判分：Agent 改完代码后，评估用例把测试文件写进 Sandbox 执行，
测试通过就算过。这份测试文件就是判分标准本体——改了它，等于换了一道题，旧结果不能再采信。

用 `loadText` 读它，NiceEval 会把文件内容算进这条评估用例的 fingerprint：
文件改一字节，下次运行这条评估用例自动重跑，其它评估用例照常复用缓存。
用 `fs.readFile` 自己读拿到的内容一样，但 NiceEval 不知道这次读取发生过——
改了测试文件，缓存照常命中，你看到的是拿旧测试判出来的旧结论。

## 步骤

1. 判据文件与评估用例一起放进仓库：

   ```text theme={null}
   evals/
     react-datepicker/
       pr-6058.eval.ts
     fixtures/react-datepicker/pr-6058/
       tests/datepicker_test.test.tsx   # 隐藏测试
       tests/run-tests.sh               # 跑测脚本
   ```

2. 在 `.eval.ts` 的**模块顶层**读入：

   ```typescript theme={null}
   import { defineEval } from "niceeval";
   import { loadText } from "niceeval/loaders";
   import { commandSucceeded } from "niceeval/expect";

   const fixture = (p: string) =>
     new URL(`../fixtures/react-datepicker/pr-6058/${p}`, import.meta.url);

   const hiddenTest = await loadText(fixture("tests/datepicker_test.test.tsx"));
   const runTests = await loadText(fixture("tests/run-tests.sh"));
   ```

   路径写项目根相对的字符串也可以：`loadText("evals/fixtures/react-datepicker/pr-6058/tests/run-tests.sh")`。
   `loadText` 直接收 `URL` 对象，不需要 import `node:url`。

3. 在 `test(t)` 里写进 Sandbox 并执行：

   ```typescript theme={null}
   export default defineEval({
     description: "react-datepicker pr-6058",
     async test(t) {
       await t.send("修复 changeMonth 面板错位问题。不要改测试文件。");
       await t.sandbox.writeText("src/test/datepicker_test.test.tsx", hiddenTest);
       await t.sandbox.writeText("tests/run-tests.sh", runTests);
       t.check(await t.sandbox.runCommand("bash", ["tests/run-tests.sh"]), commandSucceeded());
     },
   });
   ```

改一下 `datepicker_test.test.tsx` 再跑同一条命令，只有这条评估用例重跑，验证生效。

## 注意

* **`loadText` 必须写在模块顶层。** 缓存判断发生在运行之前，写进 `test(t)` 里运行期才读就来不及了，
  NiceEval 会直接报错并提示挪到顶层。
* **读 Agent 的产物用 `t.sandbox`，不用 `loadText`。** Sandbox 里 Agent 跑出来的文件是本次运行的证据，
  每次都不同，不属于 fingerprint。用 `t.sandbox.file(...)` 一类断言去读。
* 判据是结构化数据（case 对照表）时用 `loadYaml` / `loadJson`，
  见[数据驱动测试](/docs/zh/tutorials/dataset-fanout)。
