So, I’ve been working on a project for my new workplace, and because of all the dependencies (which are all necessary - I checked), the test suite itself takes 6-7 seconds just to boot up.
My normal workflow on smaller projects is to have guard running, and then use TDD to drive the design of the application. This works pretty well, because on a smaller application, it only takes 1 second or so to run the test file.
However, when working with this current application - it’s taking 6-7 seconds between each save - which deters me from doing true TDD (I end up doing Test First Design instead - which isn’t the goal).
I realize that the issue of speed is because of including test_helper (or spec_helper), which include the Rails stack and the application’s dependencies.
So - all in all, I guess my question is:
What is the best way to create fast tests when needing to test classes that are dependent on Objects that inherit from ActiveRecord?
Ex:
Models with Associations
Service classes that use ActiveRecord Objects
Is that just the pain of testing Rails Models? Or should I be pulling out all business logic into Modules/Classes?
Those classes that are services, should I just be injecting the ActiveRecord object into the initialize function - so that I can send in a stub within the test?
I’ve been using Spring as well, and it’s generally pretty simple to set up and run. I recommend adding a line to your spec_helper to reload spring whenever you edit a factory, as Spring won’t track factory changes automatically.
Having the test environment pre-loaded is 80% of the battle. The other two things to do if your test suite isn’t running fast that I would use the --profile option to find your slowest running specs. Sometimes one feature spec can be responsible for a huge portion of your suite’s slowness.
The other thing I try to do to keep suites fast is to access the database as little as possible. Don’t use create when build or new will do. Unless your test relies on associations, you should be able to avoid the DB in most cases.
With Spring in use, I think the effort to employ workarounds like having an ActiveRecord-less spec helper are overkill and of extremely limited marginal value.
I’ve added spring to the project, and things are much faster - thanks, @benorenstein !
One thing I’ve noticed with spring though (at least, in collaboration with guard), is that it’s finicky with some initializers (ex: an internal engine that is setting some defaults, redis and resque.
As such - there are some tests that are not intermittently failing that pass find when just running rake test:all.
You can add the initializers folder to the list of things that Spring watches (I do this with factories), and Spring will restart whenever you edit an initializer.
The crazy thing - is that none of the initializers are being edited when this is happening. It just happens off the bat, and continues as I continue to run tests via guard.