-
-
Notifications
You must be signed in to change notification settings - Fork 0
Dynamic Features
SpecForge offers several ways to make your tests dynamic and data-driven through expressions, data generation, and variable management.
Expressions are dynamic values evaluated at runtime using the {{ }} syntax:
- name: "Create user"
request:
url: /users
http_verb: POST
json:
email: "{{ faker.internet.email }}"
role: "{{ default_role }}"
store:
user_id: "{{ response.body.id }}"See Step Reference for the complete expression reference.
Access any Faker method using the faker. prefix:
- name: "Create user with fake data"
request:
url: /users
http_verb: POST
json:
name: "{{ faker.name.name }}"
email: "{{ faker.internet.email }}"
phone: "{{ faker.phone_number.phone_number }}"
address:
street: "{{ faker.address.street_address }}"
city: "{{ faker.address.city }}"
state: "{{ faker.address.state }}"
zip: "{{ faker.address.zip_code }}"When a Faker method needs arguments, use key position (no {{ }}):
- store:
age:
faker.number.between:
from: 18
to: 65
price:
faker.number.decimal:
l_digits: 2
r_digits: 2
- name: "Use generated values"
request:
url: /products
http_verb: POST
json:
price: "{{ price }}"
min_age: "{{ age }}"Faker's nested namespaces work naturally:
- name: "Game-themed test data"
request:
url: /characters
http_verb: POST
json:
zelda_character: "{{ faker.games.zelda.character }}"
pokemon: "{{ faker.games.pokemon.name }}"
superhero: "{{ faker.superhero.name }}"Generate test objects using FactoryBot through the factories. prefix:
- store:
user: "{{ factories.user }}"
admin: "{{ factories.user.admin }}" # Using a trait
- name: "Create post for user"
request:
url: /posts
http_verb: POST
json:
title: "{{ faker.lorem.sentence }}"
user_id: "{{ user.id }}"Access any attribute on a factory-created object:
- store:
author: "{{ factories.user }}"
- name: "Verify author data"
request:
url: "/users/{{ author.id }}"
expect:
- status: 200
json:
content:
name: "{{ author.name }}"
email: "{{ author.email }}"See Factory Support for factory configuration and advanced usage.
Use generate.array to create arrays of dynamic values:
- name: "Bulk create users"
request:
url: /users/bulk
http_verb: POST
json:
users:
generate.array:
size: 10
value:
name: "{{ faker.name.name }}"
email: "{{ faker.internet.email }}"Inside generate.array, the special index variable (0-based) is available:
- name: "Create numbered items"
request:
url: /items/bulk
http_verb: POST
json:
items:
generate.array:
size: 5
value:
position: "{{ index }}"
name: "Item {{ index }}"This produces: [{position: 0, name: "Item 0"}, {position: 1, name: "Item 1"}, ...]
Chain methods on any resolved value:
- store:
# Chain on faker results
lowercase_email: "{{ faker.internet.email.downcase }}"
uppercased_name: "{{ faker.name.name.upcase }}"
# Chain on factory attributes
user: "{{ factories.user }}"
first_post_title: "{{ user.posts.first.title }}"
# Array access with indices (zero-based)
second_comment: "{{ user.posts.0.comments.1.body }}"Chaining works on:
- Faker results
- Factory objects and their associations
- Variables (including nested hashes and arrays)
- Response data
Access environment variables with the env. prefix:
- name: "Authenticated request"
request:
url: /admin/users
headers:
Authorization: "Bearer {{ env.API_TOKEN }}"
X-Api-Key: "{{ env.API_KEY }}"This is useful for:
- API tokens and secrets (keep out of version control)
- Environment-specific configuration
- CI/CD pipeline variables
Define variables for use in subsequent steps:
- store:
base_email: "test@example.com"
default_role: "user"
- name: "Create user"
request:
url: /users
http_verb: POST
json:
email: "{{ base_email }}"
role: "{{ default_role }}"When a step has request:, capture response values:
- name: "Create user"
request:
url: /users
http_verb: POST
json:
name: "{{ faker.name.name }}"
store:
user_id: "{{ response.body.id }}"
user_email: "{{ response.body.email }}"
- name: "Get created user"
request:
url: "/users/{{ user_id }}"
expect:
- status: 200
json:
content:
email: "{{ user_email }}"Define variables in forge_helper.rb for use across all blueprints:
SpecForge.configure do |config|
config.global_variables = {
api_version: "v1",
default_role: "user",
admin_email: "admin@test.com"
}
end- name: "Versioned API request"
request:
url: "/api/{{ api_version }}/users"
json:
role: "{{ default_role }}"See Context System for detailed coverage of variable scoping, shadowing, and the store: system.
- Step Reference -- Complete expression syntax
- Context System -- Variable scoping and storage
- Factory Support -- FactoryBot integration
- Factory Lists -- Creating multiple factory instances