Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to add tests to an existing Rails project?

I have a Rails project which I neglected to build tests for (for shame!) and the code base has gotten pretty large. A friend of mine said that RSpec was a pain to use unless you use it from the beginning. Is this true? What would make him say that?

So, considering the available tests suites and the fact that the code base is already there, what would be my best course of action for getting this thing testable? Is it really that much different than doing it from the beginning?

like image 228
Zach Avatar asked Sep 21 '08 16:09

Zach


People also ask

What type of test is not typical in a rails application?

Don't write route tests, except if you're writing an API, for the endpoints not already covered by integration tests. Don't write view tests. You should be able to change copy or HTML classes without breaking your tests. Just assess critical view elements as part of your in-browser integration tests.

What are integration tests rails?

While unit tests make sure that individual parts of your application work, integration tests are used to test that different parts of your application work together.


2 Answers

This question came up recently on the RSpec mailing list, and the advice we generally gave was:

  • Don't bother trying to retro-fit specs to existing, working, code unless you're going to change it - it's exhausting and, unless the code needs to be changed, rather pointless.
  • Start writing specs for any changes you make from now on. Bug fixes are an especially good opportunity for this.
  • Try to train yourself into the discipline that before you touch the code, first of all write a failing example (=spec) to drive out the change.

You may find that the design of code which wasn't driven out by code examples or unit tests makes it awkward to write tests or specs for. This is perhaps what your friend was alluding to. You will almost certainly need to learn a few key refactoring techniques to break up dependencies so that you can exercise each class in isolation from your specs. Michael Feathers' excellent book, Working Effectively With Legacy Code has some great material to help you learn this delicate skill.

I'd also encourage you to use the built-in spec:rcov rake task to generate code coverage stats. It's extremely rewarding to watch these numbers go up as you start to get your codebase under test.

like image 122
mattwynne Avatar answered Sep 22 '22 19:09

mattwynne


Maybe start with the models? They should be testable in isolation, which ought to make them the lowest-hanging fruit.

Then pick a model and start writing tests that say what it does. As you go along, think about other ways to test the code - are there edge cases that maybe you're not sure about? Write the tests and see how the model behaves. As you develop the tests, you may see areas in the code that aren't as clean and de-duplicated (DRY) as they might be. Now you have tests, you can refactor the code, since you know that you're not affecting behaviour. Try not to start improving design until you have tests in place - that way lies madness.

Once you have the models pinned down, move up.

That's one way. Alternatives might be starting with views or controllers, but you may find it easier to start with end-to-end transaction tests andwork your way into smaller and smaller pieces as you go along.

like image 29
Mike Woodhouse Avatar answered Sep 21 '22 19:09

Mike Woodhouse