This document describes the comprehensive testing infrastructure used to validate RealWorld API implementations against the OpenAPI 3.0.1 specification. The testing system uses Postman collections executed via Newman CLI to perform automated API validation, ensuring that any backend implementation adheres to the contract defined in openapi.yml().
The testing infrastructure serves two primary purposes:
apps/api/ correctly implements all endpointsFor information about the OpenAPI specification that these tests validate, see API Specification. For details on running the reference implementation itself, see Reference Implementation. For CI/CD pipeline configuration, see CI/CD Pipelines.
Sources: api/Conduit.postman_collection.json1-10 api/openapi.yml1-20 api/README.md1-12
The testing system consists of three interconnected components that work together to validate API implementations:
Test Execution Flow Diagram
The testing architecture implements a three-layer validation approach. The OpenAPI specification openapi.yml1-919 serves as the source of truth, defining all 15 API endpoints, request/response schemas, and authentication requirements. The Postman collection Conduit.postman_collection.json1-2411 translates these specifications into executable test cases with embedded JavaScript assertions. The execution layer, coordinated by run-api-tests.sh1-20 uses Newman to run the collection and validate responses.
Sources: api/Conduit.postman_collection.json1-10 api/openapi.yml1-20 api/run-api-tests.sh1-20 Makefile66-77
The test suite is configurable through environment variables that control the test target and user credentials:
| Variable | Default | Description |
|---|---|---|
APIURL | https://api.realworld.io/api | Base URL of the API to test |
USERNAME | u{timestamp} | Username for test user registration |
EMAIL | {USERNAME}@mail.com | Email for test user |
PASSWORD | password | Password for test user |
DELAY_REQUEST | 500 | Milliseconds to wait between requests |
These variables are processed by run-api-tests.sh6-11 and passed to Newman as global variables via the --global-var flag run-api-tests.sh15-18
Sources: api/run-api-tests.sh6-11
Option 1: Test Against Already-Running Server
This method is defined in Makefile63-64 and directly invokes the test script with APIURL=http://localhost:3000/api.
Option 2: Automated Server Lifecycle
This target Makefile66-77 performs the complete test lifecycle:
JWT_SECRET setSERVER_PID)Sources: Makefile63-77 api/run-api-tests.sh1-20
The actual test execution uses Newman via bun x newman:
This command run-api-tests.sh13-19:
bun x to execute Newman without requiring global installation"$@"Sources: api/run-api-tests.sh13-19
Postman Collection Folder Organization
The collection Conduit.postman_collection.json8-2411 is organized into seven top-level folders that group related functionality:
Sources: api/Conduit.postman_collection.json8-2411
The collection uses Postman's global variables to maintain state across requests, enabling sequential test workflows:
State Management in Test Flow
Key state variables stored across requests:
| Variable | Set By | Used By | Purpose |
|---|---|---|---|
token | Login and Remember Token lines 141 | All authenticated endpoints | JWT authentication |
slug | Create Article line 676 | Article CRUD operations | Target specific article |
slug2 | Create Second Article line 744 | Pagination test cleanup | Second article for testing |
commentId | Create Comment lines 2103-2104 | Delete Comment | Target specific comment |
Example token storage script Conduit.postman_collection.json140-141:
Example token usage in Authorization header Conduit.postman_collection.json216:
Sources: api/Conduit.postman_collection.json120-148 api/Conduit.postman_collection.json660-693 api/Conduit.postman_collection.json728-747
Each request contains embedded JavaScript test scripts that validate response structure and content. The collection uses two assertion styles:
Legacy Style (using tests object):
Modern Style (using pm.test):
Example comprehensive property validation Conduit.postman_collection.json23-31:
Example ISO 8601 timestamp validation Conduit.postman_collection.json373:
Sources: api/Conduit.postman_collection.json19-34 api/Conduit.postman_collection.json326-340 api/Conduit.postman_collection.json356-389
The test suite provides comprehensive coverage of all 15 API endpoints defined in the OpenAPI specification:
| Category | Endpoint | Method | Test Requests | Authentication |
|---|---|---|---|---|
| User/Auth | /users | POST | 1 | No |
/users/login | POST | 2 | No | |
/user | GET | 2 | Yes | |
/user | PUT | 2 | Yes | |
| Profiles | /profiles/{username} | GET | 2 | Optional |
/profiles/{username}/follow | POST | 1 | Yes | |
/profiles/{username}/follow | DELETE | 1 | Yes | |
| Articles | /articles | GET | 7 | Optional |
/articles | POST | 2 | Yes | |
/articles/feed | GET | 1 | Yes | |
/articles/{slug} | GET | 2 | Optional | |
/articles/{slug} | PUT | 1 | Yes | |
/articles/{slug} | DELETE | 2 | Yes | |
| Comments | /articles/{slug}/comments | GET | 1 | Optional |
/articles/{slug}/comments | POST | 1 | Yes | |
/articles/{slug}/comments/{id} | DELETE | 1 | Yes | |
| Favorites | /articles/{slug}/favorite | POST | 2 | Yes |
/articles/{slug}/favorite | DELETE | 2 | Yes | |
| Tags | /tags | GET | 1 | No |
Total: 37 test requests across 15 unique endpoints
Sources: api/Conduit.postman_collection.json8-2411 api/openapi.yml21-453
The test suite validates multiple aspects of API behavior:
Every endpoint test validates that responses contain the expected properties and nested objects:
Tests verify that properties have the correct data types:
Specific tests validate that articlesCount represents total count, not page size:
The collection creates a second article lines 728-779 specifically to test pagination, then deletes it lines 877-911 to clean up.
Tests verify that updates persist across requests:
The "Verify Update User Persisted" request lines 292-342 fetches user data after an update to confirm changes were saved.
Multiple tests validate authentication mechanisms:
Article list tests validate query parameters:
GET /articles?author=johnjacob line 481GET /articles?tag=dragons line 637GET /articles?favorited={{USERNAME}} line 559GET /articles?limit=1 line 813GET /articles?limit=1&offset=1 line 856Sources: api/Conduit.postman_collection.json19-34 api/Conduit.postman_collection.json356-389 api/Conduit.postman_collection.json782-874 api/Conduit.postman_collection.json292-342
The testing infrastructure is integrated into the repository's build system through several Makefile targets:
Test Execution Flow via Makefile
reference-implementation-test-with-postman Makefile66-77
This target orchestrates the complete test lifecycle:
SERVER_PIDreference-implementation-test-with-postman-and-already-launched-server Makefile63-64
For faster iteration during development, this target assumes the server is already running and directly invokes the test script with:
DELAY_REQUEST=50 - Reduced delay for faster executionAPIURL=http://localhost:3000/api - Local server URLrunning-processes-clean Makefile82-87
This target ensures all Nitro dev server processes are terminated:
The || true ensures the Makefile doesn't fail if no processes are found.
Sources: Makefile63-87
The testing infrastructure is integrated into GitHub Actions workflows, enabling automated validation on every commit and pull request. The workflow configuration is located in .github/workflows/api.yaml and executes the same Makefile targets used for local development, ensuring consistency between local and CI environments.
For detailed information about the CI/CD pipeline configuration, triggers, and workflow steps, see CI/CD Pipelines.
Sources: Makefile66-77
The collection includes a sophisticated test sequence to validate pagination behavior, ensuring that articlesCount always represents the total count of matching articles, not the number returned in the current page:
Pagination Validation Sequence
The test sequence Conduit.postman_collection.json660-911:
slugslug2articles.length === 1 (only 1 article returned)articlesCount === 2 (total count, not page size)articles.length === 1 (still 1 article)articlesCount === 2 (total unchanged by offset)The pagination tests explicitly verify that backends implement the specification correctly, where articlesCount must always represent the total number of matching articles, not just those returned in the current page lines 800-804 lines 845-846
Sources: api/Conduit.postman_collection.json660-911 api/openapi.yml696-741
Some tests include conditional logic to handle different testing contexts. The Register request lines 14-36 includes a guard for integration tests:
This allows the same collection to be used in both full integration test suites and quick validation scenarios where certain checks should be skipped.
Sources: api/Conduit.postman_collection.json20-32
When tests fail, Newman provides detailed output including:
The test script output can be controlled via the DELAY_REQUEST environment variable to throttle request rate, which is useful when testing against rate-limited APIs or during debugging to make the test execution easier to follow.
The Makefile's test target Makefile66-77 also verifies that the server process started successfully before running tests (using kill -0 "$$SERVER_PID"), providing an early exit with error code 4 if the server failed to start, rather than letting all tests fail with connection errors.
Sources: Makefile66-77 api/run-api-tests.sh11
Refresh this wiki