问题
My acceptance tests (RSpec/Capybara) have some long sequences of steps all under a single it...do
block, and I'd like to manually add some additional documentation of each step into the RSpec documentation output.
So where the RSpec output (in documentation format) currently looks like:
FooController
New user creates account and creates profile
it passes
Within the long sequence of steps I'd like to push some additional info to the output:
FooController
New user creates account and creates profile
... new user saw signup page!
... new user got email confirmation!
... confirmation link worked!
... new user saw empty profile!
... new user filled in profile
it passes
In terms of documenting the app, those extra statements would be better than a large black box with a single 'it passed' result message.
Since there is apparently no way to use multiple it...do
blocks to build the long sequence of steps for a acceptance test, I'm hoping there is a simple way to push additional messages to the RSpec output stream, ideally with them being indented and displayed (red/green) as if they were pat or separate it...do
examples.
回答1:
Eventually, I opted for customization of the DocumentationFormatter, by including the following code somewhere in the spec/support
folder (to ensure automatic loading):
require "rspec/core/formatters/documentation_formatter"
class RSpec::Core::ExampleGroup
def step(msg)
example.metadata[:step_messages] << msg if example.metadata[:step_messages]
yield
end
end
class RSpec::Core::Formatters::DocumentationFormatter
def example_started(example)
example.metadata[:step_messages] = []
end
def example_passed(example)
output.puts passed_output(example)
print_steps(example)
end
private
def print_steps(example)
example.metadata[:step_messages].each do |msg|
output.puts detail_color("#{' ' * (@group_level + 1)}#{msg}")
end
end
end
With this trick, you obtain a step
method that you can use within your it
blocks.
When running rspec with --format documentation
, relevant messages from step
blocks will be printed out, appropriately indented.
For instance, the following code
it "should show all and only appoved posts" do
step "show all approved posts" do
Post.all.approved.each do |post|
should have_content(post.title)
end
end
step "show only approved posts" do
should have_selector(".post", count: Post.all.approved.count)
end
end
will produce the following output (with step strings colorized in light blue):
should show all and only appoved posts
show all approved posts
show only approved posts
This is admittedly a very rough solution, but it can probably be made nicer with a little bit more work.
回答2:
Here's what I did... added a nextstep("message") method to my specs that outputs "message" to the console using awesome_print gem so I can color it, and also to the logger.
def nextstep(txt)
$step += 1
@speclog.debug ''
@speclog.debug ''
@speclog.debug "#{$scene}, step: #{$step}: " + txt
ap (' ' * ($indent * 2 - 1)) + "step: #{$step}: " + txt, {:color => {:string => :blueish}}
end
A little hackish, but it does give us very nice descriptive output when running rspec, for example if we have
it "New user creates account and creates profile" do
# some assertions
nextstep "... new user saw signup page!"
# some assertions
nextstep " ... new user got email confirmation!"
# some assertions
nextstep " ... confirmation link worked!"
# some assertions
nextstep "... new user saw empty profile!"
# some assertions
nextstep "... new user filled in profile"
end
we get the more descriptive spec output as shown in the question (and if there's a failure we see the step we were on):
step 1: ... new user saw signup page!
step 2: ... new user got email confirmation!
step 3: ... confirmation link worked!
step 4: ... new user saw empty profile!
step 5: ... new user filled in profile"
来源:https://stackoverflow.com/questions/12790100/in-rspec-rails-acceptance-tests-is-there-any-way-to-push-messages-to-the-rspec-o