Skip to content

Commit 4e49d9e

Browse files
committed
Codes Review Checklist for YAML API Tests (No UI Required)
1 parent 247779b commit 4e49d9e

1 file changed

Lines changed: 386 additions & 0 deletions

File tree

Lines changed: 386 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,386 @@
1+
---
2+
title: "Codes Review Checklist for YAML API Tests (No UI Required)"
3+
date: "2026-02-19"
4+
slug: "codes-review-checklist-for-yaml-api-tests-no-ui-required"
5+
id: "6373f29b-5b13-4c16-b18c-324b56229979"
6+
image:
7+
url: "https://kccqmbkylzrrhibpxtbk.supabase.co/storage/v1/object/public/public-user-assets/b460f601-795d-47ba-abf4-41fb76ccea6f/6373f29b-5b13-4c16-b18c-324b56229979/main-image.webp"
8+
alt: "Codes Review Checklist for YAML API Tests (No UI Required)"
9+
author:
10+
name: "DevTools Team"
11+
avatar: "/logo.svg"
12+
tags: ["ci","github-actions","pull-requests","git","yaml","api-testing"]
13+
category: "CI/CD"
14+
summary: "Code review checklist for YAML API tests: chaining, deterministic assertions, secrets hygiene, and CI rules. Review flows in Git, no UI required."
15+
cta:
16+
primary:
17+
heading: "Add YAML API tests to PR checks"
18+
body: "Run flows headless in CI and review changes in Git. Use the CI integrations guide to pin versions, wire secrets, and publish JUnit results."
19+
buttonText: "Set up CI integrations"
20+
url: "https://dev.tools/docs/how-to/ci-integrations/"
21+
secondaryText: "GitHub Actions template"
22+
secondaryUrl: "https://dev.tools/templates/github-actions/"
23+
secondary:
24+
heading: "Manage env vars and secrets safely"
25+
body: "Parameterize base URLs, tokens, and run IDs so flows stay deterministic across local runs, PR checks, and nightly CI."
26+
buttonText: "Environments & variables"
27+
url: "https://dev.tools/docs/how-to/environments-and-variables/"
28+
secondaryText: "Chaining with flows"
29+
secondaryUrl: "https://dev.tools/docs/how-to/working-with-flows/"
30+
badge:
31+
text: "PR checklist focus"
32+
variant: "neutral"
33+
---
34+
35+
If your API tests live in a UI, your “review” is mostly trust. A teammate says they updated a Postman collection, CI runs Newman, and you get a green check. The problem is that the test logic, chaining, and assertions are not first-class code artifacts, so reviewers cannot reliably answer the questions that matter: what changed, why it changed, and whether it will be deterministic in CI.
36+
37+
YAML-first API tests flip that. When flows are native YAML in Git, the pull request diff is the source of truth. This article is a practical **codes review checklist** (code review checklist) for YAML API tests that assumes experienced reviewers and CI-native workflows.
38+
39+
## What “reviewable” means for YAML API tests
40+
41+
A reviewable YAML API test has three properties:
42+
43+
- **Diffable**: the meaningful behavior change is visible in a Git diff (not hidden behind UI state or re-serialized exports).
44+
- **Deterministic**: it passes or fails for product reasons, not because timestamps moved, ordering changed, or the environment drifted.
45+
- **Composable**: request chaining is explicit, so the flow documents dependencies and can be re-run locally and in CI.
46+
47+
This is where YAML-native tooling differs from common alternatives:
48+
49+
- **Postman + Newman**: collections are JSON exports with a lot of incidental structure, plus test logic often lives in scripts. PR diffs tend to be noisy, and “reviewing” often means importing into Postman to understand intent.
50+
- **Bruno**: tests are stored as files, which is good, but the format is a custom DSL (`.bru`), so you still have a tool-specific representation to learn and standardize.
51+
- **Native YAML flows**: reviewers can read requests, variables, and assertions directly in the PR, and apply the same engineering standards as any other code.
52+
53+
If you are already using DevTools flows, the companion pieces worth keeping open while reviewing are:
54+
55+
- [Git-Friendly YAML API Tests: Formatting Rules That Keep Diffs Clean](https://dev.tools/blog/git-friendly-yaml-api-tests-formatting-rules-that-keep-diffs-clean/)
56+
- [Deterministic API Assertions: Stop Flaky JSON Tests in CI](https://dev.tools/blog/deterministic-api-assertions-stop-flaky-json-tests-in-ci/)
57+
- [API Testing in GitHub Actions: Secrets, Auth, Retries, Rate Limits](https://dev.tools/blog/api-testing-in-github-actions-secrets-auth-retries-rate-limits/)
58+
59+
![A Git pull request diff view showing a YAML API test file with a few added assertions, a renamed step, and a new extracted variable; the diff highlights make the behavioral change easy to review.](https://kccqmbkylzrrhibpxtbk.supabase.co/storage/v1/object/public/public-user-assets/b460f601-795d-47ba-abf4-41fb76ccea6f/6373f29b-5b13-4c16-b18c-324b56229979/image-0.webp)
60+
61+
## The PR checklist (what to verify, and why)
62+
63+
Use the table below as the baseline reviewer checklist. It is intentionally biased toward catching CI flakes, bad chaining, and non-reviewable diffs.
64+
65+
| Review area | What to look for in the diff | Why it matters in CI and Git |
66+
|------------|-------------------------------|------------------------------|
67+
| Secrets and auth | No tokens, cookies, API keys, session IDs, or PII committed. New auth mechanisms use env vars or CI secrets, not copied headers. | Prevents leaks and “works on my machine” sessions. Keeps flows shareable. |
68+
| Base URLs and environment | URLs are parameterized (per env) instead of hardcoded to a dev machine, preview URL, or a one-off tenant. | Makes the same flow runnable locally, in PR checks, and in nightly runs. |
69+
| Volatile headers | Removed or normalized headers like `User-Agent`, `Sec-*`, dynamic tracing headers, random request IDs, and anything browser-noisy. | HAR-derived tests often fail due to irrelevant browser headers. |
70+
| Request chaining | IDs, tokens, CSRF values, cursors, and `Location` headers are captured once and referenced later. No “magic” values in later steps. | Eliminates hidden coupling to pre-existing state. Improves debuggability. |
71+
| Assertions | Assertions validate invariants (types, presence, allowed values), not brittle full-body snapshots unless normalized. | Prevents flakes from timestamps, ordering, and irrelevant fields. |
72+
| Data isolation | Flow creates its own resources (unique run ID), does not rely on global fixtures unless explicitly managed. | Enables parallel runs and reduces cross-test interference. |
73+
| Cleanup | Created resources are deleted (or a teardown flow exists). For non-idempotent systems, the cleanup strategy is explicit. | Keeps environments from accumulating state and breaking later tests. |
74+
| Timing and retries | No unconditional sleeps. Polling/retry is scoped to eventual consistency points, with bounds and backoff. | Avoids slow, flaky pipelines and hidden timeouts. |
75+
| Naming and structure | Step names are stable and descriptive. Changes do not reorder large blocks without reason. | Makes diffs reviewable and maps cleanly to CI reports. |
76+
| CI compatibility | Flow can run headless without UI state. CI steps pin tool versions, emit JUnit/JSON, and preserve minimal artifacts for debugging. | Makes failures diagnosable and protects against tool drift. |
77+
78+
## 1) Secrets and sessions: “If it came from a browser, assume it is toxic”
79+
80+
Most review failures in YAML API tests come from accidentally committing replayable sessions.
81+
82+
During review, search the diff for:
83+
84+
- `Authorization: Bearer ...` literals
85+
- `Cookie:` literals
86+
- `X-CSRF-Token` values
87+
- JWT-looking strings (`eyJ...`)
88+
- Email addresses, phone numbers, tenant IDs
89+
90+
If the YAML was generated from HAR, enforce this policy:
91+
92+
- Raw `.har` files are not committed.
93+
- YAML flows are committed only after **redaction** and **parameterization**.
94+
95+
Reference: [How to Redact HAR Files Safely (Keep Tests Shareable, Remove Secrets)](https://dev.tools/blog/how-to-redact-har-files-safely-keep-tests-shareable-remove-secrets/).
96+
97+
A reviewer-friendly pattern is “declare secrets as environment variables, chain everything else”. For example (illustrative YAML pattern):
98+
99+
```yaml
100+
env:
101+
BASE_URL: ${BASE_URL}
102+
API_TOKEN: ${API_TOKEN}
103+
104+
steps:
105+
- name: whoami
106+
request:
107+
method: GET
108+
url: ${BASE_URL}/v1/me
109+
headers:
110+
Authorization: Bearer ${API_TOKEN}
111+
assert:
112+
status: 200
113+
jsonpath:
114+
"$.id":
115+
exists: true
116+
```
117+
118+
Review question to ask: **Does this flow still work if I rotate credentials and run it in a clean environment?** If the answer is “no”, it is not ready.
119+
120+
## 2) Request chaining: make dependencies explicit, or expect flakes
121+
122+
Chaining is where YAML tests either become reliable workflow checks or degrade into “copy/paste a bunch of requests”. The review goal is to ensure each step’s inputs come from:
123+
124+
- environment variables (for configuration)
125+
- extracted values from prior responses (for runtime correlation)
126+
- deterministic literals (for constants)
127+
128+
A practical chain example (illustrative YAML pattern):
129+
130+
```yaml
131+
steps:
132+
- name: login
133+
request:
134+
method: POST
135+
url: ${BASE_URL}/auth/login
136+
headers:
137+
Content-Type: application/json
138+
body:
139+
email: ${TEST_USER_EMAIL}
140+
password: ${TEST_USER_PASSWORD}
141+
extract:
142+
access_token: "$.accessToken"
143+
assert:
144+
status: 200
145+
jsonpath:
146+
"$.accessToken":
147+
type: string
148+
149+
- name: create_project
150+
request:
151+
method: POST
152+
url: ${BASE_URL}/v1/projects
153+
headers:
154+
Authorization: Bearer ${access_token}
155+
Content-Type: application/json
156+
body:
157+
name: "ci-${RUN_ID}"
158+
extract:
159+
project_id: "$.id"
160+
assert:
161+
status: 201
162+
jsonpath:
163+
"$.id":
164+
type: string
165+
166+
- name: get_project
167+
request:
168+
method: GET
169+
url: ${BASE_URL}/v1/projects/${project_id}
170+
headers:
171+
Authorization: Bearer ${access_token}
172+
assert:
173+
status: 200
174+
jsonpath:
175+
"$.name":
176+
equals: "ci-${RUN_ID}"
177+
```
178+
179+
Reviewer checks that catch real bugs:
180+
181+
- **No hidden coupling**: if `project_id` appears as a literal anywhere, send it back.
182+
- **Chaining happens immediately**: capture the ID in the response that produced it (not three steps later).
183+
- **Headers are not copy/pasted blindly**: later requests should carry only what they need.
184+
185+
If your org still relies on Postman scripts for this, you can often eliminate most scripting by making correlation explicit in YAML, which is easier to review and harder to accidentally break.
186+
187+
For deeper chaining and multi-step business logic patterns, keep this handy: [API Workflow Automation: Testing Multi-Step Business Logic](https://dev.tools/guides/api-workflow-automation/).
188+
189+
## 3) Assertions: prefer invariants over snapshots (unless you normalize)
190+
191+
Reviewers should treat assertions as the contract of the flow. The anti-pattern is “status 200 everywhere” plus an occasional brittle full-body comparison.
192+
193+
A good assertion set usually contains:
194+
195+
- **status**: including expected non-200s for negative cases
196+
- **headers**: content type, cache policy where relevant, location headers on creates
197+
- **body invariants**: existence, type checks, enum membership, numeric bounds
198+
199+
Illustrative YAML assertion pattern:
200+
201+
```yaml
202+
- name: list_projects
203+
request:
204+
method: GET
205+
url: ${BASE_URL}/v1/projects?limit=50
206+
headers:
207+
Authorization: Bearer ${access_token}
208+
assert:
209+
status: 200
210+
headers:
211+
Content-Type:
212+
contains: "application/json"
213+
jsonpath:
214+
"$.items":
215+
type: array
216+
"$.items[0].id":
217+
exists: true
218+
```
219+
220+
Review guidance for “snapshot-like” expectations:
221+
222+
- If the diff adds a snapshot, require evidence it is **canonicalized** (timestamps removed, ordering normalized, IDs redacted) or it will flake.
223+
- If a field is inherently unstable (timestamps, UUIDs, ETags, request IDs), assert format/type, not equality.
224+
225+
References:
226+
227+
- [JSON Assertion Patterns for API Tests: A Practical Guide (with YAML Examples)](https://dev.tools/blog/json-assertion-patterns-for-api-tests-a-practical-guide-with-yaml-examples/)
228+
- [Schema vs Snapshot Testing for APIs: What Actually Works in CI](https://dev.tools/blog/schema-vs-snapshot-testing-for-apis-what-actually-works-in-ci/)
229+
230+
## 4) Data isolation and cleanup: design for parallel runs
231+
232+
If your pipeline shards flows or runs them concurrently, reviewers must reject any test that assumes shared mutable state.
233+
234+
The simplest review rule is:
235+
236+
- Every flow that creates data must either delete it, or namespace it under a unique `RUN_ID`.
237+
238+
Illustrative cleanup pattern:
239+
240+
```yaml
241+
steps:
242+
- name: delete_project
243+
request:
244+
method: DELETE
245+
url: ${BASE_URL}/v1/projects/${project_id}
246+
headers:
247+
Authorization: Bearer ${access_token}
248+
assert:
249+
status:
250+
any_of: [200, 204]
251+
```
252+
253+
If deletion is not reliable (event-driven cleanup, soft deletes, async), the reviewer should insist on one of:
254+
255+
- a bounded polling step that waits until the resource disappears
256+
- a separate teardown flow that runs even on failure (CI responsibility)
257+
258+
Also watch for “test-only fixtures” that are shared across runs. Those are fine if they are immutable and clearly marked as such. Otherwise, they create order dependence.
259+
260+
## 5) Timing, retries, and eventual consistency: no unconditional sleeps
261+
262+
If a diff introduces `sleep: 5000` (or equivalent), it is usually a smell.
263+
264+
What to accept instead:
265+
266+
- retries scoped to specific transient statuses (for example 409/429/503)
267+
- polling loops that terminate with a hard timeout
268+
- idempotency keys on retried creates
269+
270+
During review, ask:
271+
272+
- **What failure mode is this retry masking?**
273+
- **Is the operation idempotent?** If not, how do we prevent duplicate writes?
274+
- **Are we respecting rate limits?** If a flow runs in 10 shards, “just retry” can become a thundering herd.
275+
276+
This is a CI plumbing issue as much as a test issue, see: [API Testing in GitHub Actions: Secrets, Auth, Retries, Rate Limits](https://dev.tools/blog/api-testing-in-github-actions-secrets-auth-retries-rate-limits/).
277+
278+
## 6) YAML hygiene: optimize diffs for humans, not serializers
279+
280+
A large percentage of “bad reviews” happen because the diff is unreadable.
281+
282+
Reviewers should enforce:
283+
284+
- stable key ordering
285+
- sorted headers and query params
286+
- consistent quoting for ambiguous scalars
287+
- block scalars for large JSON bodies (to avoid single-line noise)
288+
- stable step naming (renames are meaningful, not cosmetic)
289+
290+
If a PR contains massive reorder-only diffs, send it back and ask for:
291+
292+
- formatting changes isolated in their own commit, or
293+
- a pre-commit formatter so the team stops fighting the same battle
294+
295+
Reference: [YAML API Test File Structure: Conventions for Readable Git Diffs](https://dev.tools/blog/yaml-api-test-file-structure-conventions-for-readable-git-diffs/).
296+
297+
## 7) CI review points: pin versions, emit artifacts, keep failures actionable
298+
299+
Even with perfect YAML, CI can rot. Reviewers should check the workflow changes (if any) with the same seriousness as test changes.
300+
301+
Key items to verify in CI YAML:
302+
303+
- **Pinned tool versions** (runner image, actions, the test runner CLI)
304+
- **JUnit output** published so failures show up in the PR UI
305+
- **Artifacts** uploaded (logs, minimal results), but not raw secrets or full unredacted payload dumps
306+
307+
A minimal example of “pin and report” (illustrative GitHub Actions snippet):
308+
309+
```yaml
310+
- name: Run API flows
311+
run: |
312+
./devtools run ./flows --report-junit ./artifacts/junit.xml --report-json ./artifacts/results.json
313+
314+
- name: Upload artifacts
315+
uses: actions/upload-artifact@<pinned-commit-sha>
316+
with:
317+
name: api-test-artifacts
318+
path: artifacts/
319+
```
320+
321+
For more complete CI patterns (parallel shards, caching, PR reporting), see:
322+
323+
- [API regression testing in GitHub Actions](https://dev.tools/guides/api-regression-testing-github-actions/)
324+
- [Pinning GitHub Actions + Tool Versions: Stop CI Breakage (DevTools Included)](https://dev.tools/blog/pinning-github-actions-tool-versions-stop-ci-breakage-devtools-included/)
325+
- [JUnit Reports for API Tests: Make GitHub Actions Show Failures Cleanly](https://dev.tools/blog/junit-reports-for-api-tests-make-github-actions-show-failures-cleanly/)
326+
327+
## Review heuristics by change type
328+
329+
### New flow added
330+
331+
Look for correctness and maintainability:
332+
333+
- flow starts from a clean, reproducible auth step (or uses a documented token source)
334+
- every step asserts something meaningful
335+
- chain values are extracted and reused, no copied IDs
336+
- cleanup exists, or there is a documented reason it cannot
337+
338+
### Existing flow modified
339+
340+
Look for “intent alignment”:
341+
342+
- assertion changes are explained by an API contract change, not by “make CI green”
343+
- removed assertions have a justification
344+
- request changes do not introduce browser-only noise
345+
346+
### Refactor only
347+
348+
Look for safety:
349+
350+
- no behavior change hidden in formatting
351+
- step renames preserve stable reporting identifiers (important for JUnit history)
352+
- reordered blocks are justified (or avoided)
353+
354+
## Red flags that should block a merge
355+
356+
- committed secrets or replayable sessions
357+
- hard-coded environment-specific URLs
358+
- sleeps added instead of bounded polling
359+
- snapshot assertions added without normalization
360+
- “status 200 only” checks for business-critical steps
361+
- shared global resources without namespacing or cleanup
362+
363+
## Frequently Asked Questions
364+
365+
**What should I review first in a YAML API test PR?** Start with secrets and determinism: verify no committed tokens/cookies, no hard-coded env URLs, and no brittle snapshot assertions.
366+
367+
**How is YAML test review different from Postman/Newman review?** With YAML in Git, you can review requests, chaining, and assertions directly in the PR diff. Postman collections often require importing into a UI to understand behavior.
368+
369+
**What is the biggest cause of flaky YAML API tests in CI?** Hidden coupling to state (hard-coded IDs, shared fixtures) and unstable assertions (timestamps, ordering, non-canonical snapshots). Second is auth drift (expired sessions copied from browsers).
370+
371+
**Should we allow snapshot testing in YAML flows?** Yes, but only for payloads that are canonicalized and redacted. Otherwise snapshots tend to fail on harmless changes.
372+
373+
**How do I keep request chaining readable as flows grow?** Extract values as close as possible to where they are produced, reference them immediately, and keep step names stable and specific.
374+
375+
**What should we store as CI artifacts for API test runs?** Store JUnit XML and minimal logs/results for debugging. Avoid raw HARs and full unredacted request/response dumps unless you have a redaction policy.
376+
377+
## Put the checklist into practice with Git-native YAML flows
378+
379+
If your team is trying to get out of UI-locked test definitions (or make Postman/Newman runs actually reviewable), the fastest path is to standardize on native YAML flows in Git and enforce the checklist above in PRs.
380+
381+
DevTools is built around that workflow: record real traffic, export human-readable YAML, review it in pull requests, and run it locally or in CI. Start with the CI setup guide, then tighten your review standards:
382+
383+
- [API regression testing in GitHub Actions](https://dev.tools/guides/api-regression-testing-github-actions/)
384+
- [Git Workflow for YAML API Tests: PR Checks, Reports, Merge Rules](https://dev.tools/blog/git-workflow-for-yaml-api-tests-pr-checks-reports-merge-rules/)
385+
386+
Get the tool and keep your tests local-first and Git-first: [https://dev.tools](https://dev.tools)

0 commit comments

Comments
 (0)