-
-
Notifications
You must be signed in to change notification settings - Fork 0
Debugging
This guide covers debugging techniques in SpecForge to help you troubleshoot test failures and understand what's happening during test execution.
The quickest way to debug is using CLI verbosity flags -- no changes to your blueprints needed:
spec_forge run --verbose # Level 1: Show step names
spec_forge run --debug # Level 2: Show request/response on failures
spec_forge run --trace # Level 3: Show everything for all stepsStart with --verbose to see which step is failing, then escalate to --debug or --trace for more detail.
For interactive debugging, add debug: true to any step:
- name: "Debug this step"
debug: true
request:
url: /users
expect:
- status: 200Aliases: pry: true, breakpoint: true
Note: The debug flag does not inherit to nested steps -- it only triggers for the step it's defined on.
Configure your debug handler in forge_helper.rb:
SpecForge.configure do |config|
# Simple: drop into Pry
config.on_debug { binding.pry }
endThe handler receives a context parameter if your block accepts one:
config.on_debug do |context|
puts "Step: #{context.step.name}"
puts "Variables: #{context.variables.inspect}"
binding.pry
endWhen your debug handler receives context, it has access to:
| Property | Description |
|---|---|
context.variables |
Current variable state (including request and response if a request was made) |
context.forge |
The forge instance |
context.blueprint |
The current blueprint being executed |
context.step |
The current step |
The most useful property for debugging is usually context.variables:
config.on_debug do |context|
vars = context.variables
# See all available variables
puts "Available variables: #{vars.keys}"
# If this step made a request, inspect request/response
if vars[:request]
puts "Request URL: #{vars[:request][:url]}"
puts "Request method: #{vars[:request][:http_verb]}"
end
if vars[:response]
puts "Response status: #{vars[:response][:status]}"
puts "Response body: #{vars[:response][:body]}"
end
binding.pry
endThe context.step object contains the step's configuration:
config.on_debug do |context|
step = context.step
puts "Step name: #{step.name}"
puts "Has request? #{step.request?}"
puts "Has expectations? #{step.expects?}"
puts "Tags: #{step.tags}"
binding.pry
endconfig.on_debug do |context|
response = context.variables[:response]
puts "Status: #{response[:status]}"
puts "Body: #{response[:body].inspect}"
binding.pry
endconfig.on_debug do |context|
puts "All variables:"
context.variables.each do |key, value|
puts " #{key}: #{value.inspect}"
end
binding.pry
endconfig.on_debug do |context|
request = context.variables[:request]
puts "URL: #{request[:url]}"
puts "Method: #{request[:http_verb]}"
puts "Headers: #{request[:headers].inspect}"
puts "Body: #{request[:body].inspect}"
binding.pry
endYou can also use callbacks for debugging specific lifecycle points:
SpecForge.configure do |config|
# Log every request
config.after(:step) do |context|
next unless context.step&.request?
request = context.variables[:request]
response = context.variables[:response]
puts "#{request[:http_verb]} #{request[:url]} → #{response[:status]}"
end
endSee Callbacks for more on lifecycle hooks.
- Running Tests -- CLI options and verbosity flags
-
Configuration -- Setting up
on_debug - Callbacks -- Lifecycle hooks for logging
- Context System -- Understanding variables