rspec-expectations-2.9.1 is released! »
Created at: 03.04.2012 22:18, source: David Chelimsky, tagged: bdd rspec ruby
This is a bug-fix only release, and is recommended for everybody using rspec-2.9.
Bug fixes
- Provide a helpful message if the diff between two objects is empty.
- Fix bug diffing single strings with multiline strings.
- Fix for error with using custom matchers inside other custom matchers (mirasrael)
- Fix using execution context methods in nested DSL matchers (mirasrael)
more »
rspec-2.9.0 is released! »
Created at: 18.03.2012 01:10, source: David Chelimsky, tagged: rspec rails ruby
rspec-2.9.0 is released wtih lots of bug fixes and a few minor feature improvements as well. Enjoy!
rspec-core-2.9.0 / 2012-03-17
Enhancements
- Support for “X minutes X seconds” spec run duration in formatter. (uzzz)
- Strip whitespace from group and example names in doc formatter.
- Removed spork-0.9 shim. If you’re using spork-0.8.x, you’ll need to upgrade to 0.9.0.
Bug fixes
- Restore
--full_backtraceoption - Ensure that values passed to
config.filter_runare respected when running over DRb (using spork). - Ensure shared example groups are reset after a run (as example groups are).
- Remove
rescue falsefrom calls to filters represented as Procs - Ensure described_class gets the closest constant (pyromaniac)
- In “autorun”, don’t run the specs in the at_exit hook if there was an exception (most likely due to a SyntaxError). (sunaku)
- Don’t extend groups with modules already used to extend ancestor groups.
itscorrectly memoizes nil or false values (Yamada Masaki)
rspec-expectations-2.9.0 / 2012-03-17
Enhancements
- Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution of RSpec::Matchers (which is included in every example).
- Autoload files with matcher classes to improve load time.
Bug fixes
- Align
respond_to?andmethod_missingin DSL-defined matchers. - Clear out user-defined instance variables between invocations of DSL-defined matchers.
- Dup the instance of a DSL generated matcher so its state is not changed by subsequent invocations.
- Treat expected args consistently across positive and negative expectations (thanks to Ralf Kistner for the heads up)
rspec-mocks-2.9.0 / 2012-03-17
Enhancements
- Support order constraints across objects (preethiramdev)
Bug fixes
- Allow a
as_null_objectto be passed towith - Pass proc to block passed to stub (Aubrey Rhodes)
- Initialize child message expectation args to match any args (#109 - preethiramdev)
rspec-rails-2.9.0 / 2012-03-17
Enhancments
- add description method to RouteToMatcher (John Wulff)
- Run “db:test:clone_structure” instead of “db:test:prepare” if Active Record’s schema format is “:sql”. (Andrey Voronkov)
Bug fixes
mock_model(XXX).as_null_object.unknown_methodreturns self again- Generated view specs use different IDs for each attribute.
more »
Validations are behavior, associations are structure »
Created at: 13.02.2012 00:53, source: David Chelimsky, tagged: rspec ruby
TL;DR:
- TDD is about specifying behavior, not structure.
- Validations are behavior, and should be specified.
- Associations are structure, and need not be.
Disclaimer
This is my personal viewpoint, though it is not mine alone. YMMV.
Declarations
ActiveRecord provides a declarative interface for describing the structure and behavior of a model:
class Article < ActiveRecord::Base validates_presence_of :title has_many :comments end
While syntactically similar, these two declarations do fundamentally different things.
Validations are behavior
The validates_presence_of :title declaration changes the behavior of
the save method (and other methods that use save), and should be specified
explicitly. Here’s an example using shoulda matchers:
describe Article do it { should validate_presence_of(:title) } end
Even though the matcher’s name looks just like the likely implementation, the
validate_presence_of matcher specifies that you can not save an Article
without a non-nil value for title, not that the
validates_presence_of(:title) declaration exists.
Associations are structure
The has_many declaration exposes a comments method to clients that appears
to be a collection of Comment objects. Doing Test-Driven Development, you
would add this declaration when a specified behavior requires it e.g.
describe Article do describe "#with_comments_by" do it "finds articles with comments by the submitted comment_author" do article = Factory(:article) article.comments << Factory.build(:comment, :author => "jdoe") Article.with_comments_by("jdoe").should eq([article]) end end end
This example needs a comments method that returns a collection in order to
pass. If it doesn’t exist already (because no other example drove you to add
it), this would be all the motivation you need to introduce it. You don’t need
an example that says it "should have_many(:comments)".
Testing the framework
Some will argue that we don’t need to spec validations either, suggesting that
it "should validate_presence_of(:title)" is testing the Rails framework,
which we trust is already tested. If you think of TDD as a combination of
specification, documentation, and regression testing, then this argument falls
short on the specification/documentation front because the validation is
behavior and, thus, the spec should specify the validation.
Even if you view testing as nothing more than a safety net against regressions,
the argument still falls down in the face of refactoring. If we add a Review
class that also has_many(:comments) and validates_presence_of(:title), and
we want to extract that behavior to a Postable module that gets included in
both Article and Review, we’d want a regression test to fail if we failed
to include either of those declarations in the Postable module.
But declarations are already declarative!
Another argument is that declarations supply sufficient documentation. e.g. we
can look at rental_contract.rb and know that it validates the presence of
:rentable:
class RentalContract < ActiveRecord::Base has_many :monthly_charges has_one :rentable, :polymorphic => true validates_presence_of :rentable def default_monthly_charge price / months_applied end end
This is an interesting argument that I think has some merit, but I think it would require an extraordinarily disciplined and consistent approach of using declarations 100% of the time in model files such that each one is the spec for that model, e.g.
class Contract < ActiveRecord::Base validates_presence_of :name has_many :monthly_expenses calculates_default_monthly_charge end
100% may sound extreme, but as soon as we define a single method body in any one of the models, the declarative nature of the file begins to degrade, and so does its fitness for the purpose of specification. Plus, if we can only understand the expected behavior of a model by looking at its spec and its implementation, we’ve lost some of the power of a test-driven appraoch.
What do you think?
Do you spec associations? If so, what value do you get from doing so? If not, have you run into situations where you wished you had?
Same questions for validations.
more »
rspec-rails-2.8.1 is released »
Created at: 05.01.2012 07:43, source: David Chelimsky, tagged: bdd rspec rails ruby
Bug fix release
The rails-3.2.0.rc2 release broke stub_model in rspec-rails-2.0.0 > 2.8.0.
The rspec-rails-2.8.1 release fixes this issue, but it means that when you
upgrade to rails-3.2.0.rc2 or greater, you’ll have to upgrade to
rspec-rails-2.8.1 or greater.
Because rspec-rails-2.8.1 supports all versions of rails since 3.0, I recommend that you upgrade to rspec-rails-2.8.1 first, and then upgrade to rails-3.2.0.rc2 (or 3.2.0 once it’s out).
Changelog
http://rubydoc.info/gems/rspec-rails/file/Changelog.md
Docs
http://rubydoc.info/gems/rspec-rails
http://relishapp.com/rspec/rspec-rails
more »
RSpec-2.8 is released! »
Created at: 05.01.2012 04:38, source: David Chelimsky, tagged: bdd rspec ruby
We released RSpec-2.8.0 today with a host of new features and improvements since 2.7. Some of the highlights are described below, but you can see the full changelogs at:
- http://rubydoc.info/gems/rspec-core/file/Changelog.md
- http://rubydoc.info/gems/rspec-expectations/file/Changelog.md
- http://rubydoc.info/gems/rspec-mocks/file/Changelog.md
- http://rubydoc.info/gems/rspec-rails/file/Changelog.md
Documentation
While not 100% complete yet, we’ve made great strides on RSpec’s RDoc:
- http://rubydoc.info/gems/rspec-core
- http://rubydoc.info/gems/rspec-expectations
- http://rubydoc.info/gems/rspec-mocks
- http://rubydoc.info/gems/rspec-rails
http://rspec.info is now just a one pager (desperate for some design love - volunteers please email rspec-users@rubyforge.org). All the old pages are redirects to the relevant RDoc at http://rubydoc.info. RSpec-1 info is still available at http://old.rspec.info.
We’ve still got Cucumber features up at http://relishapp.com/rspec, but we’re going to be phasing that out as the primary source of documentation. There are a lot of reasons for this, and I’ll try to follow up with a separate blog post on this topic.
rspec-core
Improved support for tags and filtering
You can now set default tags/filters in either RSpec.configure or a .rspec
file and override these tags on the command line. For example, this configuration
tells rspec to run all the examples that are not tagged :slow:
# in spec/spec_helper.rb RSpec.configure do |c| c.treat_symbols_as_metadata_keys_with_true_values = true c.filter_run_excluding :slow end
Now when you want run those, you can just do this:
rspec --tag slow
This will override the configuration and run onlly the examples tagged :slow.
–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.
rspec –init
We added an --init switch to the rspec command to generate a “spec”
directory, and “.rspec” and “spec/spec_helper.rb” files with some starter code
in them.
rspec-expectations
We discovered that the matcher DSL generates matchers that run considerably slower than classes which implement the matcher protocol. We made some minor improvements in the DSL, but to really improve things we re-implemented every single built-in matcher as a class.
more »
