如何在 CI 流水线中生成测试文件
仓库里的二进制 fixture 会永远留在历史中,无法在 diff 里审查,文件一大就根本行不通。请改为在流水线内部用配方生成这些文件。配方是文本,每次生成的字节都相同,最后一步还能证明什么都没有变动。
简短回答
安装 tfg,在测试之前运行 tfg generate fixtures.yaml --out ./fixtures,在测试之后运行
tfg verify ./fixtures/manifest.json。这两步都会自行让构建失败,并给出说明原因的退出码。
为什么不提交
为什么 fixture 不该放在仓库里
- 它会留在历史中。之后再删除二进制文件也不会让克隆变小,因为它的每个版本都还在。
- diff 看不出改了什么。审查者只看到一个 PDF 不同了,仅此而已。配方的变化只有一行。
- 大文件放不下。GitHub 会拒绝包含超过 100 MB 文件的推送,所以一个 500 MB 上传限制的测试没有什么可提交的。
该提交的是配方。相同的配方和种子在每台机器上写出相同的字节,所以在流水线里生成的文件,就是你在笔记本上用过的那个文件。
配方
放在测试旁边的配方
这个配方写出二十五张应被接受的发票和两张超过限制、应被拒绝的图片,清单会记录这两种预期:
version: 1
seed: 7741
targets:
- id: invoices
format: pdf
count: 25
size: 300kb
expected: accept
- id: over_the_limit
format: png
count: 2
size: 12mb
expected:
outcome: reject
reason: size_limit
tfg validate fixtures.yaml 会检查它而不写入任何内容,并一次列出所有问题。
GitHub Actions
安装工具并构建 fixture 的工作流
jobs:
test:
runs-on: ubuntu-latest
env:
TFG_VERSION: "0.4.0"
steps:
- uses: actions/checkout@v4
- name: install tfg
run: |
base=https://github.com/donislawdev/TestingFilesGenerator/releases/download/v$TFG_VERSION
curl -fsSLO "$base/tfg_${TFG_VERSION}_linux_amd64.tar.gz"
curl -fsSLO "$base/verify-SHA256SUMS.txt"
sha256sum --check --ignore-missing verify-SHA256SUMS.txt
tar -xzf "tfg_${TFG_VERSION}_linux_amd64.tar.gz" ./tfg
sudo mv tfg /usr/local/bin/
- name: build the fixtures
run: tfg generate fixtures.yaml --out ./fixtures
- name: run the tests
run: pytest tests/
- name: nothing moved
run: tfg verify ./fixtures/manifest.json
校验和那一行把压缩包与同一发行版中的 verify-SHA256SUMS.txt 比对。版本是固定的,所以新发行版绝不会改变你没动过的构建。
GitLab CI
同样的事,写成 GitLab 作业
fixtures:
image: ubuntu:24.04
variables:
TFG_VERSION: "0.4.0"
script:
- apt-get update -qq && apt-get install -y -qq curl ca-certificates
- base=https://github.com/donislawdev/TestingFilesGenerator/releases/download/v$TFG_VERSION
- curl -fsSLO "$base/tfg_${TFG_VERSION}_linux_amd64.tar.gz"
- curl -fsSLO "$base/verify-SHA256SUMS.txt"
- sha256sum --check --ignore-missing verify-SHA256SUMS.txt
- tar -xzf "tfg_${TFG_VERSION}_linux_amd64.tar.gz" ./tfg
- ./tfg generate fixtures.yaml --out ./fixtures
- pytest tests/
- ./tfg verify ./fixtures/manifest.json
变红的时候
什么会让一个步骤失败,为什么
每种结局都有自己的退出码,所以步骤会自行失败,日志会说明是哪一种。流水线会遇到的有:
3- 配方无效。没有写入任何内容,每个问题都会被指出4- 格式做不到所要求的事,例如小于它最小值的大小6- 磁盘空间不足7-tfg verify发现一个与其清单不符的文件8- 运行已结束,但并非所有内容都已生成
失败的运行不会向标准输出打印任何内容,所以日志解析器永远不会把错误当成数据。完整的表格在文档页面上。
PowerShell
PowerShell 脚本还需要多写一行
PowerShell 不会把程序的退出码带出 .ps1 文件。用 -File 运行一个脚本,即使里面的工具拒绝了工作,脚本也会返回
0,于是本该变红的构建变成了绿色。最后一行就是全部的修复:
tfg generate fixtures.yaml --out ./fixtures
exit $LASTEXITCODE
这是 PowerShell 的行为,与本工具无关。cmd、bash 和 zsh 不需要额外处理。
多个作业
在作业之间共享 fixture
通常不需要上传它们。因为相同的配方写出相同的字节,每个作业都可以运行自己的 tfg
generate,这比上传再下载更快。当一个作业必须接收另一个作业的文件时,在传输之后对清单运行 tfg verify,它会告诉你收到的是否就是写出的。
接下来