Write API tests as sequential workflows in YAML. Generate OpenAPI documentation automatically.
# spec_forge/blueprints/users.yml
- name: "Create and verify user"
request:
url: /users
http_verb: POST
json:
name: "Jane Smith"
email: "jane@example.com"
expect:
- status: 201
json:
shape:
id: integer
name: string
email: string
store:
user_id: "{{ response.body.id }}"
- name: "Fetch created user"
request:
url: "/users/{{ user_id }}"
expect:
- status: 200
json:
content:
name: "Jane Smith"Two steps. One workflow. No Ruby code required.
For Testing
- Write tests the way you think about APIs - as sequences of actions
- Zero boilerplate: no HTTP client setup, no configuration objects
- Full access to RSpec matchers, Faker, and FactoryBot without writing Ruby
For Documentation
- Auto-generate OpenAPI specs from your workflows
- Tests ensure documentation always matches your actual API
- View in Swagger UI or Redoc with one command
For Teams
- YAML workflows are easier to review than Ruby test code
- QA, developers, and product can all read and contribute
- Version-controlled specifications that live with your code
# Install
gem install spec_forge
# Initialize project structure
spec_forge init
# Create your first workflow
spec_forge new blueprint users
# Run it
spec_forge run
# Generate and view documentation
spec_forge serveVisit http://localhost:8080 to see your API documentation!
- Step-based workflows: Tests execute sequentially with explicit variable flow
- Variable storage: Capture response values with
store:, reference them with{{ variable }} - Validation modes: Simple
shape:matching for structure,schema:for precise control - Tag filtering: Run subsets with
--tags smokeor--skip-tags slow - Lifecycle hooks: Execute Ruby code at forge, blueprint, or step boundaries
- Dynamic data: Built-in Faker and FactoryBot integration
- Nesting: Group steps and share configuration with the
shared:wrapper
- name: "Login"
request:
url: /auth/login
http_verb: POST
json:
email: "{{ faker.internet.email }}"
password: "testpass123"
expect:
- status: 200
json:
shape:
token: string
store:
auth_token: "{{ response.body.token }}"
- name: "Authenticated requests"
shared:
request:
headers:
Authorization: "Bearer {{ auth_token }}"
steps:
- name: "Get profile"
request:
url: /me
expect:
- status: 200
- name: "Update profile"
request:
url: /me
http_verb: PUT
json:
name: "Updated Name"
expect:
- status: 200Consider alternatives when you need:
- Complex Ruby logic in tests - custom transformations, calculations, or validation beyond matchers
- Intricate test setup - complex database states, multiple service mocks, elaborate fixtures
- Non-REST APIs - GraphQL, gRPC, or WebSocket testing may need specialized tools
- Heavy computational testing - load testing, performance benchmarks, parallel execution
You can use SpecForge alongside traditional RSpec tests. Use SpecForge for standard REST workflows and RSpec for complex scenarios.
For comprehensive guides and reference:
- Getting Started - Installation and your first workflow
- Writing Tests - Complete syntax reference
- Configuration - Setup and framework integration
- Running Tests - CLI commands and filtering
- Dynamic Features - Variables, Faker, FactoryBot
- Documentation Generation - OpenAPI customization
Upgrading from 0.7? See the Migration Guide.
API Reference: itsthedevman.com/docs/spec_forge
| Command | Description |
|---|---|
spec_forge init |
Initialize project structure |
spec_forge new blueprint <name> |
Create a workflow file |
spec_forge new factory <name> |
Create a factory file |
spec_forge run |
Execute workflows |
spec_forge docs |
Generate OpenAPI specs |
spec_forge serve |
Generate and serve documentation |
Run spec_forge help <command> for detailed options.
Contributions welcome! See the Contributing Guide.
Available as open source under the MIT License.
I'm currently looking for opportunities where I can tackle meaningful problems and help build reliable software while mentoring the next generation of developers. If you're looking for a senior engineer with full-stack Rails expertise and a passion for clean, maintainable code, let's talk!