如何在 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,它會告訴你收到的是否就是寫出的。
接下來