vinicq/falsegreen-robot
GitHub: vinicq/falsegreen-robot
falsegreen-robot 通过确定性静态扫描,查找 Robot Framework 测试中未进行有效验证却显示通过(绿灯)的「误报」测试用例。
Stars: 1 | Forks: 0
# falsegreen-robot
**一个问题,一个工具:误报。** falsegreen-robot 用于查找 Robot Framework 测试中那些在没有进行任何有效验证就显示通过(绿灯)的测试 —— 这些测试因为没有关键字验证任何内容、失败被吞没、检查永远为真或测试被跳过,从而放行了错误行为。
基于官方 Robot Framework 解析器(`robot.api.get_model`)的确定性静态扫描 —— 无需执行。它是 [falsegreen](https://github.com/vinicq/falsegreen) (Python/pytest) 和 [falsegreen-js](https://github.com/vinicq/falsegreen-js) (JS/TS) 的同胞项目。基于语义和意图的检查位于 [falsegreen-skill](https://github.com/vinicq/falsegreen-skill)。
## 为什么需要
一个全绿的 Robot 测试套件并不能证明其正确性。一个测试用例可能运行了关键字却从未调用验证关键字;`Run Keyword And Ignore Error` 可能会掩盖失败;`Should Be True ${TRUE}` 永远不会失败。该工具会在这些模式进入代码审查之前,标记出解析器能够证明的模式。
## 安装
```
pip install falsegreen-robot
```
## 用法
```
falsegreen-robot # scan cwd
falsegreen-robot tests/ # scan a path
falsegreen-robot --json # machine-readable output
falsegreen-robot --output report.json # write to a file
falsegreen-robot --output .falsegreen/ # write report. into a directory
falsegreen-robot --disable C16 # turn off specific codes
```
每个发现的问题都会报告其金字塔层级(unit / integration / e2e,从测试套件导入的库中读取)以及一行修复提示,同时摘要会按层级细分发现的问题,并列出最常见的修复方法。`--output` 可以接收文件或目录:对于无扩展名或以斜杠结尾的路径(例如 `.falsegreen/`),将根据所选格式生成 `report.` 文件。报告属于运行产物;请将输出目录加入 gitignore。
退出代码:`0` 表示正常,`10` 表示仅存在低置信度问题,`20` 表示存在高置信度问题。在 CI 中配置退出代码为 `20` 以阻止合并。
## 检测内容
Robot 中的预言机(Oracle)是**验证关键字**。扫描器能够跨库识别它们(`Should` 命名约定以及特定库的形式:SeleniumLibrary 的 `Element Should Be Visible`,Browser 的断言引擎 `Get Text sel == expected`,RESTinstance 的 schema 关键字,DatabaseLibrary 的 `Row Count Should Be Equal`,以及自定义的 `Verify*`/`Assert*` 关键字)。不包含上述任何内容的测试不进行任何验证。
| 代码 | 置信度 | 标记内容 |
|---|---|---|
| C2 | 高 | 空测试用例、任务或关键字(未运行任何关键字) |
| C2b | 低 | 运行了关键字但无验证关键字(无预言机) |
| C3 | 高 | `Run Keyword And Ignore Error`/`Return Status` 掩盖了失败,状态从未被断言 |
| C5 | 高 | 永远为真(`Should Be True ${TRUE}`,对相等字面量使用 `Should Be Equal`) |
| C6 | 低 | 弱检查 —— 对裸变量使用 `Should Be True`(仅判断了布尔真值,而非实际比较) |
| C7 | 高 | 自我比较(`Should Be Equal ${x} ${x}`) |
| C16 | 低 | 将 `Sleep` 用作同步(时间依赖) |
| C21 | 低 | 验证仅在条件分支中运行(位于 `IF` / `Run Keyword If` 内) —— 可能永远不会执行 |
| C23 | 低 | 测试数据中包含硬编码的 IP 地址 URL(`http://10.0.0.5:8080`) —— 环境耦合 |
| C32 | 低 | 被跳过的测试(`robot:skip` / `Skip`) |
| R1 | 高 | 无论任何检查结果如何,`Pass Execution` 强制使测试通过 |
| R2 | 低 | 用户关键字命名类似验证器(`Verify`/`Assert`/`Should`...),但其主体未进行任何验证 —— 空壳预言机 |
| R3 | 高 | `.resource` 文件中包含 `*** Test Cases ***` —— 这是无效的;这些用例永远不会运行 |
| R4 | 高 | `No Operation` 是唯一的步骤 —— 测试/任务/关键字什么都没做 |
| R5 | 高 | 带有 `[Template]` 但没有数据行 —— 模板化测试运行了零个用例 |
扫描 `.robot` 和 `.resource` 文件中的 `*** Test Cases ***`、`*** Tasks ***` (RPA) 和 `*** Keywords ***` 定义。R2 捕捉到了导致漏报 C2b 的根本原因:一个测试调用了 `Verify Login` 看似受保护,但该关键字实际上从未断言任何内容。
### 可选项:可维护性组(默认关闭)
不属于误报(false-green)—— 测试仍然进行了验证 —— 因此默认关闭。使用 `--diagnostics` 启用。
分为三组,映射 `falsegreen` 和 `falsegreen-js`:`false-positive`(C*/R*,开启),`diagnostic`(D*,可选项),`coupling`(M*,可选项)。
| 代码 | 组别 | 标记内容 |
|---|---|---|
| D2 | diagnostic | 测试/任务级别的控制流(`IF`/`FOR`/`WHILE`/`TRY`)(指南建议避免这样做) |
| M2 | coupling | 包含过多步骤的测试/任务(指南建议最多约 10 个) |
```
falsegreen-robot --diagnostics # include D*/M* as warnings
```
在概念匹配的情况下,这些代码 ID 与同胞扫描器共享(C2/C2b/C3/C5/C7/C16/C21/C32)。
没有断言操作符的 Browser `Get` 关键字只是普通的 getter,因此唯一步骤为 `Get Text h1` 的测试会被识别为无验证(C2b)。
## 测试层级(金字塔)
falsegreen-robot 能够扫描金字塔各个层级的 Robot 测试套件。发现过程是与层级无关的 —— 它会读取任何 `.robot`/`.resource` 文件 —— 但有些代码会结合具体层级进行解读,因此在某一层级有效的模式在另一层级不会被标记。
- **Unit:** 具有边界替身的关键字逻辑。预言机是 `Should` 关键字。
- **Integration(API 和数据库):** 通过 RequestsLibrary 和 RESTinstance 进行的 API 测试(schema 关键字算作预言机),以及通过 DatabaseLibrary 进行的数据库测试(`Row Count Should Be Equal`、`Check If Exists In Database`)。它们是有意访问真实的 endpoint 或 datastore,因此在该层级,请求或数据行本身就是验证。
- **E2E:** Browser 库以及 SeleniumLibrary/Appium。页面断言(`Page Should Contain`、`Get Text ... == ...`)是预言机;在这个层级,渲染元素的存在是真实的检查,而不是弱检查。
在声称是 Unit 测试的用例中,如果实际上访问了真实的 API 或数据库,这本身就是一种代码异味(环境耦合,神秘访客),而不是测试层级的问题。C23 标记了最严重的形式:硬编码的 IP 地址 endpoint。
## 范围与诚实
静态扫描:它仅负责关键字结构所能证明的内容。它不会运行测试套件,因此无法发现仅存在于运行时的代码异味(Test Run War,跨套件的执行顺序依赖)。期望值是否与预期行为相矛盾属于语义范畴,应交由 `falsegreen-skill` 处理。精确率优于召回率:`C2b` 属于低置信度,因为自定义关键字可能在内部进行了断言,而其名称中并未包含 `Should`。
## 许可证
MIT,Vinicius Queiroz。
新贡献者会自动添加;该表格还根据 [all-contributors](https://allcontributors.org) 规范认可了非代码类贡献(文档、想法、基础设施、测试、研究)。
标签:Python, Robot Framework, 云安全监控, 无后门, 测试工具, 逆向工具, 静态分析