Run RSpec tasks in a specific order - ruby

I have a bunch of RSpec Rake tasks defined that I'd like to run in a specific order when I run the entire suite of tests.
I've tried something like this:
task :run_in_order => [:one, :two, :three] do
puts "Run suite of tests"
end
And it runs the first test and then stops and doesn't run the rest of the tasks.
So if using Rake syntax it doesn't work. Is there a way to note task dependencies for RSpec Rake tasks?

Check this http://blog.davidchelimsky.net/2012/01/04/rspec-28-is-released/
–order rand We added an --order option with two supported values: rand
and default.
rspec --order random (or rand) tells RSpec to run the groups in a
random order, and then run the examples within each group in random
order. We implemented it this way (rather than complete randomization
of every example) because we don’t want to re-run expensive
before(:all) hooks. A fair tradeoff, as the resulting randomization is
just as effective at exposing order-dependency bugs.
When you use --order random, RSpec prints out the random number it
used to seed the randomizer. When you think you’ve found an
order-dependency bug, you can pass the seed along and the order will
remain consistent:
--order rand:3455
--order default tells RSpec to load groups and examples as they are declared in each file
Basically you should order your tests in a spec file an then execute it with --order default option.
.

Related

How would I test a ruby method that only calls a system command?

After looking at:
How do I stub/mock a call to the command line with rspec?
The answer provided is:
require "rubygems"
require "spec"
class Dummy
def command_line
system("ls")
end
end
describe Dummy do
it "command_line should call ls" do
d = Dummy.new
d.should_receive("system").with("ls")
d.command_line
end
end
My question is: How does that actually test anything?
By making a method to that says "call the ls command on the system", and then writing a test that says "my method should call the ls command on the system", how does that provide any benefit?
If the method were to change, I would have to change the test as well, but I'm not sure I see the added benefit.
The approach you are describing is known as the "mockist" or "London" school of unit testing. It's benefits include
That the act of constructing such a test creates an incentive to design units which are not excessively complex in terms of their dependencies or conditional logic
That such tests execute very quickly, which can be very important for large systems
That such tests can be reasonably built to provide maximal coverage for the unit under test
That such tests provide a "vise" of sorts around your code such that inadvertent changes will result in a failing test
Of course, such tests have their limitations, which is why they are often paired with system level tests which test whether a collection of units operating together achieve some higher order outcome.

Can RSpec be configured to fail any example which does not contain any expectations?

I know that in RSpec you can easily mark an example as incomplete by omitting the block:
it 'is not a complete example'
But is it possible to get RSpec to fail any example which does not contain any expectations?
IE. RSpec will happily pass this example:
it 'does not have any expectations but still passes' do
end
I want to emulate the behavior of PHPUnit which fails any test not containing any assertions.
There isn't a built-in way, but it's a feature I'd like to see added at some point.
In the meantime, it's not too hard to add yourself:
http://blog.sorah.jp/2012/12/17/rspec-warn-for-no-expectations

When exact does rspec's before(:all) run?

The question is straight forward, given a pattern that runs multiple *_spec.rb files, does before(:all) run once before all of the files or before each file? I know before(:each) runs before each example but I'm unclear about the other.
If it helps my use case is I want to initialize a selenium instance in before(:all) and login to a website. I only want to log in once at the start of the run and destroy the selenium instance at the end of the run rather than initialize/destroy for each *_spec.rb file that runs.
I was going to test this by simply putting a puts statement in the before(:all) block but it doesn't print to screen, just ignores the puts call all together.
A before(:all) runs once for the example group it is defined in (ie a describe or context block). For clarity it is aliased as before(:context) starting with rspec 3.
It sounds like you're after before(:suite)
before(:all) will run once before the examples within a given Describe block.
This behavior is described in the RSpec Core 2.0 documentation. According to the RSpec Core 3.2 documentation, before(:context) provides the same functionality as before(:all).

Is there a way to generate the documentation for an RSpec test without actually running the test?

For each test in each spec file in a given directory, I would like to generate the output of rspec spec --format documentation, so it looks something like this:
something
does something that passes
does something that fails
does something that is pending
I don't want it to actually run the tests. I would like a list so that I can gauge the current test coverage level. These are not unit tests, so RCov would be of no use.
This comes a few years too late :D, but here's what you can do:
rspec --dry-run --format documentation
There used to be until we added one liners:
it { should do_something }
That form is widely used and can only generate documentation if it runs.

Prevent database rollback in specs in Ruby on Rails?

When running RSpec tests in Ruby on Rails 2.3 with ActiveRecord, the database gets rolled back to the state after a before :all block after each example (it block).
However, I want to spec the lifecycle of an object, which means going through a number of examples one by one, changing the state and testing postconditions. This is impossible with the rollback behaviour.
So to clarify:
describe MyModel
before :all { #thing = MyModel.create }
it "should be settable" do
lambda { #thing.a_number = 42 }.should_not raise_exception
end
it "should remember things" do
#thing.a_number.should == 42
# this fails because the database was rolled back ☹
end
end
Is there some way to persist changes made in examples?
I agree with normalocity, in this case it looks like you would be better off with a single spec containing two assertions.
There are cases in which it is helpful to turn off rollbacks, e.g. for higher level tests with Capybara and Selenium, in which case you can use the use_transactional_fixtures configuration option. You can put thi
RSpec.configure do |config|
config.use_transactional_fixtures = false
end
Well, that depends on what you're trying to do. If you're testing the life cycle (a series of things that happen over time), that's more the realm of integration tests, which you can build more in tools such as Cucumber, etc. Spec is more designed to do small tests of small bits of code.
It's technically possible for you to simply write a long spec test, with multiple .should statements, and so long as all of them pass, then you've effectively got the kind of test you're describing. However, that's not really, in my experience, what spec is designed to give you.
I guess what I'm saying is, don't try to prevent the rollback - that's not what it's there to do. Either use a tool more designed to do the kinds of tests you're looking to build, or write a longer test that has multiple .should statements.

Resources