<div dir="ltr">Thanks again for all the responses everyone, hugely useful! <div><br></div><div>So far we've managed to shave 10 minutes off the test run using a variety of tricks:</div><div><br></div><div>1 - spring</div>
<div>2 - parallel_tests</div><div>3 - GC tuning</div><div>4 - Deferred GC</div><div><br></div><div>Not a trick, but upgrading to Ruby 2.0 has helped as well, although this has caused a few test failures as well. </div><div>
<br></div><div>To get the rest of the suite down, i'll be looking at implementing lots of people's suggestions</div><div><br></div><div>Thanks</div><div><br></div><div>Tom</div></div><div class="gmail_extra"><br><br>
<div class="gmail_quote">On 5 December 2013 21:46, Viktor Trón <span dir="ltr"><<a href="mailto:viktor.tron@gmail.com" target="_blank">viktor.tron@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
IMHO zeus, vcr, database cleaner truncate, db on ramdisk, and frugal<br>
use of factory create (as opposed to build) go a very long way with<br>
clean non-hacky solutions<br>
<div class="HOEnZb"><div class="h5"><br>
On 5 December 2013 18:58, James McCarthy <<a href="mailto:james2mccarthy@gmail.com">james2mccarthy@gmail.com</a>> wrote:<br>
> Just in case some low hanging fruit hasn't been covered;<br>
><br>
> I’d first turn your network connection off and run the test suit to catch<br>
> any stupid tests coupled to api’s and put VCR on there for the moment. I’ve<br>
> picked up several apps where this has happened.<br>
><br>
> If you’ve got Devise in there make sure your test_helper puts the stretch<br>
> time down to one;     Devise.stretches = 1<br>
><br>
> If Factory Girl is being used then move as many things to use<br>
> builld_stubbed; Use Factory Girl's build_stubbed for a Faster Test Suite<br>
><br>
> What version of Ruby? I’ve found vanilla 1.8.7 benefitted from moving to EE<br>
> and manually controlling GC YMMV;<br>
><br>
> <a href="http://fredwu.me/post/60441991350/protip-ruby-devs-please-tweak-your-gc-settings-for" target="_blank">http://fredwu.me/post/60441991350/protip-ruby-devs-please-tweak-your-gc-settings-for</a><br>
> <a href="https://gist.github.com/JamesChevalier/4735441" target="_blank">https://gist.github.com/JamesChevalier/4735441</a><br>
> <a href="http://labs.goclio.com/tuning-ruby-garbage-collection-for-rspec/" target="_blank">http://labs.goclio.com/tuning-ruby-garbage-collection-for-rspec/</a><br>
><br>
> I have gone down the route of taking my least rails coupled tests require a<br>
> skinny_test_helper.rb that doesn’t load the whole rails stack and provides<br>
> just enough unit test running, leaving the slow stuff to integration and<br>
> controller tests, and at this stage, only the stuff you can move over really<br>
> easily or you are re-factoring the wrong thing.<br>
><br>
> Controller tests often get a bad rap, they can add value. Ask yourself if<br>
> the goal of an integration test could be achieved by testing further down<br>
> the stack where it consumes less resources e.g. is a test for the presence<br>
> of a widgets description actually a proxy for the controller instantiating a<br>
> variable. Is an integration test actually a proxy for testing a helper, or<br>
> an indication that the view code should be re-factored into some kind of<br>
> view [helper | view object | presenter | whatever you call it]?<br>
><br>
> But now I’m getting into re-factoring which I didn’t set out to comment on:<br>
> <a href="http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/" target="_blank">http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/</a><br>
><br>
><br>
><br>
> On 5 Dec 2013, at 10:54, Sam Livingston-Gray <<a href="mailto:geeksam@gmail.com">geeksam@gmail.com</a>> wrote:<br>
><br>
> I just put a require statement at the top of the fast test file for what I'm<br>
> testing, and another one for anything it depends on. When that gets to be<br>
> annoying, I know I have too many dependencies. ;)<br>
><br>
> --<br>
> (Sent from phone. Please excuse: brevity, top posting, hilarious<br>
> autocorrections.)<br>
><br>
> On Dec 5, 2013, at 7:29 AM, Jon Leighton <<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a>> wrote:<br>
><br>
> Hi Tom,<br>
><br>
> On 05/12/13 09:28, Mr Jaba wrote:<br>
> Interesting points on making your unit tests independent of Rails, I<br>
> hadn't considered the class reloading aspect. Does this interfere very<br>
> badly? Is it avoidable at all? Or was the cost of maintaining all the<br>
> requires simply too high?<br>
><br>
><br>
> If you want to run your tests outside of Rails, you can't rely on the<br>
> rails autoloading mechanism (ActiveSupport::Dependencies). But if you<br>
> put requires all over the place, it will prevent AS::Dependencies from<br>
> working when you *do* want it to (i.e. code reloading in dev mode won't<br>
> work, because the code was loaded by a require rather than a missing<br>
> constant).<br>
><br>
> The solution I ended up with was basically using require_dependency<br>
> rather than require, and stubbing out require_dependency for my "outside<br>
> Rails" tests. It was nasty.<br>
><br>
> In might be possible to *just* use AS::Dependencies in your unit tests,<br>
> without loading the full Rails app. That's something I didn't try, but<br>
> with spring loading the full app is not such a big deal for me these<br>
> days anyway, so I don't see the benefit of having tests that can run<br>
> outside of the Rails app.<br>
><br>
> Jon<br>
><br>
><br>
> Thanks again<br>
><br>
> Tom<br>
><br>
><br>
> On 5 December 2013 09:04, Jon Leighton <<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a><br>
> <mailto:<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a>>> wrote:<br>
><br>
>   Hi Tom,<br>
><br>
>   On 04/12/13 22:56, Mr Jaba wrote:<br>
> First up, thanks for Spring (amongst your many other contributions!)<br>
> it's a really useful gem!<br>
><br>
><br>
>   Glad you like it!<br>
><br>
> With regards to the factories, what do you recommend instead? Simpler<br>
> objects with less coupling to Rails?<br>
><br>
><br>
>   Yeah I don't like the factories approach at all. Apart from often being<br>
>   a source of test slowness, they encourage you down the path of high<br>
>   coupling and make it too trivial to create a boat load of<br>
>   database-backed objects. Bo Jeanes wrote a post about this:<br>
>   <a href="http://bjeanes.com/2012/02/factories-breed-complexity" target="_blank">http://bjeanes.com/2012/02/factories-breed-complexity</a><br>
><br>
>   There are certainly situations in a Rails app where you need to test<br>
>   against the database. For this I use fixtures, which I find perfectly<br>
>   adequate and much faster than factories. You do need to ensure your<br>
>   fixtures don't get out of control, but generally I think of fixtures as<br>
>   a handful of pre-inserted records that I might modify in specific tests<br>
>   in order to achieve a certain thing (rather than creating a new fixture<br>
>   entry for each thing, which can get out of hand).<br>
><br>
>   Apart from that, it's obviously wise to avoid inserting stuff in the<br>
>   database as much as possible, e.g. if you just want to test the logic of<br>
>   a certain method which only interacts with a model's attributes, you can<br>
>   just create an in-memory instance.<br>
><br>
>   I have been down the path of making my "unit tests" independent of the<br>
>   Rails app so as to avoid the boot process, and found it impractical to<br>
>   be honest:<br>
><br>
>   1) You end up with require and require_dependency everywhere, and it's<br>
>   hard to get this right in a way that plays nicely with Rails' class<br>
>   reloading<br>
>   2) Even if you make some tests independent of Rails, you're still going<br>
>   to need some that are not independent of Rails, so you only solve part<br>
>   of the problem<br>
><br>
>   This was part of my motivation for spring - if we can't make get rid of<br>
>   having to boot the Rails app, let's make booting the Rails app less<br>
>   painful.<br>
><br>
>   Not sure any of these comments help with your current predicament, but<br>
>   hopefully they're vaguely useful anyway!<br>
><br>
>   Jon<br>
><br>
><br>
> Thanks for your input!<br>
><br>
> Tom<br>
><br>
><br>
> On 4 December 2013 22:43, Jon Leighton <<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a><br>
><br>
>   <mailto:<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a>><br>
><br>
> <mailto:<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a> <mailto:<a href="mailto:j@jonathanleighton.com">j@jonathanleighton.com</a>>>><br>
><br>
>   wrote:<br>
><br>
><br>
>   Hello there,<br>
><br>
>   On 04/12/13 22:20, Mr Jaba wrote:<br>
> I've recently taken ownership of a new project with a large<br>
><br>
>   test suite<br>
><br>
> (2000ish tests), and the overall run time is around 30 minutes<br>
><br>
>   which is<br>
><br>
> certainly less than ideal!<br>
><br>
> Now I know the general approach to "Fast Rails Tests" but<br>
><br>
>   taking the<br>
><br>
> time to refactor the whole test suite is a bit too much<br>
><br>
>   right now. I'm<br>
><br>
> wondering if anyone has experience of transforming a test<br>
><br>
>   suite of<br>
><br>
>   this<br>
><br>
> magnitude to something a bit speedier? If so how did you go<br>
><br>
>   about it?<br>
><br>
> What tips, tricks and techniques can you share?<br>
><br>
> A bit more info:<br>
><br>
> - Test::Unit tests, moving to Minitest<br>
> - Rails 3.2.16<br>
> - Running parallel_tests shaved 5 mins off the time<br>
> - Using Spring to reduce Rails load time.<br>
><br>
> Any advice gratefully received!<br>
><br>
><br>
>   I think you need to provide some more information :) What's<br>
><br>
>   making it<br>
><br>
>   take so long - the sheer number of tests or what the tests are<br>
><br>
>   doing? Do<br>
><br>
>   you have certain types of tests that are taking a large<br>
><br>
>   portion of the<br>
><br>
>   time (e.g. Capybara tests?) Are you using factories? In my<br>
><br>
>   experience<br>
><br>
>   factories are an easy cause of a slow test suite.<br>
><br>
>   One thing to think about is whether you can break up your test<br>
><br>
>   suite.<br>
><br>
>   For example in the application I work on, we have<br>
><br>
>   unit/integration tests<br>
><br>
>   which run in about 25 seconds on my machine. I frequently run<br>
><br>
>   these<br>
><br>
>   during development and they often alert me to problems. But I<br>
><br>
>   rarely run<br>
><br>
>   the full set of capybara tests which takes several minutes - I<br>
><br>
>   let the<br>
><br>
>   CI do that and run failing tests individually where necessary.<br>
><br>
>   This<br>
><br>
>   achieves a decent balance of fast feedback for development without<br>
>   throwing away the safety net of proper full-stack tests.<br>
><br>
>   Jon<br>
>   _______________________________________________<br>
>   Chat mailing list<br>
>   <a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a> <mailto:<a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a>><br>
><br>
>   <mailto:<a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a> <mailto:<a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a>>><br>
><br>
>   <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
><br>
> _______________________________________________<br>
> Chat mailing list<br>
> <a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>
> <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
><br>
> _______________________________________________<br>
> Chat mailing list<br>
> <a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>
> <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
><br>
><br>
><br>
> _______________________________________________<br>
> Chat mailing list<br>
> <a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>
> <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
><br>
_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>
<a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</div></div></blockquote></div><br></div>