Until yesterday, one of our in-development applications was routinely taking over 4 minutes to run its full test suite (without running our Cucumber tests). Four minutes per run can pretty easily turn into an hour per day when testing every commit. I was beginning to think that "testing" is the new "compiling".
The best solution for benchmarking Rails tests is the aptly named test_benchmark. After just one run with BENCHMARK=true1, it became pretty apparent what the problem was: we had one test file (of out of several dozen total) that was taking nearly a minute to run. That's 25% of total test time being spent in one file. Crikey.
Let me stop right here and spoil the end of this post for you: I rewrote the test from scratch, and I was able to get this specific test down to around 3 seconds. Here's the story:
Mint uses Shoulda for all its tests these days, with much praise about how nicely shoulda tests read. This is the recommended "shoulda way" to write a controller test:
context "on GET to index" do
setup { get :index ; @stuff = Factory(:stuff) }
should_respond_with :success
should_render_template :index
should_assign_to(:stuff) { [@stuff] }
end
When you write a test like this, you need to understand that the macros you see (eg, should_respond_with) each create a separate test. That separate test runs the setup method of its context along with any other setup methods in contexts above it. This means that the above context block results in 3 object creations and three get calls.
Here's the same test, written with Rails' built-in assertions:
test "on GET to index" do
stuff = Factory(:stuff)
get :index
assert_response :success
assert_template :index
assert_equal [@stuff], assigns(:stuff)
end
One object created. One test request made. It may not seem like much, but multiply this behavior over 20 context blocks and it suddenly starts to add up. Does the test/unit version look as nice? Maybe not, but if writing tests like this makes our tests 1600% faster, I'm tempted to overlook the "pretty factor".2
The moral of the story is to be mindful. If you choose to use a third-party testing library, shoulda or otherwise, be aware of how it works and its shortcomings. Be critical about your tests. Benchmark often and consider it a bug if your tests take too long.
-
We added this line to `test.rb` so that benchmarks don't clutter our
test output all the time:
ENV['BENCHMARK'] = 'false' unless ENV['BENCHMARK']
-
In the spirit of full disclosure, shoulda is not completely at fault. In our specific test, this sort of behavior was exacerbated by some bad test design. We had several nested `context` blocks, each with their own setup blocks, along with a global setup method that created loads of objects that were only used in a handful of tests; we were creating 50+ objects for every test. Shoulda didn't write these tests poorly, but it didn't encourage good behavior either.
Original cartoon by xkcd
Comments
Spandnox
18 May, 2012
Heutzutage befindet gegenseitig der weltweite Hauptsitz dieses Herstellers inside Singapur. Ein ordentliches Kabel hat parallel zu den Draehten gleichermassen noch die Absonderung integriert, welche verwehrt, dass ein Pfeifen aus einer Musikquelle mit uebertragen wird das wahrhaftig nur der Sound zu hoeren ist. http://tinyurl.com/c9c4fjf - monster beats kopfhoerer Young benannte sich in Doktor Dre um. Typ Sitzgelegenheit dieser Deutschlandzentrale des Unternehmens befindet einander in unserem nordas heisstin-westfaelischen Nettetal. Vornehmlich in ihrem Heimatstaat, Utah, besitzt Skullcandy den sehr guten Ausruf. Natuerlich gehoeren ebenfalls Diese Kopfhoerer mit Buegel, Eine perfekte entschuldige kabellos an Eine perfekte Hi-Fi-Anlage wer weiss den Tv angeschlossen werden erleben, zum Kopfhoererprogramm des Elektronikanbieters. Vorteil der Bauform: Entsprechende Ohrhoerer werden klein und ebenfalls transportabel, weshalb sie gleichermassen vielmals MP3-Playern und Smartphones kostenlos beiliegen. Jetzt lud ich sie zum ersten mal zum essen ein. Als sie eintrat, kam mir ihr Gesicht bekannt vor. http://ow.ly/aZ1CN - just beats kopfhoerer Meine Augen waren geblendet von dem gleissendem Licht, das erste mal seit langem sah ich wieder Tageslicht langsam, ganz langsam gewoehnte ich mich daran. Tja, das war es dann Anfragen bei der Polizeiund bei zwei Rechtsanwaelten bestaetigten mir, dass ich keine Chance hatte. Winzige Logos oder Bauart werten folgende hinauf, wobei Modelle mit ausgefallener Ausformung des Kopfhoerergehaeuses ausgewaehlt werden koennen. Dazu wurde pinkes Rauschen auf dem XE abgespielt, einmal mit und einmal ohne BeatsAudio, und von einem spezial Mikrofon aufgenommen. http://qr.is/1000aI - dr dre beats solo hd Allerdings staut gegenseitig unter den das Ohr umschliessenden Muscheln gleichermassen die Waerme. http://po.st/NAg4xS - monster kopfhoerer