Hi all. I've been working on a project recently with a lot of moving parts (eventmachine, rabbitmq, background worker processes, web server, etc).
Predictably, testing it in a way that's aesthetically pleasing, reliable, and fast has turned up a number of challenges. For example, EM runs in a blocking event loop when you call EM.run; AMQP will only run inside an EM.run loop. There are some (excellent) options like moqueue and bunny for working around the latter, to an extent, but integration tests running on the whole stack must either run as a background thread or against a separate, already-running server (both of which in turn require that rabbitmq-server and postgres be running). Add the need for repeatable test data to the mix, and you get the choice of either using transactions (which are not visible between threads, i.e. cause pain and/or death), or deleting data between tests. If a backgrounded thread is still writing to a record you've deleted, bad things tend to happen. I could go on. Anyway - after much suffering, I find myself arriving at some strange conclusions recently, which I'm going to collectively dub something snappy ending in 'DD', in the hope it makes me famous. If you have any ideas for a name, chime in. Here's the canon (WIP): * The tests are more important than the application. * The application should be refactored constantly to improve the quality of the tests. * The tests should run as close to instantly as possible. * The application's architecture should maximize the quality (speed, clarity, reliability) of the test suite. * Tests should be structured like a pyramid: unit tests on the bottom, functional tests in the middle, integration tests on the top. * If you can't unit test something without mocking the very laws of physics, scrap it. * Use simpler data structures. * If you must use classes rather than hashes, arrays or other primitives (things you can serialize to JSON): ** pay attention to their comparison / equality operators (==, ===, <=>, etc) ** make them able to import & export a more primitive version of themselves (eg. #to_json) for easier testing * write custom matchers to make your unit tests beautiful. Use these in your cuke step definitions when it makes sense. * make your code as ugly as you must to make the specs beautiful (but no uglier). * if you decide to use a library, you own it, and you'll end up seeing it naked. Try to make sure it's not suffering from either obesity or gangrene well before this happens. If you can avoid using it entirely without making your specs worse or adding code, do. Now, much of this won't apply to most Rails projects. All of it is off the top of my head and to be taken with unhealthy quantities of salt. I just wanted to throw it out there and see what ideas / opinions other people have. so? -- cheers, David Lee -- You received this message because you are subscribed to the Google Groups "Ruby or Rails Oceania" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rails-oceania?hl=en.
