Hi Jesse... Did you ever find a solution to this problem. Im having the same issue.
On Sunday, February 15, 2015 at 1:28:07 PM UTC-8, Jesse Whitham wrote: > > Absolutely not I will raise this there now. Thanks for the suggestion. > > On Friday, 13 February 2015 13:11:15 UTC+13, Jon Rowe wrote: >> >> Hi Jesse, would you mind opening an issue for `get ‘test’` not working in >> a `before(:context)` over on `rspec-rails`? I’m not sure that it’s fixable >> (due to the way Rails works) but if it isn’t we should probably stop people >> from trying to do so. >> >> Jon Rowe >> --------------------------- >> [email protected] >> jonrowe.co.uk >> >> On Friday, 13 February 2015 at 08:39, Jesse Whitham wrote: >> >> Hi Myron, >> >> Thanks for your quick response. The feature you are talking about could >> be very useful I would suggest that it would only provide what I would like >> if it formats the expectation failures in a way that they are not just a >> long string of different failures. In regards to the before(:context) hooks >> I did look at this an option, and you are absolutely right about the >> caveats in my case (testing an api) the get/post methods from rspec-rails >> are not usable as below. >> >> Failure/Error: get 'test' >> RuntimeError: >> @routes is nil: make sure you set it in your tests setup method. >> >> >> My hypothetical case of 100 expectations is really just being used to >> emphasize the problem in reality I have a bunch of tests similar to this >> that make more like 4-5 expectations but then if you expand it to look at >> invalid user, disabled user and deleted user etc. you end up with a lot >> more. Honestly it isn't a huge performance hit that make my tests take >> hours and hours to run, but in saying that the more I write the worse it >> will get. (By no way am I saying these tests are perfect I believe checking >> it respects an XML format and is valid XML is probably superfluous) >> >> context 'valid request' do >> before do >> @user = FactoryGirl.create(:authenticable_user) >> # Not going to put the actual request here assume its something >> post :api_request, request >> end >> >> it { expect(response).to be_ok } >> >> describe 'with a valid user' do >> it 'is a valid XML structure' do >> expect { parse_xml(response.body) }.not_to raise_error >> end >> it 'is successful' do >> expect(response.body).to include("success='true'") >> end >> it 'respects expected XML format' do >> expect(response.body).to match_response_schema('login_response' >> ) >> end >> it 'contains a valid authentication token' do >> auth_token = Nokogiri::XML(response.body).xpath( >> "//login_response").attribute("auth_token").value >> expect(auth_token).to match(#A regex) >> end >> end >> >> Any way if you have hints etc. let me know. Honestly being able to use >> before(:all) with post/get would fix this problem perfectly but from what >> you have noted this seems not possible and may require some work on >> rspec-raiils itself. >> >> Thanks, >> Jesse >> >> On Thursday, 12 February 2015 16:47:18 UTC+13, Myron Marston wrote: >> >> On Wednesday, February 11, 2015 at 7:23:13 PM UTC-8, Jesse Whitham wrote: >> >> So I ran into this problem with Testing our API. >> >> The problem is the get request is called multiple times based on >> examples. e.g this code below will run get 'test' twice. >> >> require 'rails_helper' >> >> describe API::TestController, type: controller do >> before do >> get 'test' >> end >> >> it { expect(response).to be_ok } >> it { expect(response.body).to eq('test code')end >> >> This is a problem when you start to have more expect statements in terms >> of performance. As far as I know there is no good workarounds for examples >> to re use the same response. The guide herehttp://betterspecs.org/#single >> talks >> about putting multiple expects into the it statement, this seems to go >> against getting good failure responses. >> >> Using a before(:all) you get an error like so >> >> Failure/Error: get 'test' >> RuntimeError: >> @routes is nil: make sure you set it in your tests setup method. >> >> Is there a way to send only one request without ruining the failure >> responses? >> (or if you like use memoization over multiple examples) >> >> I did find you could use a global variable but this seems like the worst >> code ever. >> >> require 'rails_helper' >> >> describe API::TestController, type: controller do >> it 'makes a single request' do >> get 'test' >> $stupid_global = response >> end >> it { expect($stupid_global).to be_ok } >> it { expect($stupid_global.body).to eq('test code')end >> >> >> I posted this here https://github.com/rspec/rspec-core/issues/1876 and >> got this response: >> >> This conundrum (shared state vs performance is one of the reasons we >> added compound matchers to RSpec 3.2, so you can now do: >> >> >> it { expect(response).to be_ok.and eq 'test code' } >> >> >> This isn't a complete solution of course but we don't want to advocate >> shared state across examples. >> >> Incidentally Github issues are not the place to request support, please >> use the mailing list / google group (https: >> //groups.google.com/forum/#!forum/rspec) and/or #rspec on freenode." >> >> >> I really don't see this as a even usable solution as if you have 100 >> expectations >> >> >> And you compound those you end up with failure in one string like so: >> >> >> Failure/Error: "we expected it to have this and and we expected it to >> have this and we expected it to have this and we expected it to have this >> and we expected it to have this and we expected it to have this we >> expected it to have this we expected it to have this we expected it to >> have this we expected it to have this we expected it to have this we >> expected it to have this" >> >> you don't compound them have one useless string with lots of expectations >> >> Failure/Error: "we expected the response to be ok (not sure why its not)" >> >> or you make 100 requests (massive performance load). >> >> Does anyone have any suggestions for better ways? Alternative testing >> frameworks? (maybe rspec just isn't useful for this kind of testing) or >> even a feature for shared state? (By the sounds of it this will not be >> supported) >> >> >> >> Hey Jesse, >> >> This is a great question. One solution, which has been available for >> years, is to use a before(:context) (or before(:all) — that’s the old >> RSpec 2.x form, and it still works in RSpec 3) hook. See, for example, this >> PR >> <https://github.com/rspec/rspec-support/pull/179/files#diff-ec40054ce667411396ff663c4d03bb50R65> >> where >> I’m doing a slow operation in before(:context), storing it in an >> instance variable, making it available via some attr_reader declarations, >> and using the results from multiple examples. >> >> Note, however that before(:context) hooks come with many caveats. (See >> the “Warning: before(:context)” section from our docs >> <http://rspec.info/documentation/3.2/rspec-core/RSpec/Core/Hooks.html#before-instance_method>). >> >> The basic problem is that many things that integrate with RSpec — such as >> DB transactions from DB cleaner or rspec-rails, or the rspec-mocks test >> double life cycle — have a per-example life cycle, and running logic >> *outside* of that lifecycle can cause problems. If you create DB records >> in before(:context) and are using per-example DB transactions, it would >> create the records and not clean them up afterwords, potentially affecting >> later tests. So I’d say the before(:context) solution is great as long >> as you don’t have per-example life cycle stuff going on. If you do have >> that kind of stuff going on (and it’s very common to, especially in a rails >> context) you’re better off avoiding before(:context) or at least being >> extremely careful what you do in there. >> >> I think the “one expectation per example” guideline is a useful >> corrective to a pattern many first-time testers fall into, where they do >> too much in one test or one example, and have hard-to-understand test >> failures, but it's not something I recommend following strictly. >> Personally, I use “one expectation per example” as a signal…if I’m putting >> multiple expectations in one example I may be specifying multiple >> behaviors. In fast, isolated unit tests you want to keep each example >> focused on one behavior. In slower, integrated tests that’s far less >> important, and the cost of the setup time (and different kind of test) >> causes me to not worry about “one expectation per example”. If you are >> doing slow integrated testing and the thing being is so complicated that it >> needs 100 expectations (as per your hypothetical case), that suggests to me >> that your logic could benefit from being refactored, with more of it being >> extracted into stand-alone ruby objects that don’t interact with the slow >> external things and can be quickly unit tested in isolation. >> >> One other thing I’ve been mulling over recently is a new feature in RSpec >> that would better support what you’re trying to do. I’m thinking it would >> be something like: >> >> it "returns a successful response" do >> get 'test' >> aggregate_failures do >> expect(response).to be_ok >> expect(response.body).to eq("test code") >> endend >> >> The idea is that aggregate_failures (not necessarily what we’ll call it >> — it’s the best name I’ve thought of so far, though) will change how >> expect works for the duration of the block so that rather than aborting >> on first failure, it collects all expectation failures until the end of the >> example, and the block, and then, if there were any failures in the block, >> it’ll abort at that point with all of the failure output. >> >> Would that do what you want? >> >> HTH, >> Myron >> >> -- >> You received this message because you are subscribed to the Google Groups >> "rspec" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/rspec/454ab805-c421-4ac8-a335-9a1f0e737653%40googlegroups.com >> >> <https://groups.google.com/d/msgid/rspec/454ab805-c421-4ac8-a335-9a1f0e737653%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> >> >> -- You received this message because you are subscribed to the Google Groups "rspec" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/35d2697f-8a71-406e-b733-2ba3e98e59dd%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
