Re: [rspec-users] Monitor method invoking from superclass
Rick, could you elaborate on this? I'm curious, how would you use a shared example group here, given his sample code? My first thought was to use ancestors to get the parent class, and re-define the 'a' method there to do something simple and observable, and then test that. Is that evil? On Thu, Sep 30, 2010 at 11:00 AM, Rick DeNatale wrote: > On Thu, Sep 30, 2010 at 10:36 AM, Zhi-Qiang Lei > wrote: > > > > On Sep 30, 2010, at 9:56 PM, Rick DeNatale wrote: > > > > >> What you really should be testing that the observable effects of the > >> call are 'as if' the super call were made. > >> > >> If you could test that the super call was made it would be testing > >> that the implementation were a certain way more than the behavior of > >> the object, and that's the road to writing brittle tests. > > > > > In my case, there is already a test case for the method in class A, and > its feature is complex. So I was trying to test the super call but > observable effect for simple. Anyway, thank you both. > > That's what shared example groups are for. > > > -- > Rick DeNatale > > Blog: http://talklikeaduck.denhaven2.com/ > Github: http://github.com/rubyredrick > Twitter: @RickDeNatale > WWR: http://www.workingwithrails.com/person/9021-rick-denatale > LinkedIn: http://www.linkedin.com/in/rickdenatale > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] What should I test/specify?
Ok, so here's the scenario. I have a top-level module, with a method called load_file. It should take a file name, get the YAML module (Syck) to parse it, and then send the result to a class, which should convert that result into a series of objects. I'm not sure what specs, if any, I should write for load_file. I can get into the nitty gritty details of exactly what methods it should be calling, but that seems brittle. I can skip all that and just make assertions about the final series of objects, but I'd rather put those specs on the class that's actually doing the conversion. Suggestions? Here's the code that I (think I) want to drive out: module BTree def self.load_file file_name raw = YAML::load_file file_name tree = BehaviorTreeCreator.new(raw).create end end ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] What should I test/specify?
On Sat, Oct 30, 2010 at 12:46 PM, David Chelimsky wrote: > On Oct 30, 2010, at 11:40 AM, Andrew Wagner wrote: > > > Ok, so here's the scenario. I have a top-level module, with a method > called load_file. It should take a file name, get the YAML module (Syck) to > parse it, and then send the result to a class, which should convert that > result into a series of objects. > > > > I'm not sure what specs, if any, I should write for load_file. I can get > into the nitty gritty details of exactly what methods it should be calling, > but that seems brittle. I can skip all that and just make assertions about > the final series of objects, but I'd rather put those specs on the class > that's actually doing the conversion. > > > > Suggestions? Here's the code that I (think I) want to drive out: > > > > module BTree > > def self.load_file file_name > > raw = YAML::load_file file_name > > tree = BehaviorTreeCreator.new(raw).create > > end > > end > > One approach would be: > > describe BTree do > describe "::load_file" do > let(:filename) { '/tmp/btree_example.yml' } >let(:content) { "---\na: 1\n" } >before { File.open(filename,'w') {|f| f.write content } } >after { File.delete filename } > >it "reads and parses the content of the file" do > BTree.load_file(filename).should > eq(BehaviorTreeCreator.new(content).create >end > end > end > > Assuming there are specs for BehaviorTreeCreator.new(content).create, then > this tells the story pretty well without being terribly invasive. > > WDYT? > > David > > > > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > I like this, though it's missing a YAML::load(content). I.e., BTree.load_file(filename).should eq(BehaviorTreeCreator.new(YAML::load content).create ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] What should I test/specify?
Yeah, that's about what I figured, thanks. This is what I came up with: require 'spec_helper.rb' require 'yaml' describe "BTree" do describe ".load_file" do context "when the file exists" do before(:all) { File.open("test_file.yaml", 'w') {|f| } } after(:all) { File.delete "test_file.yaml"} after(:each) { BTree.load_file "test_file.yaml" } it "parses the yaml in the file" do YAML.stub!(:load_file).and_return(:foo) YAML.should_receive(:load_file).with("test_file.yaml").and_return(:foo) end it "converts the raw data into a tree" do fake_creator = Object.new fake_creator.stub! :create YAML.stub!(:load_file).and_return(:data) BehaviorCreator.stub!(:new).and_return :tree BehaviorCreator.should_receive(:new).with(:data).and_return fake_creator fake_creator.should_receive :create end end context "when the file doesn't exist" do it "raises an error" do lambda { BTree.load_file "non_existent.yaml" }.should raise_error end end end end On Sat, Oct 30, 2010 at 12:47 PM, John Feminella wrote: > If you're writing a unit test for a method, the general rule of thumb > is to test what the method itself does. That sounds tautological, but > it's meant to define the boundary of what you should and shouldn't > care about. > > In this case, you only care about the fact that `YAML::load_file` is > called, and that `BehaviorTreeCreator.new` is then called with the > result of that, and that *that* result has `create` invoked on it. > That's it: if those three things happen, then this method is working > as you expect. > > Your unit tests for BehaviorTreeCreator.new and .create will probably be > richer. > > ~ jf > -- > John Feminella > Principal Consultant, BitsBuilder > LI: http://www.linkedin.com/in/fjsquared > SO: http://stackoverflow.com/users/75170/ > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] What should I test/specify?
On Sat, Oct 30, 2010 at 9:54 PM, Andrew Premdas wrote: > On 30 October 2010 14:40, Andrew Wagner wrote: > >> Ok, so here's the scenario. I have a top-level module, with a method >> called load_file. It should take a file name, get the YAML module (Syck) to >> parse it, and then send the result to a class, which should convert that >> result into a series of objects. >> >> I'm not sure what specs, if any, I should write for load_file. I can get >> into the nitty gritty details of exactly what methods it should be calling, >> but that seems brittle. I can skip all that and just make assertions about >> the final series of objects, but I'd rather put those specs on the class >> that's actually doing the conversion. >> >> Suggestions? Here's the code that I (think I) want to drive out: >> >> module BTree >> def self.load_file file_name >> raw = YAML::load_file file_name >> tree = BehaviorTreeCreator.new(raw).create >> end >> end >> >> > Its not obvious what specs to write for load_file because load_file is > poorly named. It does far more than load a file. If you write your specs > for load file and read them, they won't make sense e.g. > > load_file should use YAML (why should it use YAML, and what happens if the > file isn't YAML > load_file should create a behaviour tree (why should it create a TREE) > > Perhaps BTree only needs a yaml_to_tree, and you can pass the yaml into the > method. If this was the case you might spec the following: > what happens if you pass invalid YAML > what happens if you pass valid YAML > what happens if you pass nothing > > Generally if a method is hard to spec, then its smelly, there is something > wrong with it, it needs work > > HTH > > Andrew > > >> ___ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > > > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > An interesting perspective. The purpose of the behavior tree module is to provide a simple, standard way to represent behaviors in a plain-text format. I'm borrowing YAML because it seems like a good, lightweight approach. I'm using load_file (and load) to mirror YAML::load_file (and YAML::load). I'll definitely take some of your ideas into consideration, thanks. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] Shared contexts
Suppose we have this class: class MarbleMachine def insert color # process marble of color 'color' end def press button # process a push of the given button end def output # compute a result end end Let's presume here that the machine takes any number of marbles in any of 8 different colors, and that it has a few different buttons that can be pressed. The output is highly dependent on what actions you take, in what order. Obviously, a bit of a silly example, but easier than explaining a complex, highly data-driven application. Ok, now let's think about writing some specs. We're really not interested in trying to specify every possible scenario. But there are a few scenarios that we know are important. For example, we know that the customer is very interested in what happens in the state the machine is in after the sequence: [:blue_marble, :medium_button, :black_marble, :orange_marble] What happens if you insert two green marbles after this? What happens if you insert a yellow marble and press the big purple button? etc. In addition, the customer is also very interested in what happens if you push the red button when the machine is in a variety of states. What I'm trying to get at, here, is that I want to share some complex contexts across specs while not varying the action I'm specifying. I also want to vary the action I'm specifying in a number of different contexts (which is more along the lines of shared examples). I don't really want to think about it in terms of the state that exists, because that's not useful from the customer's standpoint. To be sure that things are set up correctly, we need to be able to say what happened, not just what the state is. So, how would you organize your specs in a scenario like this? ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Shared contexts
OK, in the face of chirping crickets, let me try to be a little more concrete. Here is a start at trying to spec out some behavior for our fabled MarbleMachine: https://gist.github.com/703446 I'd love to get some suggestions for improving how this is organized. Specifically, there are a few different, but related, contexts like the ones I've put in shared examples. Ideally, I'd like to figure out how to make these contexts composable in some way, because the actions they're comprised of are composable. On Tue, Nov 16, 2010 at 1:07 PM, Andrew Wagner wrote: > Suppose we have this class: > > class MarbleMachine > def insert color > # process marble of color 'color' > end > > def press button > # process a push of the given button > end > > def output > # compute a result > end > end > > Let's presume here that the machine takes any number of marbles in any of 8 > different colors, and that it has a few different buttons that can be > pressed. The output is highly dependent on what actions you take, in what > order. Obviously, a bit of a silly example, but easier than explaining a > complex, highly data-driven application. > > Ok, now let's think about writing some specs. We're really not interested > in trying to specify every possible scenario. But there are a few scenarios > that we know are important. For example, we know that the customer is very > interested in what happens in the state the machine is in after the > sequence: > > [:blue_marble, :medium_button, :black_marble, :orange_marble] > > What happens if you insert two green marbles after this? What happens if > you insert a yellow marble and press the big purple button? etc. > > In addition, the customer is also very interested in what happens if you > push the red button when the machine is in a variety of states. > > What I'm trying to get at, here, is that I want to share some complex > contexts across specs while not varying the action I'm specifying. I also > want to vary the action I'm specifying in a number of different contexts > (which is more along the lines of shared examples). I don't really want to > think about it in terms of the state that exists, because that's not useful > from the customer's standpoint. To be sure that things are set up correctly, > we need to be able to say what happened, not just what the state is. > > So, how would you organize your specs in a scenario like this? > ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] "unit" vs. "functional" specs
I went back and forth on whether to send this to this list or the ruby-talk list, so feel free to tell me to take a hike... I'm working on a personal project where I'm trying to keep a really high bar on quality. One of the ways I'm doing that is to stick very close to the BDD/TDD cycle as suggested in the RSpec book. However, I'm actually using rspec for both the feature-level (BDD) tests and the unit-level (TDD) tests. I'm also striving for 100% test coverage using Simplecov. That said, I just realized that, to enforce that cycle, it's also important that I ask "do my unit tests by themselves provide 100% test coverage?". Because, otherwise, it's easy to get excited and write code to make the feature past, that isn't TDD'd. Anyway, all that to ask: is there some way to configure Simplecov to emit code coverage stats for just a subset of all the tests that are running? That is, I want to set up my rakefile such that it runs all my tests, but only reports on code coverage for the unit tests. Am I going about this with the right mindset? Any suggestions? ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] Current test failing?
Is there any way, within a test (e.g., in an after block), to see whether the test is currently passing, failing, or pending? Even a hack-ish kind of way? I'm just curious. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] it_behaves_like and running single examples
To diagnose this, I would start to try to isolate the problem as much as possible. Get it all the way down to one file, outside of rails, with one test that exemplifies the behavior, if need be. And if you get to that point and still see the strangeness...send us a pastebin of it :) On Wed, Feb 16, 2011 at 9:34 AM, Andrew Vargo wrote: > Hello, > > I am running rspec 2 and rails 3 in a project. > > When I have a shared example being used in a spec file, I loose the > ability to run a single test in that file. > rspec spec/controllers/proposals_controller_spec.rb:13 for instance > will always give me a green '..', even if I put uparsable junk in that > example like > it "should choke" do > asdfasdfasdfasfd > end > > Running the file w/o the line number works ace. > > When I remove the shared example line: it_behaves_like "...", all goes > back to normal. > > Any thoughts? Even if where to start diagnosing it? My shared > example is in a rb file in spec/support. > > Thanks, > Andrew > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Controller testing - it doesn't print if given some print value
What does your actual spec look like? On Wed, May 18, 2011 at 10:04 AM, DKR wrote: > I am working on Rspec2.5.0 with rails 3.0.6 . And I was successfully > able to complete model testing. But when I come to controller part I > wanted to see whether some variable getting generated & I have given > > My Controller > def some_action > @users=User.create(params[:user]) > p @users > end > end > > Here in model if give 'p object_name' it prints well.But I am not able > to see the results when I do bin/rspec spec/controllers/ > user_controller_spec.rb > > Any ideas will be highly appreciable. > ___ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users