[rspec-users] expect_render, why does there need to be a warning
There is a warning on the web site about expect_render and stub_render: WARNING: expect_render and stub_render, while very useful, act differently from standard Message Expectations (a.k.a. mock expectations), which would never pass calls through to the real object. This can be very confusing when there are failures if you're not aware of this fact, because some calls will be passed through while others will not. This is especially confusing when you use stub_render because, as with all Method Stubs, you will get very little feedback about what is going on. My questions: Is this a sign that expect_render is doing to much? Is there a benefit from having expect_render and stub_render sometimes pass the render call to the underlying template object? Why not force all partials to be tested individually? Testing partials individually seems like a cleaner, more consistent and less confusing route to go, especially when you consider the nesting of paritals which render other partials. Zach ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] [ANN] RSpec-1.0.8
I've been waiting for this since June so I can have expect_render officially . Thanks for the hard work! Zach On 8/13/07, David Chelimsky [EMAIL PROTECTED] wrote: The RSpec Development Team is pleased to announce the release of RSpec-1.0.8. RSpec 1.0.6 is the holy cow, batman, it's been a long time since we released and there are a ton of bug fixes, patches and even new features release. RSpec 1.0.7 and 1.0.8 deal with a regression introduced in 1.0.6 and a hiccup in releasing 1.0.7, respectively. == RSpec RSpec is a Behaviour Driven Development framework which plays the same role that a unit testing framework would play in Test Driven Development, but does so using words and structures that better support BDD. http://rspec.rubyforge.org == rspec_on_rails rspec_on_rails is a Ruby on Rails plugin that supports a BDD approach to developing the various layers of objects within a Rails application. See http://rspec.rubyforge.org/documentation/rails/index.html == Installation http://rspec.rubyforge.org/download.html http://rspec.rubyforge.org/documentation/rails/install.html ___ 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] expect_render, why does there need to be a warning
On 8/15/07, David Chelimsky [EMAIL PROTECTED] wrote: On 8/15/07, Zach Dennis [EMAIL PROTECTED] wrote: On 8/14/07, David Chelimsky [EMAIL PROTECTED] wrote: On 8/14/07, Zach Dennis [EMAIL PROTECTED] wrote: On 8/14/07, David Chelimsky [EMAIL PROTECTED] wrote: On 8/14/07, Zach Dennis [EMAIL PROTECTED] wrote: There is a warning on the web site about expect_render and stub_render: WARNING: expect_render and stub_render, while very useful, act differently from standard Message Expectations (a.k.a. mock expectations), which would never pass calls through to the real object. This can be very confusing when there are failures if you're not aware of this fact, because some calls will be passed through while others will not. This is especially confusing when you use stub_render because, as with all Method Stubs, you will get very little feedback about what is going on. My questions: Is this a sign that expect_render is doing to much? Is there a benefit from having expect_render and stub_render sometimes pass the render call to the underlying template object? Why not force all partials to be tested individually? Testing partials individually seems like a cleaner, more consistent and less confusing route to go, especially when you consider the nesting of paritals which render other partials. That's the whole reason for the existence of expect_render. If you're spec'ing '_outer_partial' and you want to specify that it renders '_inner_partial', but you don't want to actually render '_inner_partial', there is no way to do that with traditional mocking frameworks because they are not designed to pay attention to one call to a method: render(:partial = '_inner_partial') while letting another call to the same method: render(:partial = '_outer_partial') through to the object. Agreed that expect_partial is doing to much, but what alternatives do we have? When testing views the first call to render is going to be the one that should be passed to the underlying template, since this is from the test. Every subsequent call to render will be done from within the template, so RSpec can look for a matching expectation. It seems that expect_render is in charge of setting those up. If this is done then a simple convention will be enforced, every inline render :partial call will have to be expected in a view spec, and every view template (or partial) will have to have it's own view test. This gets rid of issues of nesting, confusion and poorly written specs where someone is asserting contents of a partial rendered multiple levels deep in the render chain. Granted you end up with more view tests, but they are cleaner, shorter and easier to read. More importantly they are easier to maintain and update because they will be easy to find an existing spec for to start test driving changes, rather then having to find the view which renders your partial and the spec that renders that view (and heaven forbid your partial is used in several views, and each view tests the contents of that partial). I think you are describing a good convention, but I don't think rspec should force it on everybody. The goal here is to provide tools that ALLOW you to do things in certain ways but not force you to. For example, rspec_on_rails supports isolated views, but you can do rails-style functional tests (using controller specs with integrated views) if you want. How about a integrate_inline_renders similar to integrate_views? Just don't use expect_render and it'll do that. Magic! I'm on the opposite view point. I don't want to pass through renders, I want to force all inline renders to be enforced. If i have a view that calls render :partial = 'foo' and I don't use expect_render I want it to yell at me saying an unexpected call was made on the template. Zach ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] undefined method `mock_model' for [RSpec example]:#Class:0x25550a8
On 8/20/07, David Chelimsky [EMAIL PROTECTED] wrote: On 8/20/07, Zach Dennis [EMAIL PROTECTED] wrote: On 8/20/07, aslak hellesoy [EMAIL PROTECTED] wrote: Several problems here: First, rspec_scaffold must be given a *singularised* name, in your case 'product'. (This is Rails being finicky, not RSpec). ok Second, after running rspec_scaffold you must run rake db:migrate This I didn't do, but doing this makes no difference on the mock model error. This does fix the issue if I run the spec from RAILS_ROOT, but not if I run the spec from within the spec/views/products directory. Ah - now THAT makes sense. This won't work on any system at all. RSpec looks for /spec/views/ in the path to know that it's a view spec. If you're in the view spec directory, it doesn't get the information it needs. Make sense? Third, before you can run specs with ruby or spec, you must create the test database. This can be done with rake spec or rake db:test:prepare The database was already in existence, so I left that part omitted in the video If I run specs from RAILS_ROOT then everything works, but not if I'm not in RAILS_ROOT. This is less of an issue I originally thought, but the directory thing is a minor irritation, although I can make sure to run specs from the RAILS_ROOT. We'd have to change how rspec figures out what behaviour_type to use to reduce the irritation. Any suggestions? Use expand_path on the current file and see if it is in RAILS_ROOT/specs/views ? Zach ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Story Runner: Readability of output with multiple params
On 10/13/07, David Chelimsky [EMAIL PROTECTED] wrote: And the user, Joe, works for, Acme, as a, janitor I vote no on this. And the user $user works for $company as a $jobtitle, Joe, Acme, janitor If these are the two choices then this one is better, but this doesn't feel quite right. It seems like StoryRunner should maintain consistent and clean readability. The argument passing nature of declaring values used in tests at the story part (Given, When, etc.) description reduces readability. For another discussion it may be valuable to discuss whether or not the story parts (Given, When, etc..) should even support do/end blocks. I realize this kills the ability to mark things as pending in StoryRunner, but that seems like a side effect that could be overcome. Do/end blocks seem to add unnecessary code ugliness for the Story's themselves. I like reading: Given a user for the company acme When they login Then they see their user profile And not: Given a user for the company, Acme do |company| # code here... end When they login, Joe do |login| # the login code. end Then they see their user profile do #... end it seems like a good idea to keep acceptance test declaration separate from the implementation this Story's are supposed to be at a higher level then spec examples. I like to keep them closer to customer readable/writable myself. Zach ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Story Runner: Readability of output with multiple params
Does it add any value to even add things like Joe and Acme into a story part? It seems like that is an implementation detail of your story. Who cares about Joe or Acme, don't you just care that you have a user who works for a company. And if that company has a particular trait wouldn't it be cleaner to identify the company by that trait rather then a name in the description? IE: Given a user who works for a company that sells cartoons And then in your helper you can use Joe and Acme def a_user_who_works_for_a_company_that_sells_cartoons @user = Generate.user( joe) @company = Generate.company(Acme) @company.employees = @user end ? -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] plain text stories
Nice work David! This is a wonderful step in the right direction! Zach Dennis http://www.continuousthinking.com On 10/21/07, David Chelimsky [EMAIL PROTECTED] wrote: Thanks to discussions on this list, suggestions from many of you and a patch from Pat Maddox, we now have Plain Text User Stories in Story Runner. Read more: http://blog.davidchelimsky.net/articles/2007/10/21/story -runner-in-plain-english Cheers, David ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] rspec_on_rails, receive_and_render experiment
A recent exploration on receive_and_render to assist with some common view spec'ing can be found at http://www.continuousthinking.com/2007/11/14/rspec_on_rails-render_and_receive_matcher Suggestions and feedback are welcome. Thanks, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] textmate bundle
Does anyone else have issues running rspec textmate bundle? I've got revision 2997, but the blasted thing just won't run. It is checked out to my /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle When it runs I get the below error... textmate is not a valid class name /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/options.rb:173:in `load_class': textmate is not a valid class name (RuntimeError) from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/options.rb:137:in `parse_format' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/option_parser.rb:93:in `initialize' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1260:in `call' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1260:in `parse_in_order' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1247:in `catch' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1247:in `parse_in_order' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1241:in `order!' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/option_parser.rb:118:in `order!' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1332:in `permute!' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1353:in `parse!' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1343:in `parse' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/option_parser.rb:10:in `parse' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:34:in `run' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:33:in `chdir' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:33:in `run' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:12:in `run_file' from /tmp/temp_textmate.AZtCnz:4 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] textmate bundle
On Nov 28, 2007 11:56 AM, Brian Takita [EMAIL PROTECTED] wrote: Hello Zach. Are you running Rspec 1.0.8 with the Trunk version of the Textmate Bundle? It wasn't 1.0.8, but it was a revision from about a month ago, give or take a few days. I've updated to trunk and that problem has gone away. Running all examples works, but running focused examples blows up with the below error. This appears under the green RSpec Results header: /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb:108:in `run': You have a nil object when you didn't expect it! (NoMethodError) You might have expected an instance of Array. The error occurred while evaluating nil.empty? from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:22:in `run' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:21:in `each' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:21:in `run' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/options.rb:85:in `run_examples' from /Users/zdennis/source/ao_projects/circlebuilder/vendor/plugins/rspec/lib/spec/runner/command_line.rb:19:in `run' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:34:in `run' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:33:in `chdir' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:33:in `run' from /Users/zdennis/Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/../spec/mate/runner.rb:17:in `run_focussed' from /tmp/temp_textmate.zWPVDL:4 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Mocks? Really?
On Dec 26, 2007 3:23 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Dec 23, 2007 2:27 PM, Zach Dennis [EMAIL PROTECTED] wrote: I know the questioned are directed towards Dan so I hope you don't me chiming in. My comments are inline. Thanks a lot for your comments, I really appreciate them. I've been dying to respond to this for the past several days, but haven't had internet access. On Dec 15, 2007 2:17 AM, Pat Maddox [EMAIL PROTECTED] wrote: On Dec 8, 2007 4:06 AM, Dan North [EMAIL PROTECTED] wrote: I prefer the mantra mock roles, not objects, in other words, mock things that have behaviour (services, components, resources, whatever your preferred term is) rather than stubbing out domain objects themselves. If you have to mock domain objects it's usually a smell that your domain implementation is too tightly coupled to some infrastructure. Assuming you could easily write Rails specs using the real domain objects, but not hit the database, would you never mock domain objects (where never means you deviate only in extraordinary circumstances)? I'm mostly curious in the interaction between controller and model...if you use real models, then changes to the model code could very well lead to failing controller specs, even though the controller's logic is still correct. In Java you don't mock domain objects because you want to program toward an interface rather then a single concrete implementation. Conceptually this still applies in Ruby, but because of differences between the languages it isn't a 1 to 1 mapping in practice. I must be misunderstanding you here, because you say you don't mock domain objects, and the rest of your email suggests that you mock basically everything. I'll respond more later, but wanted to point out that that should be In Java you mock domain objects because you want to I don't know how the n't got in there. ;) Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Mocks? Really?
On Dec 26, 2007 3:23 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Dec 23, 2007 2:27 PM, Zach Dennis [EMAIL PROTECTED] wrote: I know the questioned are directed towards Dan so I hope you don't me chiming in. My comments are inline. Thanks a lot for your comments, I really appreciate them. I've been dying to respond to this for the past several days, but haven't had internet access. On Dec 15, 2007 2:17 AM, Pat Maddox [EMAIL PROTECTED] wrote: On Dec 8, 2007 4:06 AM, Dan North [EMAIL PROTECTED] wrote: I prefer the mantra mock roles, not objects, in other words, mock things that have behaviour (services, components, resources, whatever your preferred term is) rather than stubbing out domain objects themselves. If you have to mock domain objects it's usually a smell that your domain implementation is too tightly coupled to some infrastructure. Assuming you could easily write Rails specs using the real domain objects, but not hit the database, would you never mock domain objects (where never means you deviate only in extraordinary circumstances)? I'm mostly curious in the interaction between controller and model...if you use real models, then changes to the model code could very well lead to failing controller specs, even though the controller's logic is still correct. In Java you don't mock domain objects because you want to program toward an interface rather then a single concrete implementation. Conceptually this still applies in Ruby, but because of differences between the languages it isn't a 1 to 1 mapping in practice. I must be misunderstanding you here, because you say you don't mock domain objects, and the rest of your email suggests that you mock basically everything. snip Do you try to test each class in complete isolation, mocking its collaborators? Yes. The pattern I find I follow in testing is that objects whose job it is to coordinate or manage other objects (like controllers, presenters, managers, etc) are always tested in isolation. Interaction-based testing is the key here. These objects can be considered branch objects. They connect to other branches or to leaf node objects. Leaf node objects are the end of the line and they do the actual work. Here is where I use state based testing. I consider ActiveRecord models leaf nodes. What about interactions between ActiveRecord objects. If a User has_many Subscriptions, do you mock out those interactions? For me it depends. If I am testing my User object and it has a custom method called find_subscriptions_which_have_not_expired_but_which _has_not_been_read_in_over_n_days. I will not mock out any interactions with the subscriptions at that point. This is for two reasons. One, when I first get this to work I may do it in pure ruby code (no SQL help) just to get it working. At some later date/time this is going to move to SQL. I want my test to not have to change in order to do this. If I was interaction-based testing this custom find method then it wouldn't really help me ensure I didn't break something. Secondly, I view my model has a leaf node object. Most of everything my model does I want to state based test the thing to ensure the results are what I want (and not the interactions). Some times I find there is a method where I will mock an association because I truly don't care about the result, and I really only care about the interaction. For example if User delegates something to the Subscription class either via a delegate declaration or a simple method which delegates. For example: delegate :zip_code, :to = :address OR def zip_code address.zip_code end Would you still mock them out if User and Subscription were PROs (plain Ruby objects) and persistence were handled separately? Possibly. I think it depends on how the objects used each other, what kind of mini-frameworks or modules were in place to give functionality, etc. Since models get most of their functionality through inheritance of ActiveRecord::Base it would be difficult to compare w/o knowing how my PROs were hooked up. Composition or inheritance makes a difference in my head right now. Do you have any specific concrete examples in mind? When you use interaction-based tests, do you always leave those in place, or do you substitute real objects as you implement them (and if so, do your changes move to a more state-based style)? Leave the mocked out collaborators in place. An interaction based test verifies that the correct interaction takes place. As soon as you remove the mock and substitute it with a real object your test has become compromised. It's no longer verifying the correct interaction occurs, it now only makes sure your test doesn't die with a real object. This leads to perhaps a more subtle case of my previous question...ActiveRecord relies pretty heavily on the real classes of objects. To me, this means
Re: [rspec-users] Do you think it would look cleaner?
On Dec 29, 2007 1:29 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Dec 28, 2007 11:00 PM, Andrew WC Brown [EMAIL PROTECTED] wrote: I was looking over some of my specs. I was thinking that the following: @game.should_receive(:name).and_return('The Battle for Blaze') @game.should_receive(:people).and_return(500) @game.should_receive (:activated).and_return(true) Would it look cleaner if I could do this instead? @game.should_recieve_and_return( :name = 'The Battle for Blaze' :people = 500 :activated = true) Opinions? I find this more confusing. When I first read it I thought it was going to receive the hash as arguments and return the hash. I think the expressiveness of should_receive(...).and_return(...) wins in this case, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Mocks? Really?
On Dec 31, 2007 12:53 PM, Rick DeNatale [EMAIL PROTECTED] wrote: On Dec 30, 2007 10:09 PM, Francis Hwang [EMAIL PROTECTED] wrote: On Dec 30, 2007, at 9:38 PM, Jay Levitt wrote: Incidentally, how well-tested was that code base? 200 lines of copy- and-paste smells like untested code to me. 15-20 years ago, unit tests were not a widespread industry practice :) This code's in a procedural language that really, really doesn't do unit tests well. I've been trying, too. Almost wrote a pre- processor, till I thought about the maintenance nightmare that'd cause. Right, that's why I ask. I think working with languages, tools, and frameworks that are easier to test is a great advantage to how we all worked 10 or more years ago ... I suspect part of that luxury translates in being able to actually design _less_, since the cost of fixing our design mistakes in the future goes down significantly. I don't think of it as designing less. (B/T)DD means designing incrementally. I read recently something where someone made a distinction between invention and discovery. Rather than sitting down 'ahead of time' and inventing a design, you can discover the design as you go. I don't think it is designing less either. It's designing better and doing it smarter, knowing that you'll never fully comprehend the domain of your problem upfront, so you discover it, iteratively. As you discover more about the domain the design of your program changes (during refactoring) to support a domain model to which it is representing. This is a concept from Domain Driven Design. It Francis is referring to doing less upfront design to try to master it all from the outset, then I agree that less of that is better. But that is entirely different then just doing less design. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Mocks? Really?
On Jan 1, 2008 1:48 PM, Francis Hwang [EMAIL PROTECTED] wrote: On Dec 31, 2007, at 1:10 PM, Zach Dennis wrote: I don't think it is designing less either. It's designing better and doing it smarter, knowing that you'll never fully comprehend the domain of your problem upfront, so you discover it, iteratively. As you discover more about the domain the design of your program changes (during refactoring) to support a domain model to which it is representing. This is a concept from Domain Driven Design. It Francis is referring to doing less upfront design to try to master it all from the outset, then I agree that less of that is better. But that is entirely different then just doing less design. I'm not certain how much we're genuinely disagreeing here and how much we're talking past each other -- I'm certainly feeling like I'm not communicating my amorphous ideas very well. I think I understand what you are trying to get across. That is why I've communicated back what I think you have said (or at least what I think you mean) in each of my responses, hopefully clarifying my position (in both agreement and disagreement) to something more specific, since phrases like designing less can be taken in several ways and carry several different meanings. I'd much rather discuss a particular aspect of designing less where it is advantageous or not. One thing that seems fuzzy to me is the implied time frames here. Let me ask you this, Zach: Is it your aim that your released code always contains a set of classes whose interactions with other classes is well-structured and defined, through mocks, and other tools? It is my aim that objects, their responsibilities and their interactions are purposefully structured and defined. For me, this is through the iterative process of adding features to the system in a TDD/BDD manner. Since I test drive feature implementation I have explicitly made a decision to create a new object, add a new responsibility to an existing object, or move responsibilities from one object to another. Mocks are simply a tool that I use to help me discover interfaces and objects. They also help me express the coordination and interaction between objects which fulfill an application requirement, and they provide the added benefit of testing objects in isolation without the unnecessary complexity of testing objects throughout the test suite (which I believe strict state based testing of everything does). I do not use any tool primarily for the sake of designing a well-structured class taxonomy or detailed system design. No all encompassing UML diagrams or oodles of documentation. I strive for the domain driven design principle of having the domain model in the code accurately reflect the domain you are solving a problem for. And is it your belief that you can always seek to release code which embodies a precise understanding of the domain in question? I believe you can always seek to release code which is an accurate reflection of the domain you are solving a problem for. I do not believe that the code itself will be a precise understanding of the domain in question. The features you implement will be solving a specific problem in a given domain. What is required to implement those features are only part of the domain. Ideally, what is implemented is only precise enough to satisfy the feature requirement. A lot of parts of the domain will be missing. Initially, the understanding of the domain may be fuzzy at best. But you start with a single feature to implement and you begin modeling the domain within your codebase for only what is required to implement that feature. You may only end up with a couple of objects; hardly a precise or perfect understanding of the domain at large, but as more features are added and time passes you get a better grasp of the domain. As you implement more features you will most likely discover new objects and responsibilities. This may entail extracting behavior from existing objects onto a new object because it better reflects what is required in the domain or it may promote single responsibility or separation of concerns and the concept of simple objects. The whole process though is something that is learned, continually and incrementally. I don't stop development of a feature because I am not an expert of the domain I am working in. I have to understand what is required to implement a particular feature or solve a particular problem anyways -- so I try to understand how the business expert or customer understands it and I try to keep that understanding consistent within the codebase. Specifically the domain objects in the application. I agree with a lot of the concepts behind domain driven design and how it works with agile (specifically XP in my case) development. It has created simpler code, easier to understand and maintain code and better test suites for apps that I've worked on. I suppose part of what I'm saying
Re: [rspec-users] Do you think it would look cleaner?
On Dec 30, 2007 4:47 AM, Kero van Gelder [EMAIL PROTECTED] wrote: I was looking over some of my specs. I was thinking that the following: @game.should_receive(:name).and_return('The Battle for Blaze') @game.should_receive(:people).and_return(500) @game.should_receive(:activated).and_return(true) Would it look cleaner if I could do this instead? @game.should_recieve_and_return( :name = 'The Battle for Blaze' :people = 500 :activated = true) Opinions? A Hash is not ordered. (but the 1st set of statements is) I don't know if this matters in this case. RSpec doesn't enforce strict-order mocking. Nor does Mocha. Hardmock is the only mocking library in ruby that I know of that can do this, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Do you think it would look cleaner?
I learn something everyday. Thanks On Jan 2, 2008 5:09 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Jan 2, 2008 5:20 PM, Zach Dennis [EMAIL PROTECTED] wrote: RSpec doesn't enforce strict-order mocking. Sure it does, if you ask it to: http://rspec.info/documentation/mocks/message_expectations.html -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Do you think it would look cleaner?
On Jan 3, 2008 12:20 PM, Kerry Buckley [EMAIL PROTECTED] wrote: On 2 Jan 2008, at 22:09, David Chelimsky wrote: On Jan 2, 2008 5:20 PM, Zach Dennis [EMAIL PROTECTED] wrote: RSpec doesn't enforce strict-order mocking. Sure it does, if you ask it to: http://rspec.info/documentation/mocks/message_expectations.html Am I right, though, in thinking that you can't enforce order between two mocks? It would occasionally be nice to be able to say something like: master.should_receive(:start).and_then(slave).should_receive(:start) I'd like to be proven wrong again, but I don't think you can do this with rspec. From running some examples in irb it looks like each mock only verifies its own order. Hardmock does support this. Flexmock does not that I am aware of, and Mocha most certainly does not. Hardmock considers all expectations ordered across all mocks. Hardmock does work with rspec too: http://hardmock.rubyforge.org/doc/index.html -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] specs on private methods
On Jan 11, 2008 5:23 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Jan 11, 2008 3:49 AM, Shot (Piotr Szotkowski) [EMAIL PROTECTED] wrote: Daniel Tenner: Might be a personal thing, but my approach is that I try to test the public behaviour of the object. Testing private methods is, imho, getting dangerously close to specifying how the object does its business, rather than what it does. I agree on principle, but I ran into the following case in my PhD: There's a Decomposition class that decomposes an FSM to a given architecture. Its public methods should be new() and decompose!(). Now, decompose!() works by running a private method by_input_sets!() many times with different parameters. One run of by_input_sets!() takes a couple of seconds, so can be tested; one run of decompose!() takes much longer, so to test decompose!() I should stub by_input_sets!() so it returns canned data (right?). In this situation, I think I do need to test/spec the by_input_sets!() private method – otherwise there would be no code that would check on the way it works. In TDD there is a rule of thumb that says don't stub a method in the same class as the method you're testing. A simple rule I follow: Don't stub or mock the object under test. On Jan 11, 2008 9:04 AM, Shot (Piotr Szotkowski) [EMAIL PROTECTED] wrote: What about the general issue of a slow method that is fast enough to be testable in isolation, but some other method from the same class calls it so many times that it needs to be stubbed for that method to be spec'd in a sane manner? In addition to David's response to this, have you evaluated moving this method and its responsibility to its own object that could be tested in isolation, allowing you to not break the don't stub or mock the object under test guideline? -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] specs on private methods
We pass the required items in as method arguments. In the spirit of sharing code and getting people to review code. Here is our current LoginManager: class LoginManager include Injection inject :invitation_manager def login_from_cookie(cookies, session) CookieLoginManager.new( :cookies = cookies, :session = session, :invitation_manager = @invitation_manager ).login end def login_from_session(session) SessionLoginManager.new( :session = session, :invitation_manager = @invitation_manager ).login end def login_with_credentials(options, session, cookies) UserCredentialsLoginManager.new( :options = options, :session = session, :cookies = cookies, :invitation_manager = @invitation_manager ).login end def login_from_password_reset(user, session) PasswordResetLoginManager.new( :user = user, :session = session ).login end def login_from_signup(user, session) SignupLoginManager.new( :user = user, :session = session, :invitation_manager = @invitation_manager ).login end end The reason we did this in the first place was that we needed to be able to add functionality (accepting invitations) to the login process and it seemed to get ugly without having it isolated in it's own object. We use additional login managers behind the scenes to have simple testable objects for each type of login we do. The Injection module just lets us pull out existing objects from a global app content and assign them as instance variables. That is how we are getting reference to invitation manager. Zach On Jan 11, 2008 12:45 PM, Ben Mabey [EMAIL PROTECTED] wrote: Zach Dennis wrote: On Jan 11, 2008 11:56 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Jan 11, 2008 9:54 AM, Ben Mabey [EMAIL PROTECTED] wrote: David Chelimsky wrote: In TDD there is a rule of thumb that says don't stub a method in the same class as the method you're testing. The risk is that as the real implementation of by_input_sets!() changes over time, it has access to internal state that could impact the behaviour of decompose!(). So, stubbing a current_user method on a rails controller would be considered bad practice? I suppose stubbing the find on User would be just as easy but I have always just stubbed controller.current_user. Rails is tricky. These rules are stem from situations in which you are in complete control of the design. Clearly, Rails makes it easy to work with if you follow its conventions, but the resulting design is far from Object Oriented. This is not an inherently bad thing - don't get me wrong. I use Rails and it's a delight in terms of development. But it's a challenge in terms of this kind of testing. That said, the User class object is a different object than a user instance, so I have no issue w/ stubbing find on it. As for controller.current_user, a purist TDD view would have you move that behaviour elsewhere. I break the rule and just stub it directly. This general advice I learned from Uncle Bob Martin: sometimes you have to break the rules, but when you do you should do it consciously and feel dirty about it ;) On the current project we've quit moved all authentication into a LoginManager. This has worked out so nicely as we have simple methods for: login_from_cookie, login_from_session, login_from_user_credentials, etc. This cleans up a lot of the hairy code sprinkled throughout controllers and before filters which were trying to do some form of authentication based on peeking at the sessions themselves or validating users. Interesting, do you pass in the session in the constructor or how do you get access to the session data? -Ben -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] specs on private methods
To add, all of our managers return LoginResult objects which contain methods like: - successful? - user - message In the controller our code will look like: if login.successful? self.current_user = login.user else flash[:error] = login.message end This has worked well because it allows each our types of logins to generate an accurate login message based on the type of login. For example when a user logs in from a session you don't need a message, but after someone logs in with their credentials you may want to say You've successfully logged in. I like this approach because it removes responsibility away from the controller, and it makes things much easier to test (and to understand IMO). And you have a very readable API, Zach On Jan 11, 2008 12:49 PM, Zach Dennis [EMAIL PROTECTED] wrote: We pass the required items in as method arguments. In the spirit of sharing code and getting people to review code. Here is our current LoginManager: class LoginManager include Injection inject :invitation_manager def login_from_cookie(cookies, session) CookieLoginManager.new( :cookies = cookies, :session = session, :invitation_manager = @invitation_manager ).login end def login_from_session(session) SessionLoginManager.new( :session = session, :invitation_manager = @invitation_manager ).login end def login_with_credentials(options, session, cookies) UserCredentialsLoginManager.new( :options = options, :session = session, :cookies = cookies, :invitation_manager = @invitation_manager ).login end def login_from_password_reset(user, session) PasswordResetLoginManager.new( :user = user, :session = session ).login end def login_from_signup(user, session) SignupLoginManager.new( :user = user, :session = session, :invitation_manager = @invitation_manager ).login end end The reason we did this in the first place was that we needed to be able to add functionality (accepting invitations) to the login process and it seemed to get ugly without having it isolated in it's own object. We use additional login managers behind the scenes to have simple testable objects for each type of login we do. The Injection module just lets us pull out existing objects from a global app content and assign them as instance variables. That is how we are getting reference to invitation manager. Zach On Jan 11, 2008 12:45 PM, Ben Mabey [EMAIL PROTECTED] wrote: Zach Dennis wrote: On Jan 11, 2008 11:56 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Jan 11, 2008 9:54 AM, Ben Mabey [EMAIL PROTECTED] wrote: David Chelimsky wrote: In TDD there is a rule of thumb that says don't stub a method in the same class as the method you're testing. The risk is that as the real implementation of by_input_sets!() changes over time, it has access to internal state that could impact the behaviour of decompose!(). So, stubbing a current_user method on a rails controller would be considered bad practice? I suppose stubbing the find on User would be just as easy but I have always just stubbed controller.current_user. Rails is tricky. These rules are stem from situations in which you are in complete control of the design. Clearly, Rails makes it easy to work with if you follow its conventions, but the resulting design is far from Object Oriented. This is not an inherently bad thing - don't get me wrong. I use Rails and it's a delight in terms of development. But it's a challenge in terms of this kind of testing. That said, the User class object is a different object than a user instance, so I have no issue w/ stubbing find on it. As for controller.current_user, a purist TDD view would have you move that behaviour elsewhere. I break the rule and just stub it directly. This general advice I learned from Uncle Bob Martin: sometimes you have to break the rules, but when you do you should do it consciously and feel dirty about it ;) On the current project we've quit moved all authentication into a LoginManager. This has worked out so nicely as we have simple methods for: login_from_cookie, login_from_session, login_from_user_credentials, etc. This cleans up a lot of the hairy code sprinkled throughout controllers and before filters which were trying to do some form of authentication based on peeking at the sessions themselves or validating users. Interesting, do you pass in the session in the constructor or how do you get access to the session data? -Ben -- Zach Dennis http://www.continuousthinking.com -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] specs on private methods
On Jan 11, 2008 11:56 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Jan 11, 2008 9:54 AM, Ben Mabey [EMAIL PROTECTED] wrote: David Chelimsky wrote: In TDD there is a rule of thumb that says don't stub a method in the same class as the method you're testing. The risk is that as the real implementation of by_input_sets!() changes over time, it has access to internal state that could impact the behaviour of decompose!(). So, stubbing a current_user method on a rails controller would be considered bad practice? I suppose stubbing the find on User would be just as easy but I have always just stubbed controller.current_user. Rails is tricky. These rules are stem from situations in which you are in complete control of the design. Clearly, Rails makes it easy to work with if you follow its conventions, but the resulting design is far from Object Oriented. This is not an inherently bad thing - don't get me wrong. I use Rails and it's a delight in terms of development. But it's a challenge in terms of this kind of testing. That said, the User class object is a different object than a user instance, so I have no issue w/ stubbing find on it. As for controller.current_user, a purist TDD view would have you move that behaviour elsewhere. I break the rule and just stub it directly. This general advice I learned from Uncle Bob Martin: sometimes you have to break the rules, but when you do you should do it consciously and feel dirty about it ;) On the current project we've quit moved all authentication into a LoginManager. This has worked out so nicely as we have simple methods for: login_from_cookie, login_from_session, login_from_user_credentials, etc. This cleans up a lot of the hairy code sprinkled throughout controllers and before filters which were trying to do some form of authentication based on peeking at the sessions themselves or validating users. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] specs on private methods
On Jan 11, 2008 12:56 PM, Cody P. Skidmore [EMAIL PROTECTED] wrote: Thank you Zach. I was just about to ask about this. I'm just getting started with restful_authentication and have missed the context of your point. restful_authentication is such a huge improvement over what I'm use to. Could you elaborate just a little on the use context in controllers? Is this called from the authenticate method in the controller? Here is a before filter in our ApplicationController for attempting to log the user in from a cookie: Here is what we have in our application controller as a before filter for logging in from a controller: def login_from_cookie session[:invitation_code] = params[:code] if params[:code] unless logged_in? login = @login_manager.login_from_cookie(cookies, session) if login.successful? flash[:notice] = login.message self.current_user = login.user unless login.return_to.blank? redirect_to login.return_to return false end end end end And here is our SessionsController#create method for how to log in a user from their credentials: def create login = @login_manager.login_with_credentials(params[:login], session, cookies) if login.successful? self.current_user = login.user flash[:notice] = login.message redirect_to(login.return_to || home_path) session[:return_to] = nil else flash[:error] = login.message redirect_to signup_path(:login = {:email = params[:login][:email]}) end end You'll notice that we already have a @login_manager instance variable accessible in both cases. This is because of our use of the Injection plugin to automatically assign one for us from a global application context. You don't have to do that (but we like it because it decouples our controllers from implementation). You could construct a LoginManager where you need it, ie: LoginManager.new.login_with_credentials() We didn't set the methods up as class methods on LoginManager (ie: LoginManager.login_with_credentials) because we like to work with instances. We feel they are easier to test and refactor and it helps us avoid the temptation of adding class methods and instance methods which often times can lead to mixing multiple responsibilities onto an object. We're big fan of single responsibility. HTH, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] client first, top down, outside in, etc with rails
Another approach to what Pat mentioned is would be to use a presenter approach. We use presenters to encapsulate view logic and they often hide (or delegate) functionality to one or more models based on the UI component you're focusing on. This route doesn't muck up your models with things that may come in the future. When they do come you can refactor your presenter to delegate to your model, when and if your model is the object that is going to do the job. Right now it's all view implementation anyways and the way we use presenters encapsulate the requirements of the view. Here's some info on how we use presenters: http://spin.atomicobject.com/2008/01/27/the-exceptional-presenter/ The way we use presenter's is different then Jay Fields, so if you think you know what a presenter is and how to use them based on Jay Fields talks or blogs, then you should really read the above as its a different take on presenters with different goals in mind. Zach On Jan 29, 2008 1:34 AM, Pat Maddox [EMAIL PROTECTED] wrote: On Jan 28, 2008 3:24 PM, Jay Donnell [EMAIL PROTECTED] wrote: I guess I can use dummy methods in my models that simply return some canned result. Maybe even name it 'my_method_dummy' so I can easily track down the dummy methods. The stubbing syntax is so clean In rspec that I was hoping I could define a bunch of mocks in a single place, environment.rb maybe, and be able to easily glance to see what is still being mocked. We also have different people working on the views vs the models and would like for the views to progress separately from the models. We can do this by spec'ing the views in isolation but it would be nice to see the views integrated into a functioning page as well. hrm...well if you want it all in one place, I'd stick it in some mocked_methods.rb file and require that. You can open the classes you want there User.class_eval do def full_name Johnny Tsunami end end That way it's easy to see where they all are. You really don't need to introduce RSpec dependencies into your production code. Just define methods on the class you want, or use OpenStruct and return canned values, or write your own simple stub class. If I was doing this a bunch (I never would, of course :) then I might write a macro that defines these stubs for me and includes some diagnostic info, like a logger.warn(*** dude this is a stubbed method ***) and maybe the caller information as well. Then I could just do User.stub_method(:full_name, Johnny Tsunami) Going that route would let you collect info about how many times they're called, blah blah blah. Or you could just implement your code :) Pat ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Old Style Stories
On Wed, Feb 20, 2008 at 11:21 PM, Kero [EMAIL PROTECTED] wrote: I was working on a past project tonight to trunk which is using the old story format. IE: Given desc do / end When someting do /end etc.. Is this officially supported, or is this just something that hasn't been ripped out yet? It's funny to me that this is Old Style in your view. It's really just another approach. Plain text is great for some situations, but so is writing in Ruby :) Depends on the team, really, and how involved the customer is in actually doing the typing. If it is officially supported how attached are people to the re-using of do/end blocks which match the same description. Every now and then it bites me and I end up having to change one of the descriptions to differ textually then another. Why would this be specific to scenarios written in Ruby? IMO it is kind of annoying. A story part description may have the same description as another in the same scenario. Sometimes the sequence of steps provide the context, If I understand you correctly, then we had a discussion on this: http://rspec.lighthouseapp.com/projects/5645/tickets/167-blocks-provided-to-when-then-clauses-should-always-be-used and concluded that same-description means exactly-same-step, then continued http://rspec.lighthouseapp.com/projects/5645/tickets/172-warn-or-fail-on-re-specified-when-then-clause which is still open. Thanks for the links Kero. That ticket is the issue that I am talking about. This seems unfinished - was there more to this sentence? There may have been, but I cannot recall at this point. I think this is just a matter of documentation. If we got rid of block-sharing we'd be promoting much more verbose scenarios with a lot of redundancy. I think it's here to stay. An implementation of Kero's second ticket [0] would definitely help. That extra feedback of Hey, you already implemented this story part! Right there on line 11 would be great. A smaller annoyance associated with this is that story parts without blocks can get lost visually when in a sea of story parts with do/end blocks. I may be biased because on the last few customer driven production projects I've been using test/unit story runner, which I think is simpler and more developer friendly. [1] As you mentioned David, Plain text is great for some situations, but so is writing in Ruby. This begs the question now that we have plain text stories. Can we make the ruby-based stories more developer friendly? Perhaps remove string identifiers, use symbols. Quit passing in blocks to story parts, assume each story part is a method call, and I'm sure there are other things that could be suggested as well. -- Zach Dennis http://www.continuousthinking.com 0 - http://rspec.lighthouseapp.com/projects/5645/tickets/172-warn-or-fail-on-re-specified-when-then-clause 1 - http://www.continuousthinking.com/2007/11/14/test-unit-story-runner ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Old Style Stories
On Thu, Feb 21, 2008 at 11:40 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Thu, Feb 21, 2008 at 10:26 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Thu, Feb 21, 2008 at 9:07 PM, Zach Dennis As you mentioned David, Plain text is great for some situations, but so is writing in Ruby. This begs the question now that we have plain text stories. Can we make the ruby-based stories more developer friendly? Perhaps remove string identifiers, use symbols. Quit passing in blocks to story parts, assume each story part is a method call, and I'm sure there are other things that could be suggested as well. You can do all of this already except using symbols instead of Strings, something which doesn't strike me as more readable. Here's an example: http://pastie.caboo.se/155775 And here's another example with a bit more reuse expressed in the steps at the expense of more complexity in the steps. Which approach is better? I can't really say one is always better than the other. I choose based on readability in a given context. I hadn't even considered that using steps with the normal ruby stories was an option. This gives what I am looking for. As for symbols, they reduce a few keystrokes when you have to select them and/or see find them in a file or in the project, or copy them. They are not as readable as the strings as you point out. I may just need to buck up and/or write a macro which gives me the ability to select a string based on quotes. This is not really a story problem, more of my editor lacking a feature I want. Just exploring possibilities. Ditto. Thanks for the reply and for the code pastes. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] ActiveRecord, spec'ing find has right :order parameter
On Wed, Mar 5, 2008 at 12:28 PM, Rick DeNatale [EMAIL PROTECTED] wrote: I'm wanting to write a spec that a model is applying an :order option to a find call, but I don't want to completely specify all of the find parameters. So I want to write something like this, say in a controller spec User.should_receive(:find).with(:all, hash_with_at_least(:order = 'user.name ASC')) get 'index', :sort = 'up' This ability to partially specify the contents of a hash argument seems to be generally useful, particularly for Rails, and was wondering if anyone had done this. I don't think it would be too hard. Are you just wanting Mocha parameter matching? User.should_receive(:find).with(:all, has_entry(:order = 'user.name ASC')) get 'index', :sort = 'up' -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] [Stories] Login and subdomain
On Thu, Mar 6, 2008 at 10:38 AM, Pat Maddox [EMAIL PROTECTED] wrote: On Thu, Mar 6, 2008 at 7:27 AM, Ivo Dancet [EMAIL PROTECTED] wrote: You should not stub the authentication method in a story. The story should test the whole application framework, that way your story might look like this: Given a user from company x When logging in And requesting some page Then the application should do all the stuff it should In the given step you set your host, user name and password and you create that user. In the when steps you make the login request and then you can start doing the stuff you really want to test here as you'll have the session you want at that moment. That's a little too dogmatic for me. You needn't go through the entire stack every story, and you needn't go through the entire app path either. IMO you should be simulating as much as possible what the user is doing. If they have to go through path a, b, c ... to get to Z, then so be it. This involves keeping a well-factored set of helpers which can be used to navigate the app just like a user would. The only things you probably should be stubbing in a story are third party components your site may have to integrate with that aren't realistic to be run for every story (for the most part, there are other exceptions as well I know). I would avoid stubbing core functionality related to your site, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] [Stories] Login and subdomain
We do something very very similar but rather then it_should_behave_like we wrap it in a it_requires_login method... describe SomeController do it_requires_login end Zach On Fri, Mar 7, 2008 at 11:53 AM, Max Williams [EMAIL PROTECTED] wrote: I found it a little confusing to stub my authentication filters as well, but figured it out with a little help from the interwebs: in spec_helper i have this: describe a controller requiring login, :shared = true do it should have login_required set in the before filter do controller.class.before_filters.should include(:login_required) end end def mock_login_required(allow_user_to_pass=true) controller.stub!(:login_required).and_return(allow_user_to_pass) end Then, in any spec where i want to mock that filter, i just write it_should_behave_like a controller requiring login at the top of the describe block. Sorry, i can't remember the web page where i found this solution but respect to whoever posted it :) On 06/03/2008, Bastien [EMAIL PROTECTED] wrote: Thanks for your help. I tried the controller.stub!(...) as well, and it doesn't work. Ivo I totally agree with you and I'll follow your recommendations, thanks. (Would still be nice to know if the stubbing could work or if it's intended not to) On Mar 6, 4:27 pm, Ivo Dancet [EMAIL PROTECTED] wrote: You should not stub the authentication method in a story. The story should test the whole application framework, that way your story might look like this: Given a user from company x When logging in And requesting some page Then the application should do all the stuff it should In the given step you set your host, user name and password and you create that user. In the when steps you make the login request and then you can start doing the stuff you really want to test here as you'll have the session you want at that moment. Regards Ivo Dancet Op 6-mrt-08, om 16:12 heeft Bastien het volgende geschreven: Thanks David, this works just fine. I would rather do some stubbing there if it's possible though. I tried : ApplicationController.stub! (:user_authentication_required).and_return(true) (which is the filter called before each action that checks whether the user is logged in or not) But it doesn't work. When I do this : class ApplicationController def user_authentication_required return true end end it works fine (but I find it quite dirty to redefine my method that way). Aren't this two solutions supposed to give me the same result ? Is something wrong with my stubbing ? On Mar 6, 3:33 pm, Ivo Dancet [EMAIL PROTECTED] wrote: I think you can also use: post /authentication/login, { :login = user_email, :password = password }, :host = company.example.com Op 5-mrt-08, om 23:30 heeft Bastien het volgende geschreven: I've just begin using rspec stories, and i m encountering some problems. In my application i have different subdomains in which specific users can log in, for example an admin will go to admin.myapp.com/authenticate/login, and an user belonging to a specific company will log in company.myapp.com/authenticate/login, and of course both have a different login process. To perform some actions the user has to be logged in, and this is where the problem comes, how to test these actions ? - Is there a way to set a user as logged in ? (that would definitely be very convenient) So far I have tried to do the following : post /authenticate/login, {:login = user_email, :password = password } but the problem is that it doesn't use the correct subdomain and the login, as expected in that case, fails, so how to define the correct subdomain ? Thank you in advance for your help. ___ rspec-users mailing list [EMAIL PROTECTED] http://rubyforge.org/mailman/listinfo/rspec-users ___ rspec-users mailing list [EMAIL PROTECTED]://rubyforge.org/mailman/listinfo/rspec-users ___ rspec-users mailing list [EMAIL PROTECTED] http://rubyforge.org/mailman/listinfo/rspec-users ___ rspec-users mailing list [EMAIL PROTECTED]://rubyforge.org/mailman/listinfo/rspec-users ___ 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 -- Zach Dennis http://www.continuousthinking.com
Re: [rspec-users] Story testing views in isolation
On Tue, Mar 11, 2008 at 8:03 AM, Corey Haines [EMAIL PROTECTED] wrote: On Tue, Mar 11, 2008 at 6:16 AM, David Chelimsky [EMAIL PROTECTED] wrote: The reason that I want to do this is that I want to give our designer/business people a way to write stories to describe their user interface while they work on the prototype, then give us the stories to help us integrate their prototypes more safely. So you're hoping they'll use the stories and get them to pass against the views as they evolve? Yeah. I'd like to have them use the stories against the mockups they build, then we move the stories to the live app as we integrate their changes. These are just some initial thoughts I've had, so I'm always open to alternate ideas. One option I thought about was to use pages that don't have any functionality behind them (other than perhaps some basic navigation), then they could design their mockups against these. As we integrate their designs in, we can start adding functionality behind it. This seems more in line with (perhaps one of) the original ideas for stories. I realize that I could use examples for this, but I was hoping to use stories. There's really no support for this as it stands. Not sure if I'd want that to change. Other opinions? This feels like a square peg in a round hole type of situation. It doesn't seem like in practice this works very well: Given a user where? When they do something Then they see what? In isolation the Given/When/Then don't make as much sense because you can't do anything, you don't go anywhere and the Given/When/Then make less sense in the context of isolation. It also seems to muddy the definition of a story. All in all it just feels kind of funny. +1 for keeping view specs act as view specs and stories act as stories. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Story testing views in isolation
Corey, What part of the Story do you like that you want the designers to be exposed to? A higher level API, the plain text part (separation from implementation of the test), etc... ? Zach On Tue, Mar 11, 2008 at 8:39 AM, Zach Dennis [EMAIL PROTECTED] wrote: On Tue, Mar 11, 2008 at 8:03 AM, Corey Haines [EMAIL PROTECTED] wrote: On Tue, Mar 11, 2008 at 6:16 AM, David Chelimsky [EMAIL PROTECTED] wrote: The reason that I want to do this is that I want to give our designer/business people a way to write stories to describe their user interface while they work on the prototype, then give us the stories to help us integrate their prototypes more safely. So you're hoping they'll use the stories and get them to pass against the views as they evolve? Yeah. I'd like to have them use the stories against the mockups they build, then we move the stories to the live app as we integrate their changes. These are just some initial thoughts I've had, so I'm always open to alternate ideas. One option I thought about was to use pages that don't have any functionality behind them (other than perhaps some basic navigation), then they could design their mockups against these. As we integrate their designs in, we can start adding functionality behind it. This seems more in line with (perhaps one of) the original ideas for stories. I realize that I could use examples for this, but I was hoping to use stories. There's really no support for this as it stands. Not sure if I'd want that to change. Other opinions? This feels like a square peg in a round hole type of situation. It doesn't seem like in practice this works very well: Given a user where? When they do something Then they see what? In isolation the Given/When/Then don't make as much sense because you can't do anything, you don't go anywhere and the Given/When/Then make less sense in the context of isolation. It also seems to muddy the definition of a story. All in all it just feels kind of funny. +1 for keeping view specs act as view specs and stories act as stories. -- Zach Dennis http://www.continuousthinking.com -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] view spec on rails questions
For content_for blocks we have a separate testing.html.erb layout which we use when rendering our view from our spec. We then ensure the things generated in content_for are rendered correctly.. ie: render foo/index, :layout = testing Zach On Mon, Mar 10, 2008 at 11:23 PM, Jonathan Linowes [EMAIL PROTECTED] wrote: Hi I have a couple of questions 1) how do you test the response inside a content_for block I see reference to it in the release notes but dont know where to find it (tried http://rspec.info/rdoc-rails/ ) 2) I dont seem to be able to stub partials in a different directory eg %= render :partial = foos/show % And I put this in the spec template.stub_render(:partial = foos/show) the stub gets ignored and the partial still gets rendered It works fine with partials in the same directory I'm runing rspec 1.1.3 thanks linoj ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] RSpec view test for :partial with :locals?
Are you assigning @featured_user (ie: assigns[:featured_user]) before you render your template? We use :locals w/o any problem, for example: template.expect_render(:partial = 'profiles/data', :locals = {:profile = @profile}).and_return(%|p id='profiles_data_partial' /|) Zach On Tue, Mar 11, 2008 at 11:19 PM, David Schmidt [EMAIL PROTECTED] wrote: I'm currently working on some RSpec view tests and I'm having problems with expect_render. Most of the expect_render's work fine, but in one of my views I have: %= render :partial = user_cloud, :locals = {:user = @featured_user} % I see that expect_render supports :object or :collection for the second parameter, but this partial uses :locals. I tried expect_render without the second parameter and with :locals and it failed to match both times. I confirmed that the partial is rendering in the test.log. Is there a way to match this render? On a similar note, is there a way to test that layout views are rendered? I can test that the :partials in the layout are rendered, but not the layout file itself. In both of these cases I know I could do a has_tag and test for something inside the layout file or partial, but I'd rather test contents in a view test for each partial and just verify that the partial is rendered in the view tests that render the partial. Thank you, David ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Stories (well, integration tests) which aren't plain text
I put up a short post with code snippets of using RSpec's rubyesque stories: http://www.continuousthinking.com/2008/3/5/trying-rspec-s-rubyesque-stories Zach On Thu, Mar 13, 2008 at 12:21 PM, James Deville [EMAIL PROTECTED] wrote: Google for some of the stuff about story runner. It was originally not plain text, that's just a convenience. There are some earlier tutorials on David's blog about just doing stories. JD On Mar 13, 2008, at 9:11 AM, Rob Holland wrote: Hi, Having just played with getting my first plain text story working, I like how it all fits together. It worked out nicely. However, I don't feel our project needs to have stories as plain text, in fact it's a slight hindrance for us. Is there any sensible mechanism for doing integration testing using rspec without plain text stories? Thanks, Rob ___ 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 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Problems with form_for and partials
My pair and I have written a bunch of these helpers. I'll post what we have later, perhaps it will be a starting point, Zach On Fri, Mar 14, 2008 at 8:20 AM, Zach Moazeni [EMAIL PROTECTED] wrote: This hints at another extension I've wanted to write for us for a while. Common html selector strings, Labels, input fields, textareas, forms, links, etc Really just rolling up something like: response.should have_tag(input[type=text][name=?][value=?][id=company-name], user[company_name], Some Company Inc.) into something like: respose.should have_text_input(:user, :company_name, :id = company-name, Some Company Inc.) It feels closer to the Rails view helpers. Not a huge win, but we have so many selectors than abstracting up one would make our specs more readable. Damn To Code list... -Zach Begin forwarded message: From: Zach Moazeni [EMAIL PROTECTED] Date: March 13, 2008 1:46:34 PM GMT-04:00 To: rspec-users rspec-users@rubyforge.org Subject: Re: [rspec-users] Problems with form_for and partials We've been going down this route: http://pastie.caboo.se/165265 We use mocha for our mocking and originally we mocked out the form builder, but the specs felt crufty. We then converted to instantiating the FormBuilder and passing it to partials that needed it. For the views that send in the FormBuilder, we use the #with passing a block and assert the is_a? inside (I'm still not too keen on using the param helper/matchers). This looks a bit more bulky (and is kinda ugly in having assertions in a setup) but it really greased the wheels for us. We ended up preferring to assert the presence of html vs expectations on a FormBuilder stub, and it made the view specs feel a bit more natural. One last note: we hacked the #render in rspec_on_rails to output the contents of a partial (which is why the template stubbing the render returns form partial) and we assert the presence of that text in the response. Helps catch those rascally % % instead of %= %. I've been meaning to form together a patch and submit a proper extension, but it's as time allows. Perhaps a bit more than you were asking for, but I hope this helps -Zach On Mar 13, 2008, at 1:25 PM, Jonathan Linowes wrote: Thank you! for the record, I refactored my code so the view does a form_for, and any partials that render fields with the form builder does its own fields_for. This makes the design cleaner and more testable. However, I'm not sure if there's any performance cost in doing it this way instead of passing the form builder around, anyone? On Mar 13, 2008, at 5:05 AM, David Chelimsky wrote: On Wed, Mar 12, 2008 at 10:19 PM, Jonathan Linowes [EMAIL PROTECTED] wrote: On Mar 12, 2008, at 5:47 PM, David Chelimsky wrote: On Wed, Mar 12, 2008 at 9:43 PM, Zach Dennis [EMAIL PROTECTED] wrote: You can use mocha parameter matching to match on anything where your form builder would be passed in. You could also use Mocha's kind_of parameter matcher to ensure that what you expect is a FormBuilder object. Another way to do this is to not pass in your form builder, but the object needed, and then use fields_for inside the partial itself. This works well in some scenarios. You could also use rspec's parameter matching, which also supports anything but not kind_of ;) how would i use that in stub_render? eg if my view has %= render :partial = 'pages/foo', :layout = 'bar', :locals = { :f = f } % what's the stub? As of 1.1.3: stub_render(:partial = 'pages/foo', :layout = 'bar', :locals = {:f = }) There is now, in trunk, hash_including matcher, so you *should* (I haven't tried yet) be able to do this: stub_render(hash_including(:locals = {:f = })) That keeps it a bit less brittle, as the previous version will fail if you add anything else to the actual render call this won't fail. Cheers, David ___ 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 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 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Disabling a set of tests?
At the top of the file put... __END__ Zach On Fri, Mar 14, 2008 at 1:46 PM, Will Sargent [EMAIL PROTECTED] wrote: Hi all, Part of the integration test suite involves running against a sandbox on Paypal's server. Lately that server's been acting flakely. It doesn't fail all the time, but enough to confuse people. I made pending some tests that looked like they were repeat offenders, but now I'm seeing the same thing appear elsewhere. Is there any way to disable all the tests in a spec file at once? Will. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Am I off track on my testing?
On Fri, Mar 14, 2008 at 2:08 PM, __iso __ [EMAIL PROTECTED] wrote: Zach Dennis wrote: When I write software for myself I tend to flip flop. Sometimes I am writing things to learn or play and I don't test. I did that on a recent small project and I was amazed at how fast I was able to get things done. Here's another perspective to look at it from. When you write testable and tested software you spend less time coming back to it to track down and fix erroneous bugs. There is a much higher risk you will have to track down and fix erroneous bugs when you don't test (or don't test well there is a difference). One of the issues that I have had a couple times is that since I am writing the tests and the corresponding code in a serial fashion, sometimes my mind is off tangent and I write a test that is incorrect, I then write the corresponding code to allow the incorrect test to pass. And voila I have given myself confidence that everything is in working order since I tested it, but it is wrong. I believe, that one of the reasons for this is that I am writing too many tests, and because of that the tests start to lose their meaning. The tests become a series of tasks that I hastily try to place a check next to so I can feel I am working efficiently and move on to the next one. I think cutting down on the number of tests I write will allow me to better ensure the tests I have are required and correct. I am beginning to think that if a person checks the code to test code ratio more than once a week they may be testing for the wrong reason. First thing: do not stub or mock expect the object under test. When you're testing a controller do not stub! the controller and do not should_receive the controller. This removes the value you get for testing the controller itself. There are exceptions to this rule, and this is largely because people violate the use of mixins. That is for another conversation though. What would you recommend instead? Since the before_filter contains a login_required check I have to stub something to allow the test to be completed. I typically test filters by themselves, and then stub out the filters when testing the action, so there is a clear separation between the two. For logins I use a helper to ensure that a controller/action is requiring login if necessary. describe SomeController, #index do it_requires_login :get, :index end Then when testing the action itself I do stub all before filters, because I have already tested them elsewhere. If the action requires login I have a login_with_user helper which sets the logged in user to some mock User and then returns it so I can use it in my test. LIke below: describe SomeController, '#index do def get_index get :index end before do stub_before_filters! @user = login_with_a_user end ... end So when the application gradually becomes more complex do you think you'll eventually get to a point and say, well I need to test this now?. Unfortunately even if you do do that when you get to point there's a really good chance you didn't write the code for testability, so the barrier to test is much higher, and it's easier for people to give in and not test at this point because it's now to difficult to test, and they can't spend a long time fixing bad code they've written. Good point. I guess my confusion is to whether testing should exist where there is really no logic. Take an update controller method: @user = User.find(params[:id]) if @user.update_attributes(params[:user) flash[:success] = ... redirect_to admin_users_url else render :action = :index end Pretty simple stuff. Is it worth 40 lines of test code? That is what I am wondering, because I don't think so. Can someone change this implementation and still have your tests pass, but have the implementation be broken? If they can then yes it is worth the 40 lines. Pat mentioned that he uses very skinny controllers and does integration tests which go through the whole stack to make sure things work. So if he doesn't test the controller#action's because they are too simple he at least will have a failing integration test if someone breaks the implementation. The problem I have with what Pat is doing is that it takes a lot of discipline from the developer to not let the controller grow into a cesspool of logic and interaction that shouldn't be there, but you put it there because you aren't testing it directly. From what I've seen most Rails apps have important interaction in the controller actions and logic in the before filters. I would not personally take this approach on customer paid for software. Pat may be more disciplined then me though. =) Testing is not about developer enjoyment. It's about producing high quality low bug software in a way that allows you
Re: [rspec-users] Am I off track on my testing?
On Sat, Mar 15, 2008 at 5:43 PM, Ben Mabey [EMAIL PROTECTED] wrote: Zach Dennis wrote: Can someone change this implementation and still have your tests pass, but have the implementation be broken? If they can then yes it is worth the 40 lines. Pat mentioned that he uses very skinny controllers and does integration tests which go through the whole stack to make sure things work. So if he doesn't test the controller#action's because they are too simple he at least will have a failing integration test if someone breaks the implementation. The problem I have with what Pat is doing is that it takes a lot of discipline from the developer to not let the controller grow into a cesspool of logic and interaction that shouldn't be there, but you put it there because you aren't testing it directly. From what I've seen most Rails apps have important interaction in the controller actions and logic in the before filters. I would not personally take this approach on customer paid for software. Pat may be more disciplined then me though. =) I totally agree with this point. Using interaction-based testing really helps in forcing the logic down into the model. I'm curious about your comment: From what I've seen most Rails apps have important interaction in the controller actions and logic in the before filters. What are you exactly referring to? I generally use before filters for authentication... How have you seen them abused? I've seen before filters be abused. Authentication is typical an application level responsibility and it makes sense for the controller to protect its resources. No qualms there. I have inherited code bases which abused before filters for things like checking permissions for business requirements. For example: class ProjectsController ApplicationController before_filter :login_required # i'm ok with this before_filter :ensure_project_manager, :only = [:new, :create] before_filter :ensure_project_write_access, :only = [:edit, :update] # ... I've seen this filter list go on and on and on, based on any possible persmission I would rather introduce a Manager/Service object which is responsible for accessing a project, and allow that do handle the responsibility for knowing what permissions allow someone to create or edit a project. I've been experimenting with using an approach similar in spirit to what Pat is doing, but slightly different: class ApplicationController ActionController::Base rescue_from AccessDenied, ResourceNotFoundError do |exception| redirect_to /access_denied.html end # ... end class ProjectsController ApplicationController before_filter :login_required def new @project = ProjectManager.new_project end def create ProjectManager.create_project params[:project] do |project_creation| project_creation.success do |project| flash[:notice] = Project created successfully @project = project end project_creation.failure do |project| flash[:notice] = Project creation failed @project = project render :action = new end end # ... end I tend to like this for projects I've worked on where it doesn't make sense to shove all of the responsibility onto a model because it abstracts out the Manager who is in charge of ensuring permissions and doing odds and ends things involved in the creation of a project that the model should not be doing (like upload an associated picture of the project manager or ensure memberships status). In the above approach the application controller is setup to rescue from certain application exceptions, and the controllers just do their thing, and the managers which enforce the business logic will throw the exceptions it a business rule has been violated. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Specifing methods in a steps_for block
I have been putting helper methods inside of my own modules and then including them in RSpec::Story::World, which included in the context that stories are defined and run in (David, feel free to correct me if this is not 100% accurate). module Spec::Story::World def foo # this is now available to all stories being run end end Zach On Mon, Mar 17, 2008 at 9:41 AM, Ashley Moran [EMAIL PROTECTED] wrote: On 17/03/2008, Corey Haines [EMAIL PROTECTED] wrote: As an interim solution, we added this as helper file in the stories root. The key was figuring out what to mixin to. class ActionController::Integration::Session # ... end -Corey Pretty neat! Unfortunately I don't think I can do something similar. I'm using the story runner raw to drive selenium, so only have access to the RSpec library and nowhere to inject these helper methods. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Specifing methods in a steps_for block
On Mon, Mar 17, 2008 at 9:59 AM, Bart Zonneveld [EMAIL PROTECTED] wrote: On 17-mrt-2008, at 14:51, Zach Dennis wrote: I have been putting helper methods inside of my own modules and then including them in RSpec::Story::World, which included in the context that stories are defined and run in (David, feel free to correct me if this is not 100% accurate). Hmm, maybe I should clarify some more.. Imagine the following, untested, proof-of-idea code: steps_for(:adding_posts) do def valid_post { :title = 'My First Post' } end end steps_for(:common) do Given a valid post do post /posts/create, post = valid_post end end valid_post is not defined for steps_for(:common). I'm sorry my last email should have said Spec::Story::World not RSpec::Story::World. And your steps are executed in the context of Spec::Story::World, so it doesn't matter if the method is defined inside of your steps for. I understand what you want to do, but you can write better helpers which don't have this problem. For example I use the form_test_helper to submit forms in Story's, so I don't have to call post directly. I have a submit_event_form which submits a valid form by default. ie: def submit_event_form submit_form event-form do |form| form.event.name = Foo end end Then in my step matcher I have something like: When they submit the event form with invalid information do submit_event_form do |form| form.event.name = end end If I have to reuse that in more then one place I pull it out into a submit_event_form_with_invalid_information method. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] should have_tag outside Rails
http://git.or.cz/course/svn.html and also search google for git for svn users Zach On Mon, Mar 17, 2008 at 5:22 PM, Ashley Moran [EMAIL PROTECTED] wrote: On 17 Mar 2008, at 18:41, Kyle Hargraves wrote: We discussed this in a ticket on lighthouse, and I ended up writing a workalike that's sitting atop hpricot. It's not quite identical, but generally close enough and so far does everything I've needed: http://github.com/pd/rspec_hpricot_matchers Patches and/or suggestions welcome if you need anything else out of it Kyle Hi Kyle That's brilliant! I looked for something but couldn't find anything. I did some work on it this afternoon and got as far as @elements.should have_tag(#selector, :count = 2) but didn't manage inner text comparisons or nested matchers. I'm unfamiliar with git - what's the best way to include that code in a Rails app stored in SVN? RTFM link to the git docs or similar welcome... When I've finished this contract I hope to spend some time working on open source code for story/runner selenium integration, if so I will definitely put anything relevant back into that matcher. Ashley ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Why not MockEverthing or why use fixtures for all tests?
and complexity (business logic of course) good developers will decompose the problem into a number of simple objects. Some of these objects are responsible for doing the work and others are responsible for coordinating other objects to do the work. Objects which are responsible for coordinating are great candidates for using interaction-based testing, because you are concerned in the interaction, not the state. If you don't have integration tests then using an interaction-based testing approach is not worth it because you need something that is going to test the real objects working with real objects. In Rails you can write integration tests as Rail's ActionController::IntegrationTests, Rail's functional tests, RSpec stories, or RSpec controller tests w/view isolation turned off. IMO, one false benefit of only using a state-based approach when writing a full-fledged application is that every object is essentially an integration test at some level. You are always testing everything with everything that it touches. This can lead to having one failure in one model make several other model tests fail, and it can make several controller tests failing (as well as any other object which touches the model that is failing). I see this has a big negative because it makes it more difficult to pinpoint the issue. People will end up tracking it down, but it can be time consuming and frustrating. Now on the flip side people will complain that they renamed a model method and re-ran all of their tests and everything passed, but when running the application a bug exists. Doh, we forgot to update the controller that relied on calling that model method. It is normal to say/think, well that should have failed because the method doesn't exist on the model. (It sounds like David Chelimsky may have something in trunk to help with this.) The main problem here though is that an integration test didn't fail exposing that you weren't done with your change. Thinking back to coordinating objects, my controllers don't contain business logic in them because they are application layer classes, they aren't apart of the domain of my software. They are only used by the application to allow the software to fulfill the requirements of my customer. Controllers are coordinators, not DOERS. They ask other objects to fulfill a business requirement for them like moving stocks from one portfolio to the another. So I used interaction-based testing here to ensure that my controller is finding a stock, finding a portfolio and asking a portfolio manager to move the stock to the designed portfolio. I don't need to have those things written or even fully implemented to ensure my controller works as I expect. I should be able to see that my controller does what it should be doing, even if the pieces it will use to do the work in the application aren't finished. Now if those aren't implemented I should have an integration test which fails showing me that the feature for moving stocks from one portfolio to another is not completed, but that isn't what I'm testing in my controller. Also after my controller works as expected I can go make sure the PortfolioManager works as expected, and then I can go down and make sure the Stock model does what I expect. When these objects are working correctly individual I run my integration tests to ensure they work well together. Another drawback of only using state-based testing is that you always have to develop bottom up. You have to start with the low level components and work your way out. I used to write code this way. I think I have progressed beyond that, and now I write things in a Acceptance Test Driven Development style. I start by writing an integration test from the user's perspective proving that the feature doesn't work, and then I move to the view, and then to the controller, then to any manager/factory/presenter/service objects that are required, and then down to any domain level objects (models and non-models alike). You can't do this approach with state-based testing only. There is a lot of value that can be gained by developing software this way. In short: Interaction-based testing allows you to ensure that an object is doing what you expect, without the underlying implementation having to exist yet at all or in full. It is great for application layer objects which typically only coordinate domain layer objects where the correct interaction is what is important. It also helps you develop interfaces, and it can scream loudly when you have an object doing way too much. * Blaming brittleness of tests upon interaction-based testing is a red herring. Both interaction-based tests and state-based tests become brittle if they make assertions upon implementation details and overly constrain the interfaces between modules. - Nat Pryce * http://nat.truemesh.com/archives/000342.html - a wonderful read on interaction-based vs state-based testing -- Zach Dennis http://www.continuousthinking.com
Re: [rspec-users] rescue
On Tue, Mar 18, 2008 at 11:13 PM, linojon [EMAIL PROTECTED] wrote: Hi, whats the correct way to spec a rescue? This will raise it but doesnt test my code's response # controller def edit @foo = Foo.find(params[:id]) rescue flash[:notice] = Unknown foo #{params[:id]} redirect_to foos_path end # spec it should flash error if not found do Foo.should_receive(:find).and_raise get :edit, :id = '1' flash[:notice].should == Unknown foo 1 end # run Exception in... I have done a very similar thing: Foo.should_receive(:find).and_raise ActiveRecord::ActiveRecordError and then change your rescue to handle ActiveRecord::ActiveRecordError. If you get to the point where you have a generic way you'd like to handle the exceptions in a controller, or across controllers look into using the controller class method rescue_from. I'm not 100% this is what you were asking, hopefully you were just looking for confirmation, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Pending Scenarios
On Fri, Mar 21, 2008 at 9:38 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Fri, Mar 21, 2008 at 5:24 AM, Tim Haines [EMAIL PROTECTED] wrote: Hi there, newb q: The pending support for spec's and steps is nice. I'm just wondering why a scenario itself can't be pending? Because nobody asked for it :) Wanna file a feature request at lighthouse? http://rspec.lighthouseapp.com I.e. it seems to me like it would be nice to write up scenario titles for scenarios as you think of them, and for low-priority fringe scenarios leave the steps unwritten until it comes time to implement the scenario? Is there a way to add comments to the plain text file in plain text stories? Anything between the line that begins with Story: and the first line that begins with Scenario: will be part of the story narrative. Sort of like a comment, but it gets printed out. So I sometimes add additional commentary there to provide context around the As a .., I want ..., So that ... statement. Anything after the first Scenario: that does not begin with any of the keywords (Scenario:, Given, When, Then, And) is simply ignored, so you can put comments between steps and they will not be processed. I would not go crazy with this at this point because there has been a request to support multiline text in plain text stories, at which point your comments might accidentally get interpreted. Perhaps now is the time to devise a formal comment indicator. I think the obvious choice would be the same one we use in Ruby: # Given this step # this is a comment When this other step etc Thoughts? Rather than anything that does not start with Scenario|Given|When|Then|And being treated as a comment it seems more future-proof if we just say that any line whose first non-whitespace character is a # ... is a comment. Although I'm not crazy about inserting comments into plain text story files, I think that there are times when it would indeed be useful and I'd want to give the developer or customer the ability to make the call when they might need it. Zach -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] sharing story steps
On Fri, Mar 21, 2008 at 10:35 AM, Aslak Hellesøy [EMAIL PROTECTED] wrote: On 21. mars. 2008, at 07.32, Joe Van Dyk [EMAIL PROTECTED] wrote: On Thu, Mar 20, 2008 at 2:05 AM, aslak hellesoy [EMAIL PROTECTED] wrote: On Thu, Mar 20, 2008 at 5:44 AM, Joe Van Dyk [EMAIL PROTECTED] wrote: Hi, How can I have a common set of steps that all my stories share? i.e. My stories often start out looking like this: Given a user Joe Given a user Jordan then: put this in steps/users.rb: rails_proj/stories/steps or just rails_proj/steps? Whichever you like. I prefer the first one. I prefer the first one as well, -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] How do you mock an object that you don't have access to?
http://atomicobjectrb.rubyforge.org/injection/ Zach On Fri, Mar 28, 2008 at 2:17 PM, aslak hellesoy [EMAIL PROTECTED] wrote: On Fri, Mar 28, 2008 at 8:12 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Fri, Mar 28, 2008 at 11:32 AM, Luis Lavena [EMAIL PROTECTED] wrote: On Fri, Mar 28, 2008 at 3:25 PM, David Beckwith [EMAIL PROTECTED] wrote: Hi, How can I mock the go method of class B so that it returns the string fudge in this situation? class A private def start @b = B.new end end class B def go puts This is fun. end end What about: mock_b = mock(B) mock_b.stub!(:go).and_return(true) B.stub!(:new).and_return(mock_b) Something like that? Stubbing the #new method on the class is one way to do it, as Luis mentioned. Another approach is to pass the object in through the constructor. Doing so will help you achieve looser coupling between the classes. AKA Dependency Injection (http://martinfowler.com/articles/injection.html) Aslak Pat ___ 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 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Welcome Pat Maddox
Congrats pat! Zach On Fri, Apr 4, 2008 at 2:34 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Fri, Apr 4, 2008 at 10:26 AM, aslak hellesoy [EMAIL PROTECTED] wrote: On 4/4/08, Luis Lavena [EMAIL PROTECTED] wrote: On Fri, Apr 4, 2008 at 11:35 AM, Patrick Meunier [EMAIL PROTECTED] wrote: This is a great news! Congratulations Pat. +1 on that, The bdd-force within Pat is strong, and is good to see he is joining the good side of the force :-) Pat is a much needed and welcome member to the core team. I expect we'll see a lot of great contribs from him in the time to come. Welcome onboard, Pat! Thank you for the kind words, everyone. Pat ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] newbq: Organizing your stories
On Thu, Apr 10, 2008 at 8:46 PM, Tim Haines [EMAIL PROTECTED] wrote: Hi, I'm a little unhappy with how my stories are organised, and am wondering if anyone has found any particular method nicest. I'm working within an admin namespace, and currently have a plain text story file for each controller in the admin folder. I also have a steps subfolder, with one step file per controller. I'm thinking it would be nicer to add a little more granularity here, and to break the plain text story files down further into actions on each controller so there's fewer stories per story file. This could be done either in the one folder, or by adding a bunch of subfolders. I figure this is pretty common though, and that there will be one or two approaches that have evolved to work pretty well? I organize my stories based on related behavior usually as defined by the customer. For example: - stories/ - projects/ - a_user_creating_a_project_story - a_project_manager_adding_users_to_a_project_story - admin/ - an_admin_removing_users_story I use stories as system level integration tests, so they usually cover a broader scope than a controller/action. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Is testing output within content_for possible?
You can also render a testing layout which yields the content. IE: render foo, :layout = testing In layouts/testing.html.erb: %= yield :sidebar % Zach On Sun, Apr 20, 2008 at 1:00 PM, Chris Olsen [EMAIL PROTECTED] wrote: Bryan Ray wrote: This might be of some use: http://rubyforge.org/pipermail/rspec-users/2007-June/001954.html That should do it! Thanks Bryan -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] how do i remove duplication from my steps in story runner?
You should be able to make your own module of helpers and include it into Spec::Story::World module Spec::Story::World def your_helper_method # i should have access to everything I need end end Zach On Tue, Apr 22, 2008 at 10:30 PM, Perryn Fowler [EMAIL PROTECTED] wrote: Another attack. Then(two nested divs and an? $type will be displayed) do | type | response.should have_tag(div) do with_tag(div) end response.should have_tag(type == 'image' ? 'img' : type) end Thanks for the cool idea Rick, but unfortunately that only helps with my contrived little example - for my real app I really do need to be able to factor out some helper methods... ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Spec the Application Controller application.rb
Do this... after do eval IO.read(RAILS_ROOT + /config/routes.rb) end Zach On Thu, Apr 24, 2008 at 2:20 AM, Andy Croll [EMAIL PROTECTED] wrote: This bit however, replaces your other routes, so you cannot use them in your tests before(:each) do ActionController::Routing::Routes.draw do |map| map.resources :foo end end Is there a sensible way to append to the routes.rb that I'm missing? Andy -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] ANN: RSpactor 0.9.10 (aka. beta)
Just put a directory path to a project in the text field, and click Run. It will do the rest as far as I can tell, Zach On Mon, Apr 28, 2008 at 8:46 PM, Corey Haines [EMAIL PROTECTED] wrote: Well, I got it running (seemingly), but I'm not 100% sure how to use it. -Corey On Mon, Apr 28, 2008 at 8:08 PM, Corey Haines [EMAIL PROTECTED] wrote: I'm using rspactor now over autotest. I'll give the beta a shot. -Corey On Mon, Apr 28, 2008 at 3:51 PM, rubyphunk [EMAIL PROTECTED] wrote: Hey all. I've just release a first preview/beta of the upcoming RSpactor.app; a spec runner for Mac OS X Leopard. This is just some kind of test version and I'm looking for people who love to sit on the edge :) I need some help to find bugs and polish the interface/interaction. RSpactor is basically a tool like 'autotest' but runs on Cocoa and focuses on RSpec. Instead of constantly polling your files it uses FSEvents to listen to changes in your project directory. Growl support is build in.. So if you are interested have a look at: http://rubyphunk.com/2008/4/28/ann-rspactor-0-9-10-some-people-call-it-beta thanks. - Andreas ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- http://www.coreyhaines.com The Internet's Premiere source of information about Corey Haines -- http://www.coreyhaines.com The Internet's Premiere source of information about Corey Haines ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Can you use RSpec to test initializers?
On Tue, May 6, 2008 at 4:03 PM, Erik Pukinskis [EMAIL PROTECTED] wrote: Hi there! I'm trying to spec out some code that will set the smtp_settings in a custom ActiveMailer object. Basically I want to check that if my configuration object has the right smtp_server, that the ActiveMailer object gets set up correctly. So, my spec looks like this: it uses smtp server if config says so do GitoriousConfig.should_receive(:[]).with('smtp_settings').and_return({ :address = smtp.postoffice.net, }) Mailer.smtp_settings[:address].should == smtp.postoffice.net end The trouble is, the code that sets the mailer settings is in an initializer (config/initializers/mailer.rb) and it gets run long before my spec gets run, and so it never encounters my mock. Is there any way I can get the initializer code to run inside my spec? I know I could create a separate initialize method on my Mailer object that has the initialization stuff, and call that method from both my test and my initializer, but that seems less ideal than just calling the initializer from the spec. Any advice? I can't find any information at all online about using Rspec with initializers. Erik, I would not test configuration settings this way. Setting up mock expectations helps when you are talking to another object whose implementation you don't have yet, or don't want the test to rely. Since you are testing configuration settings I would vote that you test against the actual configuration settings. A quick sidebar, I don't like setting up SMTP settings in an initializer. I prefer to do it in the correct environment/*.rb file. This is because you often don't want your development or test environments sending out emails (at least not via the same route as production). If you do move the configuration setup from your initializer to an environment file then what you want to test is going to be more difficult since it may be different for each environment. And when you run a spec it's going to be executed in the test environment, which is probably not the SMTP settings you wanted to ensure got setup. You are probably wanting to make sure the production environment runs with specific settings. In the past I've foregone automated testing of my configuration settings. I usually setup my production.rb configuration on the production server, and then every time I deploy I'm symlink that file into RAILS_ROOT/config/environment/. This greatly reduces the risk that the production settings is going to be modified or altered unintentionally. Keeping snapshot backups of your production setup (or even just the configuration files) also helps reduce risk even more. You could put your production files in their own svn or git repository so you can easily revert back when you do make changes to those files. If you really want to test the production settings you could right a test which loaded up the rails application in the production environment, printed out the SMTP settings in YAML, and then your test could read that in using YAML.load and you could ensure the settings are what you expect. IE: settings = YAML.load( `RAILS_ENV=production ruby -r config/environment.rb -e y ActionMailer::Base.smtp_settings` ) settings[:domain].should == smtp.example.com -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Rspec Stories / Selenium Nightmare
in a puddle of mud, dreading that Selenium moment. -- Joseph Wilk http://www.joesniff.co.uk -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Rspec Stories / Selenium Nightmare
David, Can you provide any more info? Is it just being talked about or are people actively working on it now? I would be interested in assisting. I've done a lot with Selenium and the ruby driver and would be interested in providing beautiful high level helpers that allow people switch from non-Selenium based specs to Selenium-based specs with more ease. I know this can be a barrier for people. Zach On Thu, May 8, 2008 at 11:15 AM, David Chelimsky [EMAIL PROTECTED] wrote: Just an FYI - spec-ui, an rspec extension that supports integration with selenium and watir, has been under some discussion lately and should see some new life soon. On May 8, 2008, at 10:10 AM, Zach Dennis wrote: I've had really iffy luck with Selenium plugins in the past (selenium-on-rails, seleniumfu_rc, selenium_rc, etc.) so I've started to write a RailsSeleniumStory. I also had to remove the ActiveRecordSafetyListener in my efforts. The RailsSeleniumStory is a part of the mhs_testing plugin [0] and it provides higher level helpers. For example I love how form-test-helper is used to select and submit forms: # option 1 form = select_form 'expense_form' form.expense.amount = 12.99 form.submit # option 2 submit_form 'expense_form' do |form| form.expense.amount = 12.99 form.expense.category_id = 2 form.expense.comments = map for trip end You can use this same syntax within RailsSeleniumStories. Right now you can also use have_tag and with_tag matchers with Selenium. It supports basic matching (I wouldn't get to crazy with nesting or lots of assert-select/have-tag options), but it will be supporting more options shortly. So your login example could just look like: Given('log in as a admin user') open /admin/login submit_form login_form do |form| form.login = 'developer' form.password = 'test' end end Which IMO I really like because if you need variations of that you can pull out a helper method like: def submit_login_form(user, password='test') submit_form login_form do |form| form.login = user.login form.password = passsword end end And you could push your open into a helper as well: def go_to_login_page open /admin/login end And now your Given could look like: Given('log in as a admin user') go_to_login_page submit_login_form @user, 'test' end Now granted submit_form and select_form both take a form's id, so each of your forms need to have one. If you are interested and have the time please check it out. Granted it's in its infancy and there's not a whole lot of docs right now (there is a README.Selenium for instructions on how-to setup in your project), but you can find me on GTalk or in irc.freenode.net (zdennis) and of course right here on the rspec ML. I am have 33 scenarios using the RailsSeleniumStory, ttyl, Zach 0 - http://github.com/mvanholstyn/mhs_testing/tree/master On Thu, May 8, 2008 at 8:22 AM, Joseph Wilk [EMAIL PROTECTED] wrote: I have been using Rspec stories with Webrat feeling very productive and happy. Then I needed to do something with Selenium (Webrat could have done what I needed but it does not yet have the functionality). Selenium-core as part of a rails plugin looked nice but did not seem to fit with rspec stories. So I went the Selenium-rc route. Since Selenium uses a separate instance of rails (http://www.nabble.com/stories-with-selenium-and-the-db-td16190686.html) I had to turn off the ActiveRecordSafetyListener used in rspec to make sure the db writes committed. Which in turn left me having to manually cleanup my selenium stories :( So that required writing a new, rather gritty scenario listener which dealt with the cleaning operation. It has to do lots of horrible things like remove all listeners for a selenium story and then re-add them all for the others stories. *Code Extract* def story_ended(title, narrative) case title when 'Edit a page' #We have finished the selenium story $selenium_driver.stop #Do we need to re-add some listeners if [EMAIL PROTECTED] Spec::Story::Runner.scenario_runner.add_listener(ActiveRecordSafetyListener.instance) @listener_reloaded=true end end end I had to duplicate a lot of the story steps since now any previous post/gets did not work since they post to the test instance and not the selenium rails instance. I also needed to invoke against the selenium driver so even when the steps would work I had to duplicate them with $selenium_driver.do_something() This nice Given: Given('log in as a admin user') post '/admin/sessions/create', :login = @user.login, :password = @user.password end Being duplicated with this Given('log in as a admin user') $selenium_driver.open '/admin/login' $selenium_driver.type 'login', 'developer
Re: [rspec-users] Are you writing imperative or declarative scenarios in your stories?
and discomfort upfront associated with writing less re-usable pieces of code. When you go the declarative route all of your code is pushed together without the granular step boundaries, forcing you to face up and extract out methods which reveal the intent of the step. -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Reuse steps like a method call
On Wed, May 14, 2008 at 2:24 PM, David Chelimsky [EMAIL PROTECTED] wrote: On May 14, 2008, at 12:45 PM, Bryan Helmkamp wrote: If I have a step matcher defined as so: Given a user named $username do |username| end Is there a way to call it from another step? For example: Given a user named $username with a blog post |username| given_a_user_named(username) # calls existing step code # create a blog post end I'm pretty sure you can do this: Given a user named $username with a blog post |username| Given a user named #{username} # create a blog post end Is this by intention or just a side effect of the current implementation? -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Specifying certain tables NOT to be cleared each example?
I know the problem has been solved but you can supply global fixtures in your spec_helper.rb file. This avoids having to repeat them for every describe block. Spec::Runner.configure do |config| config.global_fixtures = :table_a, :table_b end Zach On Wed, May 21, 2008 at 10:49 PM, Andrew Selder [EMAIL PROTECTED] wrote: Is it possible to specify that certain tables not be cleared on each example. I've inherited a project where a good amount of enumerated data is stored in the database (US States, statuses, about 15-20 tables worth. Over all, it's a reasonable decision that leads to solid production code (acts_as_enumerated is good). This data is read-only and relatively static; any changes to these tables are done via migrations. The problem comes when I'm writing my tests. Obviously all these tables get wiped with each example. Yes, I could specify these as fixtures, but I really don't want to have to specify 15-20 fixtures on every example. Yes, I could mock/stub all the values, except that I use many of these values at class definition time, which means that errors are thrown before I can even mock/stub. For instance, I have a statement like this. named_scope :open, :conditions = [lead_status_id IN (?), %w{New Incubating Client UAG}.collect{|x| LeadStatus[x].id}] Which loads the named_scope using the string version of the enumeration for clarity's sake. It works great, except for testing. Does anybody see anyway around this other than creating a fixture file for each of these tables and loading all the fixtures on each describe block. Not only does this make for ugly code, but I'm sure it takes a good chunk of time to setup and teardown each of the tables each example. It would be wonderful if there was some option to specify tables that behave like this, that should be loaded at the beginning of the test run, and (optionally) trashed at the end of the run. Or even better, specify that the test script shouldn't touch (build or teardown) these tables at all, and let their migrated state remain. Thanks, Andrew ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] xhr :post giving wrong number of arguments on rails 2.1?
Use xml_http_request in your stories rather than xhr. I believe the xhr method is aliased to the wrong method... I haven't looked to see if this is a Rails issue or a rspec-rails issue, Zach On Thu, Jun 5, 2008 at 1:33 AM, Mikel Lindsaar [EMAIL PROTECTED] wrote: Getting a strange error. In a story I have the following step: When I submit a search name do xhr :post, '/searches', {:search = {:given_name = bob, :family_name = smith}} end I am getting: ArgumentError: wrong number of arguments (4 for 3) stories/searching_story_spec.rb:45 in I submit a search name But I only have 3 arguments in the above list, a symbol, a string and a hash. No exception comes up in the test.log I am on Rspec trunk from a couple of days ago and Rails 2.1. Any ideas? Mikel ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Stopping example execution?
On Sun, Jun 29, 2008 at 12:20 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Jun 29, 2008, at 11:18 AM, Britt Mileshosky wrote: However, do you see where something like a return statement or end example statement could be beneficial? If you are working from the top down with your controller action execution, then you only need to test your expectation and then bail out of your action. No need to further test or meet requirements on anything else in that action because your single test has been met. - in my example for making sure I find a user, I'd like to end execution once I DID find the user, i shouldn't have to satisfy requirements about finding an account and a person... I'll write those expectations later in another nested describe group, as you can see here, in a top down process PeopleController with a logged in user - should find user PeopleController with a logged in user who has an account - should find account PeopleController with a logged in user who doesnt have an account - shouldn't find account - should redirect ... PeopleController with a logged in user who has an account the person belongs to - should find person - should assign person for the view PeopleController with a logged in user who has an account the requested person does not belong to - should not find person - should ... My instinct about this is that it would encourage long methods because it would make it less painful to test them, so I would be adverse to anything that let's you short circuit the method. Anybody else have opinions on that? I'm just catching up on email now after being sick for the past six days, but health aside my opinion is that I agree with David's opinion. Rather than focusing on how-to write easier tests that complain less, start focusing on how-to write the right tests that complain when necessary. One of the benefits associated with feeling the pain of a test is that it may be a sign to re-assess and refactor your code. This usually happens early enough that it only takes a few minutes. Short circuiting essentially gives you the ability to not feel the pain. Its like CIPA [0], but for code. I would fear that the code would get so bad that by the time the test cried with pain your code was already beyond easy repair and instead required invasive surgery. Tests are part of the nervous system of your application. When they hurt, they're telling you something isn't right and that it should be addressed, 0 - http://en.wikipedia.org/wiki/Congenital_insensitivity_to_pain_with_anhidrosis -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Stopping Example Execution?
require user PeopleController with a logged in user - should find user PeopleController with a logged in user who has an account - should find account PeopleController with a logged in user who doesnt have an account - shouldn't find account - should redirect ... PeopleController with a logged in user who has an account the person belongs to - should find person - should assign person for the view PeopleController with a logged in user who has an account the requested person does not belong to - should not find person - should ... PeopleController # stub the minimum needed to get to the first example group up and running PeopleController with before filters - should require user PeopleController with a logged in user # stub logged in requirement - should find user PeopleController with a logged in user who has an account # stub account requirement - should find account PeopleController with a logged in user who doesnt have an account # stub no account requirement - shouldn't find account - should redirect ... PeopleController with a logged in user who has an account the person belongs to # stub account owns person - should find person - should assign person for the view PeopleController with a logged in user who has an account the requested person does not belong to # stub account doesn't own person - should not find person - should ... I prefer the second group, but unfortunately I am not able to write my specs in this organized fashion. Just sayin. I appreciate the communication value you're looking for, and you can get it by stubbing everything you need to keep execution going before(:each) example and then set message expectations (should_receive) inside each example that help tell the story of that example. PeopleController # stub everything way up here at the top where these # definitions are out of context (by means of position) with following examples # # stub controller requirments # stub logged in requirement # stub account requirement # stub no account requirement # stub account owns person # stub account doesn't own person PeopleController with before filters - should require user PeopleController with a logged in user # expect logged in query - should find user PeopleController with a logged in user who has an account # expect logged in query # expect account query - should find account etc HTH, David Yep, thats exactly what I've been practicing, and while its not exactly what I want, it does work nicely. Thank you David I'm gonna make another REALLY strong case for allowing the ability to stop example execution and test code incrementally. I currently have over 1700 examples for the current application I'm working on, and one little line of code that I added in my App controller ( before_filter :set_location ) brought on almost 1100 errors across my tests. Now I know people will say that the requirements weren't understood at the beginning of the application and that it could have been avoided with better planning... but this isn't the case. I now have to go into each of my controller tests and add the stub into every before declaration to clear up my errors. Not fun, and could've been avoided completely. Britt _ Enter the Zune-A-Day Giveaway for your chance to win — day after day after day http://www.windowslive-hotmail.com/ZuneADay/?locale=en-USocid=TXT_TAGLM_Mobile_Zune_V1 ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] auto-generated descriptions
On Fri, Jul 4, 2008 at 10:18 PM, Steve Eley [EMAIL PROTECTED] wrote: On Fri, Jul 4, 2008 at 4:45 PM, David Chelimsky [EMAIL PROTECTED] wrote: So - how bad do you think this would suck to remove that feature? Are you using it yourself? I'm not, but would it be impractical to extract it out into some sort of module or helper and tell people to include it in their config.* block if they want to use it? +1 -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Not sure why this controller spec isn't working
On Mon, Jul 7, 2008 at 5:55 PM, Britt Mileshosky [EMAIL PROTECTED] wrote: Date: Mon, 7 Jul 2008 17:27:36 -0400 From: [EMAIL PROTECTED] To: rspec-users@rubyforge.org Subject: [rspec-users] Not sure why this controller spec isn't working Hey folks, I've been mocking and stubbing pretty nicely after the various bits of advice I received earlier about doing so. I've come to bits of code that work in one place and not in another, though. I'm hoping it's not something simple I've missed. The code below fails even though code that is practically the same elsewhere (except different models in use) passes. What gives? I have: in notes_controller_spec.rb: before(:each) do @mock_note = mock_model(Note, :body = The hot dog shipment will be in later tonight., :organization = @mock_org) @mock_org = mock_model(Organization, :name = Slappy's Hot Dog Palace, :notes = [EMAIL PROTECTED]) @notes = [EMAIL PROTECTED] end it should render 'notes/new' when the Note is setup with invalid data, i.e. without a body on POST create do Note.stub!(:new).and_return(@mock_note) @notes.stub!(: post :create, :organization_id = @ mock_org.id, :new_note = { :body = @mock_note.body } response.should render_template(notes/new) end To add to what Britt already said, look at your example and then your before block again very carefully. Notice that you setup @notes in your before, and you use it to stub : in your example, but you never return @notes from anything. Instead you setup @mock_org to return an array with @mock_note. Although the contents of this and @notes are the same, you have created two different arrays. You are probably wanting to be dealing with the same @notes object in each of these cases. Zach -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] controller vars for examples
Can you provide more information about what you are spec'ing? Zach On Wed, Jul 9, 2008 at 3:08 PM, Tim Stevens [EMAIL PROTECTED] wrote: Hi, How do I override the value of a controller variable in a controller spec. For ex, if I have an action with an array, I want to have examples with different variables in the array def testing my_array = [1,2,4] end How do I test this with diff vals for my array? Thanks -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] rspec render :update
On Fri, Jul 11, 2008 at 1:04 PM, Reggie Mr. [EMAIL PROTECTED] wrote: Hi all, I'm having trouble with rspec 1.1.4 and rjs In the controller: render :update do |page| page 'added text' end render :update do |page| page.replace_html :divid :partial = 'apartial' end spec: response.should have_rjs #this should be successful for any rjs request; but fails response.should have_rjs(:replace_html) #no luck I have tried mocking the page object, but that also fails. e.g @page = mock('page) @page.should_receive(:replace_html) What's the best practice to validate rjs responses? I don't like validating generated JavaScript code from framework methods (or well tested third party libraries) against helper methods which just use regular expression matching underneath the covers (like ARTS or the built-in Rails helpers). I like to let the framework and the third party libraries test that their generated JavaScript is correct and I like to make sure my code is just doing the right thing using mocks. The below is a spec that will ensure a render :update call inside a controller action works... describe SomeController, '#foo' do it renders the items entry form do page = mock(page) controller.expect_render(:update).and_yield(page) page.should_receive(:replace_html).with(:some_id, partial = items/form) get :show, :id = 1, :expense_reimbursement_id = 2 end end And here's the controller method: def show render :update do |page| page.replace_html :some_id, :partial = Items/form end end I like to keep my RJS separate from my controller as much as possible by pushing the code into external RJS files. This helps keep the controller simple and easily understandable. I know sometimes the controller action and the RJS are both so simple that it seems like overkill to separate them. This just becomes a judgment call by the developer. If the controller action or the inline RJS grows it's pretty simple to extract an RJS file after the fact. When an RJS file becomes messy or difficult to understand you can refactor that into using Renderer objects. For more information see Extract Renderer from RJS in the Rails Refactoring Catalog: http://assets.en.oreilly.com/1/event/6/Refactoring%20Your%20Rails%20Application%20Paper.pdf -- Zach Dennis http://www.continuousthinking.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Specifying a few valid values
Perhaps... When I login with invalid credentials Then I see that I have not been logged in And in your implementation of the Then you could make sure they are at the login form still. Zach On Thu, Jul 17, 2008 at 10:19 AM, Jonathan Leighton [EMAIL PROTECTED] wrote: On Thu, 2008-07-17 at 08:50 -0500, David Chelimsky wrote: Are you familiar with Webrat? Yep, we are using it. However, I want to test what happens when invalid data is entered - that's the reason to specify that the form gets shown. What would you consider a better approach to verify the user sees the form again, instead of moving on through the application? I guess I could test that they *don't* get redirected? Cheers, Jon -- Jonathan Leighton http://jonathanleighton.com/ ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] cheat install_rspec_rails -x
Should this be valuable for anyone else, I've forked cheat (hoping for it to get pulled) to allow cheat to be used for execution. For example: cheat install_rspec_rails --execute OR cheat install_rspec_rails --x http://www.continuousthinking.com/2008/8/1/cheat-execute -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Spec'ing correct use of Timeout
On Sat, Aug 2, 2008 at 8:10 AM, Mikel Lindsaar [EMAIL PROTECTED] wrote: Heya all, I have an interesting case that I would like to bounce off the list. I have a separate thread going in ruby-talk about Timeout.timeout still running after the timeout specified. The spec on this has been the classic 'I didn't write it, so I won't spec it' and so using mocks and stubs. But in this case I am getting a failure (it seems) in the Timeout library or in the OCI8 library maybe... I actually don't know. But regardless, how would one go about specing a timeout block?. _without_ having to wait 2000 seconds? :) The first thing that comes to mind is to pass in your timeout threshold as a defaulted argument, ie: def do_something(timeout=2000), and then in the example pass in a much lower threshold. This assumes that you want the block you pass to timeout to actually be executed. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Can't access actions of a singular nested resource
Bastien, What version of Rails and rspec are you using? Using a singular resource like you presented works just fine for me, Zach On Thu, Jul 31, 2008 at 10:06 AM, Bastien [EMAIL PROTECTED] wrote: I can't figure out what I do wrong there, I have a nested controller which is defined as a singular resource, the routing works properly, but inside my specs the request never goes through the show action. I keep on getting this error : Spec::Mocks::MockExpectationError in 'Surveys::ReportController should return the survey corresponding to the report' Mock 'Class' expected :find with (any args) once, but received it 0 times In my specs : require File.expand_path(File.dirname(__FILE__) + '/../../ spec_helper') describe Surveys::ReportController do it should return the survey corresponding to the report do Survey.should_receive(:find) get :show, :survey_id=34 end end In route.rb : map.resources :surveys do |survey| survey.resource :report, :controller ='surveys/report' end In controller/surveys/report_controller.rb : class Surveys::ReportController ApplicationController def show @survey = Survey.find(params[:survey_id]) respond_to do |format| format.html format.xml end end end ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Someone please name this matcher for me
On Wed, Aug 6, 2008 at 1:50 PM, Pat Maddox [EMAIL PROTECTED] wrote: I've had a matcher in my head for a couple months, that I frequently want but never get around to writing because I can't think of the name for it. Here's how it would look [1, 2, 3, 4, 1].should ... [1, 3, 1, 4, 2] I have a couple ideas for names, but I'll hold off on them so I don't influence anyone's opinion. btw, I realize that .sort works in this case. But that's slightly less clear than I'd like, and it doesn't work for non-Comparable objects (like activerecords). [1, 2, 3, 4, 1].should consist_of([1, 3, 1, 4, 2]) Since consist means to be composed or made up of, which matches the usage. To me it reads like, this thing should be made up of these other things. WDYT? -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Can't test for page content after a redirect
On Thu, Aug 7, 2008 at 2:44 PM, Christian Lescuyer [EMAIL PROTECTED] wrote: I'm trying to verify that data entered in a form has been saved in the database. Scenario: User enters a bookmark URL Given a bookmark 'http://www.gotapi.com/rubyrails' When the user adds the bookmark Then should redirect to '/' And the page should contain 'http://www.gotapi.com/rubyrails' The first test (should redirect) passes. The second fails. I understand why: the page that is analysed is a dummy page You are being redirected. Is it possible to check data in the second page? What about something like: Scenario: User enters a bookmark URL Given I log in as a user When I add 'http://www.gotapi.com/rubyrails' as a bookmark Then I should see that has the 'http://www.gotapi.com/rubyrails' has been added to my bookmarks I'd imagine the steps to look something like: Given I log in as a user do # do whatever to login end When I add $url as a bookmark do |url| # fill out the new bookmmark form with the given url # after submitting form handle redirects follow_all_redirects end Then I should see that has the $url has been added to my bookmarks do |url| # response should have url somewhere on page end follow_all_redirects looks like: def follow_all_redirects if response.content_type == text/html follow_redirect! while response.redirect? elsif response.content_type == text/javascript if md=response.body.match(/window.location.href = ([^]+)/) get md.captures.first end end true end -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] embedding variable in a regex
On Fri, Aug 8, 2008 at 10:18 AM, aidy lewis [EMAIL PROTECTED] wrote: Given /a (PROGRAM|PROGRAMMES) title of '$title'/ do |title| end Could anyone give me the correct syntax for embedding this variable in a regex? You'll need to create a sub-expression capturing the title. Sub-expressions are denoted in a regular expression with parenthesizes. You already have one in your with (PROGRAM|PROGRAMMES). If your regex matched a given step the title would be either PROGRAM or PROGRAMMES depending on what the step description looked like. You probably want to use a non-matching sub-expression for PROGRAM|PROGRAMMES so it doesn't get captured (and thus passed in as a block parameter). Try this: Given /a (?:PROGRAM|PROGRAMMES) title of '([^']+)'/ do |title| end Which should match the step with the name Given a PROGRAM title of 'foo bar baz thingy majoo' -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] WDYT, simple, anonymous story listeners?
Sometimes I don't have a full need to make a class to do something, yet I want something readable and concise. This is influenced from the joys of JavaScript. Today I made this happen. Love it, like it, hate it, WDYT? Spec::Story::Runner.register_listener FunctionalStruct.new( :run_started = lambda { |*args| Generate.user(:login = normal user) }, :run_ended = lambda { |*args| User.destroy_all }, :method_missing = lambda { |*a| } ) -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] WDYT, simple, anonymous story listeners?
On Wed, Aug 13, 2008 at 12:24 AM, Tero Tilus [EMAIL PROTECTED] wrote: 2008-08-12 20:25, Zach Dennis: Sometimes I don't have a full need to make a class to do something, How's that _essentially_ different from making a class or extending an existing class? I am not knowledgeable enough to just see it, and becaus I can't understand the motivation, I'm bound to hate it. ;) The biggest difference is that you can pass the whole thing as an argument into the method you're calling (reduce noise, increase clarity). If you used something like OpenStruct you couldn't do it, because in Ruby you can't force invocation of a Proc object (you have to call call on it). For example, this wouldn't work using an OpenStruct: Spec::Story::Runner.register_listener OpenStruct.new( :run_started = lambda { |*args| Generate.user(:login = normal user) }, :run_ended = lambda { |*args| User.destroy_all }, :method_missing = lambda { |*a| } ) In order for this to work we'd have to create a class for our listener, like so: class MyStoryListener def run_started(*args) Generate.user(:login = normal user) end def run_ended(*args) User.destroy_all end def method_missing(*args) end end # and register it separately Spec::Story::Runner.register_listener MyStoryListener.new There is nothing wrong with this, but there are times when it feels dirty and unnecessary to create yet another class with some methods, just so the thing can be instantiated one time and passed in as an argument. That's why I decided to throw together a little FunctionalStruct, so if Proc objects got passed in they would be invokable. Here's a more specific example of the different between OpenStruct and FunctionalStruct: # openstruct example o = OpenStruct.new :foo = lambda { foo } o.foo # = Proc:#asfsblahblahblah o.foo.call # = foo # functionalstruct example f = FunctionalStruct.new :foo = lambda { foo } f.foo # = foo This is influenced from the joys of JavaScript. It even looks like JavaScript. :D One thing I miss from JavaScript is that functions are truly first class citizens. The beauty of Ruby is that I can mimic that by writing something like FunctionalStruct. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] WDYT, simple, anonymous story listeners?
On Wed, Aug 13, 2008 at 5:26 AM, Joseph Wilk [EMAIL PROTECTED] wrote: It looks like a nice shortcut for those times when you are registering simple one-off listeners. While it does provide a nice shortcut I can see reasons why that shortcut might be bad(in some cases). Separating registering and implementation can be a good thing. *Split the logic. *Organise files/classes nicely *Enable inheritance from the listeners If it was anything that I had to maintain or touch regularly I would be happier with a class. Can/Could you support mixins inside FunctionalStruct? That would help overcome some of those points. Yeah you definitely could, perhaps something like: FunctionalStruct.new( SomeModule, :foo = ..., :bar = ..., ) I can think of a couple of places that I would be happy using FunctionalStruct. Is the source for 'FunctionalStruct' written/available? http://github.com/zdennis/functional_struct/tree/master -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] WDYT, simple, anonymous story listeners?
On Wed, Aug 13, 2008 at 8:29 AM, aslak hellesoy [EMAIL PROTECTED] wrote: On Wed, Aug 13, 2008 at 2:25 AM, Zach Dennis [EMAIL PROTECTED] wrote: Sometimes I don't have a full need to make a class to do something, yet I want something readable and concise. This is influenced from the joys of JavaScript. Today I made this happen. Love it, like it, hate it, WDYT? As mentioned earlier on the RSpec development list, we're considering replacing the Story runner with a new implementation: http://github.com/aslakhellesoy/cucumber http://gojko.net/2008/08/06/cucumber-next-generation-ruby-bdd-tool/ http://www.nabble.com/-ANN--Cucumber-td18876816.html I'd rather see a similar construct for Cucumber, which already is (IMHO) much better than the Story Runner. Before(:all) do end After(:all) do end (per-scenarion Before/After is already implemented). When you say rather see a similar construct -- are you referring to having the Before(:all) and After(:all) capability that you posted, or something similar to what I posted with using a FuncionalStruct as an argument to register a listener on the existing StoryRunner (a clear/concise way to hook-in with those one off listeners) ? -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] How do you stub out callbacks?
On Thu, Aug 14, 2008 at 9:53 AM, Rob Lacey [EMAIL PROTECTED] wrote: Hi there, I'm trying to write a spec for and existing model. It has an after_create callback which I'd like to stub out. Any quick solution to this? My first question is why do you want to stub it out? My second question is what spec are you wanting to stub it out in? -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Autotest setup to run Story Runner?
On Thu, Aug 14, 2008 at 2:24 PM, Ben Men [EMAIL PROTECTED] wrote: Kamal Fariz wrote: Can Story Runner run a specific scenario in a story? Like how Spec Runner can just execute a particular example. I realize this question is a little old, but I have exactly the same need. The only solution I have is trying to build much smaller stories so that they run a bit quicker, though this can get messy. I would absolutely love to be able to run changed scenarios upon saving, like how autotest works for the specs. Has anyone achieved this yet? That would be very difficult to do and to do well (with autotest or RSpactor) since stories cover a complete vertical slice of the application, and it'd be almost impossible to know what source file (or method) affect will what stories. Continuous integration works very well for this. Let another machine pull an update (or you can push an update) and it runs the specs and stories. When I was at Atomic Object I wrote a small growl notifier which received updates from our continuous integration server telling it when something failed. It was beautiful. Of course this was really easy to write since the continuous integration server was written in a way that allowed you to attach listeners (and remote monitors) to it over the network. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Stubbing calls to the command line
On Thu, Aug 14, 2008 at 3:42 AM, Andy Croll [EMAIL PROTECTED] wrote: I'm using a call to wget to download a large datafile (multiple megabytes) having assumed this will be quicker than using open-uri. How can I spec the behaviour? Ideally I'd also like to not be hitting the internet every time I test! in my_object_spec.rb describe .get_data do before(:each) do @my_obj = MyObject.create(@valid_attributes) end it should download the file do # behaviour goes here end end in my_object.rb: def get_data `wget --output-document=#{self.filename} #{self.file_uri}` end I'll be massively grateful for any help anyone can give me. I might end up with a separate object which managed making the wget system call, and then I've have an integration-style test which ensured it correctly downloaded a given passed in URL. class MyObject def get_data WGet.download(http://some/path;) end end class WGet def download(url) `wget #{url}` end end And I probably wouldn't have a spec for WGet. I might make the integration-style test a story. Perhaps when it ran I'd start script/server in test mode, and then copy over a dummy file and pull it down from http://localhost:3000/public/dummy;. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] How much test data to use in specs
On Mon, Aug 25, 2008 at 12:53 PM, Nick Hoffman [EMAIL PROTECTED] wrote: I'm not sure how much test data I should be using in my specs. I'm writing specs for the Property model in my Rails app. Its address attribute is going to be validated with this regex: /\A\d+[a-z]? [-', a-z]{2,128}\Z/i At the moment, my plan is to spec out the following possibilities. A property is invalid if its address: 1) doesn't begin with a digit; 2) is shorter than 2 characters; 3) is longer than 128 characters; I should also test that certain characters, such as ! @ # $ etc, invalidate a property. However, all of that seems like blacklisting, and achieves poor coverage of the regular expression. Should I create a list of valid and invalid addresses to test against the regex? That seems like a decent idea, but seems synonymous with fixtures. What would you guys recommend? I might do something like the following... describe Property, email validations do [[EMAIL PROTECTED], can't start with a digit, [EMAIL PROTECTED], can't end with a digit ].in_groups_of(2) do |email, description| it description do prop = Property.new :email = email prop.should_not be_valid prop.should have(1).error_on(:email) end end end -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] How much test data to use in specs
On Mon, Aug 25, 2008 at 2:50 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-08-25, at 13:29, Zach Dennis wrote: I might do something like the following... describe Property, email validations do [[EMAIL PROTECTED], can't start with a digit, [EMAIL PROTECTED], can't end with a digit ].in_groups_of(2) do |email, description| it description do prop = Property.new :email = email prop.should_not be_valid prop.should have(1).error_on(:email) end end end -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com Hi Zach. That's a great way of iterating over test data. Do you have any suggestions for how much test data to use? I'd probably start with the first invalid email/description that I can think of. Perhaps it can't start with a digit. Then I'd update the regexp to reflect that. Next I'd add a second invalid email/description and update the regexp to reflect that. Rinse and repeat until your regexp is where you need it. This should help you not add redundant emails which test the same thing. When you get to the case where you allow from 2 up to 128 characters, you could just test those two edge cases (rather than emails which 2 characters, 3 characters, 4 characters, ... 128 characters. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] stub_model() and ActiveRecord Associations
On Tue, Aug 26, 2008 at 10:03 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Tue, Aug 26, 2008 at 8:51 PM, Mark Wilden [EMAIL PROTECTED] wrote: On Tue, Aug 26, 2008 at 5:01 PM, David Chelimsky [EMAIL PROTECTED] wrote: @target_comment = stub_model(Target) @target.stub!(:comments).and_return([EMAIL PROTECTED]) That's what we do - what would the drawbacks be? It's more invasive than I'd like. It's not all that risky though. I just feel dirty whenever I mock methods on the objects I'm focused on. FWIW. A similar approach I've used when I'm not utilizing custom SQL logic (that requires hitting the database) which is less dirty IMO than modifying the object you're focusing on is: comments = [stub_model(Target)] @target.comments = comments -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] stub_model() and ActiveRecord Associations
On Wed, Aug 27, 2008 at 3:34 AM, Matt Wynne [EMAIL PROTECTED] wrote: Here's the basic deal: Model.find(1).equal?(Model.find(1)) = false AR does not cache objects, so when you ask it for what you *think* might the same object twice, you get different ones. I thought as much... So does AR just cache the object's attributes instead and construct them on the fly as and when you ask for them? It caches the SQL statements and their results. It uses the cached results to build an instance of your model. Although the identify of the objects are different, they are equal. f = Foo.create :name = blah f.equal?(Foo.last) # false f == Foo.last # true I don't know your ultimate goal, but you could rely on object equality (and not identify equality) in your test: @target_comment.should == @target_comments.first And then rely on @target_comments.first to set up your expectation for :merge_in. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] array_including()
On Wed, Aug 27, 2008 at 12:28 PM, Matt Wynne [EMAIL PROTECTED] wrote: On a similar vein, is there a neater way to express: assigns[:events].include?(@event_1).should be_true assigns[:events].should include(@event_1) -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] story runner not running on build machine
On Thu, Aug 28, 2008 at 3:39 AM, aa aa [EMAIL PROTECTED] wrote: Ben Mabey wrote: aa aa wrote: what is going on here?! It doesn't seem to be loading the plugin does it? Please post a runner file, your spec helper, and a steps file. -Ben odd, i changed the line in the all.rb from Dir[File.expand_path(#{dir}/**/*.rb)].uniq.each do |file| to Dir[File.expand_path(#{dir}/*.rb)].uniq.each do |file| and it worked That will only load .rb files that are in the same directory as the all.rb file. So it won't load things like stories/foo/thingy.rb or stories/foo/blah/thingy.rb. My guess is that is not what you want.This is assuming your all.rb file looked like: dir = File.dirname(__FILE__) Dir[File.expand_path(#{dir}/**/*.rb)].uniq.each do |file| require file end -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Application-wide spec_helper method
You can put it in a module and include it for model specs in spec_helper.rb Spec::Runner.configure do |config| # ... config.include DescribeModelAttributeSpecHelper, :type = :model end Zach On Thu, Aug 28, 2008 at 12:41 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-08-28, at 08:02, David Chelimsky wrote: On Wed, Aug 27, 2008 at 2:38 PM, Nick Hoffman [EMAIL PROTECTED] wrote: If a helper method can be used for multiple model specs, obviously it should not be placed within a specific model's spec helper file. Is there a recommended file in which to put such a method? Maybe spec/helpers/application_helper_spec.rb ? This is a very confusing question. Model's don't typically get individual spec helper files, so I'm not sure what you're getting at. Can you give an example? I asked because I had begun to abstract my #describe_properties method away from the Property model so that it can be used with any model. Now that the method's been converted from this: http://pastie.org/261175 to this: http://pastie.org/261829 I'd like to use it with multiple models. Cheers, Nick ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
[rspec-users] webrat question, form without buttons
Can you submit a form that has no submit button/image? -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] webrat question, form without buttons
On Wed, Sep 3, 2008 at 12:40 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-09-03, at 12:06, Zach Dennis wrote: Can you submit a form that has no submit button/image? You can submit a form using Javascript. That's why we don't have submit buttons. =) But in the context of webrat, if there is a form w/o a submit button, how can you submit it? Obviossly, clicks_button doesn't work anymore. Thanks, -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] webrat question, form without buttons
On Wed, Sep 3, 2008 at 1:31 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-09-03, at 13:15, Zach Dennis wrote: On Wed, Sep 3, 2008 at 12:40 PM, Nick Hoffman [EMAIL PROTECTED] wrote: You can submit a form using Javascript. That's why we don't have submit buttons. =) But in the context of webrat, if there is a form w/o a submit button, how can you submit it? Obviossly, clicks_button doesn't work anymore. Thanks, During regular use in a browser, how is your form submitted? When the user clicks a button, but all of the handy dandy work is done in unobtrusive-style javascript. It's not a submit button. It's a CSS-made button with listeners attached, -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] webrat question, form without buttons
On Wed, Sep 3, 2008 at 6:21 PM, Ben Mabey [EMAIL PROTECTED] wrote: Jarkko Laine wrote: On 3.9.2008, at 19.38, Zach Dennis wrote: On Wed, Sep 3, 2008 at 1:31 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-09-03, at 13:15, Zach Dennis wrote: On Wed, Sep 3, 2008 at 12:40 PM, Nick Hoffman [EMAIL PROTECTED] wrote: You can submit a form using Javascript. That's why we don't have submit buttons. =) But in the context of webrat, if there is a form w/o a submit button, how can you submit it? Obviossly, clicks_button doesn't work anymore. Thanks, During regular use in a browser, how is your form submitted? When the user clicks a button, but all of the handy dandy work is done in unobtrusive-style javascript. It's not a submit button. It's a CSS-made button with listeners attached, If you're going unobtrusive, why not go all the way and have a real submit button there that gets replaced by the javascript with your custom button? +1 In fact that is really,IMO, what unobtrusive JS means. People without JS should still have buttons and can use the site, they just don't get all the pretty colors. If you don't want to hide it with JS you could also just embed the buttons within noscript tags. Thanks for your feedback Jarkko and Ben. It's just what I needed. A button for degradation is coming soon to a project near me. thx guys, -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Four Question From an RSpec Baby - Give me something to chew
On Thu, Sep 4, 2008 at 7:14 PM, Nick Hoffman [EMAIL PROTECTED] wrote: On 2008-08-27, at 15:25, Mark Wilden wrote: The other thing I would say is that mocking and stubbing are powerful tools that you should add to your arsenal as soon as possible. I've had several coworkers who resisted using them, only to finally achieve that aha! moment later. Your tests get easier to write, and they're less brittle to change. G'day Mark. I was re-reading this thread and noticed this paragraph of yours. I've been using RSpec and BDD for about 2 months now, and love it. However, I'm not a fan of mocking and stubbing, primarily for two reasons: 1) I believe that specs should test behaviour, rather than a behaviour's implementation. This is a misleading statement. Testing the behavior of an object involves its input and output collaborators. When used appropriately mocks and stubs act as an agent for design and discovery. They also allow objects under test to be isolated from other objects that it depends on (which may not even exist yet). Collaborators are what should be used to set up with stubs and mock expectations. This way we can test the behavior of the object under test given different values returned by its collaborators. For example: class FundsTransfer def transfer(amount, source_account, target_account) if source_account.balance amount raise not enough money else source_account.deposit amount target_account.withdraw amount end end Without using mocks or stubs to test the above code I wouldn't be able to test the case where the source account doesn't have enough money or does have enough money -- unless I already have implemented the Account class and its withdraw, deposit and balance methods. Taking the approach of writing the Account class first is an approach that a lot of developers take. But you build what you think you need before you actually need it. I prefer to develop from the other direction, only building what I discover I need to make it work. Either way though behavior is being tested, and it is not testing against the internal state of an object. 2) Using mocks and stubs causes your specs and implementation to be tightly coupled, which often forces you to modify your specs if changes occur in the implementation. However, #2 contradicts what you said about tests ... [are] less brittle to change when using mocks and stubs. Considering that I'm still very new to mocks and stubs, I'm probably missing something here. When you have a minute, would you mind countering me? You can write bad tests with mocks/stubs and without mocks/stubs. Using mocks/stubs doesn't immediately tightly couple your specs to your implementation. It does however tie your specs to the external interface of the object under test. If you change that, then you will need update your specs. Consider our FundsTransfer example again: class FundsTransfer def transfer(amount, source_account, target_account) if source_account.balance amount raise not enough money else source_account.deposit amount target_account.withdraw amount end end If I supply a source_account that has a stubbed out balance of less than the amount requesting to be transferred am I tightly coupling the spec to the implementation? No more so then creating a source account fixture with an amount less than the amount that I am requesting to transfer. I say this because at some point you need to test the scenario where funds are requested to be transferred from a source account that doesn't have enough money. Do you really see one of the below examples more tightly coupling the test to the implementation? account = mock(Account, :balance = 0) account = Account.new :balance = 0 The difference to me is that using the mock allows me to discover earlier what interface I want to work with on the Account class. If I go the non-mock route then I need to make sure I build the Account class with the interfaces I need first. I much prefer to work in small steps. Focus on one behaviour, and then when it works as expected, make sure any collaborators that need to be implemented are. Then use my integration tests to make sure everything is wired up correctly together. That's just me though, -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Best practices for sharing state between story steps?
This thread may help give you some insight... http://www.mail-archive.com/rspec-users@rubyforge.org/msg05382.html Zach On Sun, Sep 7, 2008 at 7:58 PM, Sam Stokes [EMAIL PROTECTED] wrote: Hi all, I'm just getting into RSpec stories and liking them (especially with webrat), but I'm finding it tricky to write steps that are self-contained and reusable, particularly where features intersect. What approaches do people use to achieve this? (Maybe a better question is, do people bother? One of the things I like about story-runner is the way I'm building a DSL for integration testing my application, but should I just write the scenario I need, write the steps to make it run and forget about reusing steps?) As an example of where I'm having trouble, say I'm writing a blog (since it's the Web 2.0 version of Hello World), so I have posts and comments. I want to write a scenario something like Given a post And some comments for the post When I view the post Then I should see the comments How do I tell the Given some comments step which post to attach the comments to? I can do it by having Given a post set a @post instance variable and having Given some comments use that, but it feels like global variables all over again. My steps (probably in different files) are coupled via the @post instance variable, and other steps can clobber it, and if I forget to clear it I might pollute later steps, and if I want to refer to more than one post (@post1, @post2) I have to rewrite all my steps... I noticed a little note on the Cucumber wiki (http://github.com/aslakhellesoy/cucumber/wikis/home) explicitly advising against using @variables for this, I'm guessing for these reasons. I could avoid the first issue by combining the top two steps into Given a post with some comments but then I still have the problem of which post When I view the post should GET. Maybe When I view a post with comments...? Any advice, criticism or sympathy appreciated :) -- Sam -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Best practices for sharing state between story steps?
On Tue, Sep 9, 2008 at 3:52 PM, Matt Wynne [EMAIL PROTECTED] wrote: On 9 Sep 2008, at 19:52, Jim Morris wrote: aslak hellesoy wrote: The debate seems to be whether step definitions should be stateful or not. In practice this is achieved by setting one or more @variables in a step and reusing them in a different step - all within a scenario. I think that is the debate, but I'd like to point out that there is always state between steps, it is just a matter of where it is being kept. In your example for instance most of the state is being kept in the database between steps (ie between Given an active site_user names aslak and he following steps. (As a side question how do you clean up the database between tests, so the state from the previous Scenario doesn't affect the next Scenario?) In some cases I use a randomly generated record each time. I think the scenarios are each wrapped in a transaction, so (as long as you're using the right type of database / tables) the slate should be wiped clean between each one. I don't think this works as you may expect since My SQL and PostgreSQL don't support nested transactions, which is what would happen if your test environment wrapped stories/scenarios in transactions and your application utilized transactions. Granted there has been hopes of getting savepoints fix the problem, but the ticket has not been resolved: http://rails.lighthouseapp.com/projects/8994/tickets/383-activerecord-should-use-savepoints-for-nested-transactions -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Growl notifications don't work each time??
On Fri, Sep 12, 2008 at 11:11 PM, Scott Taylor [EMAIL PROTECTED] wrote: On Sep 12, 2008, at 1:38 AM, Pat Maddox wrote: Greg Hauptmann [EMAIL PROTECTED] writes: Hi - has anyone had problems with Growl notifications not working each time? I can hit save on a test, wait, check. Then hit save again, wait, check. Sometimes the growl notification doesn't work. I'm using ZenTest / Rspec. * ZenTest (3.10.0) * Macintosh-2:myequity greg$ ruby -v ruby 1.8.6 (2007-09-23 patchlevel 110) [i686-darwin9.3.0] * Macintosh-2:myequity greg$ rails -v Rails 2.1.1 I don't know about your particular problem, but since you're on OS X I recommend using RSpactor instead. The app itself just works better, and growl notifications work great out of the box. Have you gotten rspactor to work with only specific directories? I'd like to run rspactor only in spec/unit, but can't seem to find any documentation on it. Also - why does it only work on OS X.5? Because it relies on the File System Events API which was introduced in 10.5. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Adding Test Spy into Rspec mocking framework
On Mon, Sep 15, 2008 at 2:28 PM, Pat Maddox [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 12:54 PM, Joseph Wilk [EMAIL PROTECTED] wrote: Doesn't RR already support test spy? I don't believe so. There is nothing on the github page or anything I can spot in the current code in git. The github docs do mention it as something they are aiming to do. o = stub(stub, :foo = true) o.foo o.should have_received(:foo) That sounds really interesting Pat. Is is something that's living in github? I would be interested to see what you are coming up with when you get a chance to let it out into the wild. It's not up there yet, but I can push it when I get home. Granted, it's far from complete, but the basics are in place. I need to pull out some of the existing expectation code so we can easily reuse it in the post hoc verification style. You have been a busy man recently Pat! Kudos to all the work you've been doing providing goodness for the community, -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] w3 validation
On Mon, Sep 15, 2008 at 5:32 PM, Jonathan Linowes [EMAIL PROTECTED] wrote: Hi, suggestions how to add w3 validation to a story step? eg Then the page should be valid You could write a then step that takes the current response.body, uploads it to the w3 validator, and checks the the response. Rather than uploading you could use the ruby tidy bindings to do offline validation which would most likely be much faster. See http://tidy.rubyforge.org/ for more information. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Cucumber - Ambiguous steps
On Mon, Sep 15, 2008 at 9:34 AM, aslak hellesoy [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 3:27 PM, David Chelimsky [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 8:21 AM, David Chelimsky [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 8:13 AM, aslak hellesoy [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 3:07 PM, Joseph Wilk [EMAIL PROTECTED] wrote: David Chelimsky wrote: On Mon, Sep 15, 2008 at 3:54 AM, Joseph Wilk [EMAIL PROTECTED] wrote: You can still use non-regular expression steps in Cucumber: I've been unable to think of a good example where I would want only a partial match of a step. Throwing away the unmatched characters. Does anyone have good examples where they would? I think you've got this right and exposed a bug. Wanna report it to lighthouse and/or fix it? Sure I'll report it and write a patch. Hold on. If you want the regexp to match until the end of the string, why don't you just stick a $ at the end of the Regexp? That's how regexen work. I don't see why they should work any differently when used in Cucumber. My previous comments withdrawn. I agree with Aslak. Although, I can see why one might be confused by this. I was. Even though these are regular expressions, the context led me to an (erroneous, but intuitive) expectation that in the presence of these two ... /this and (.*)/ /this and (.*) and the other thing/ ... that the first would not match this and that and the other thing Perhaps a hint in the error message is in order? When this and that and the other thing Ambiguous step resolution for this and \that\ and the other thing: ./features//foo-steps.rb:4:in `/this and (.*) and the other thing/' ./features//foo-steps.rb:1:in `/this and (.*)/' (Cucumber::Ambiguous) Consider ending the shorter expression with a $ WDYT? I like this much better. -Guiding people to use regexen properly is better than redefining their semantics. I completely agree. The current story runner fudges with regexps and it's really annoying. Raise the bar for regexp education... K-12. ;) -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] RSpec story failing because create is not rendering 'show'
On Sat, Sep 13, 2008 at 2:24 PM, Damian Jones [EMAIL PROTECTED] wrote: Ok I got my story to pass by changing the follwing snippet When /I create a product named (.*) described with (.*)/ do |name, description| visits new_product_path fills_in product[name], :with = name fills_in product[description], :with = description clicks_button Create end don't know why it doesn't work with this: fills_in :name, :with = name Webrat api specs say it should No it doesn't. It says that the first argument is considered as an HTML id, name or label. The id is product_name. The name is product[name] and I can't tell from what you posted if you have a label name. http://github.com/brynary/webrat/tree/master/lib/webrat/core/scope.rb Zach -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Shoulda
On Tue, Sep 30, 2008 at 8:41 AM, Andy Freeman [EMAIL PROTECTED] wrote: Are you willing to provide a simple example? I'm using the same example as the articled you linked to originally as the base. This way you should be able to clearly see the differences. http://gist.github.com/13804 Zach Andy Matt Wynne wrote: We do something similar to this, though we use a convention to set @klass to the class being spec'd in the top-level example group, rather than deriving it as they do in that sample. In view specs we also use a convention to always have a do_render method available, so that we can bring in similarly shared / generated examples. It's great for speccing two sublcasses which have some common behaviour, where it feels wrong to spec the (abstract) base class. -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users
Re: [rspec-users] Shoulda
Also, a nice thing about RSpec is that when you do describe an actual object, ie: describe Foo, you can determine this by asking the example group what it's described type is. This makes things a lot simpler and cleaner than having to hack away strings, or guess based on the name of your test. Zach On Tue, Sep 30, 2008 at 8:57 AM, Zach Dennis [EMAIL PROTECTED] wrote: On Tue, Sep 30, 2008 at 8:41 AM, Andy Freeman [EMAIL PROTECTED] wrote: Are you willing to provide a simple example? I'm using the same example as the articled you linked to originally as the base. This way you should be able to clearly see the differences. http://gist.github.com/13804 Zach Andy Matt Wynne wrote: We do something similar to this, though we use a convention to set @klass to the class being spec'd in the top-level example group, rather than deriving it as they do in that sample. In view specs we also use a convention to always have a do_render method available, so that we can bring in similarly shared / generated examples. It's great for speccing two sublcasses which have some common behaviour, where it feels wrong to spec the (abstract) base class. -- Posted via http://www.ruby-forum.com/. ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com ___ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users