Some question on good practices/assumptions

There are a number of testing terms, such as “integration,” “functional,” “acceptance,” “component,” and “system” that are not used consistently throughout the programming community. It’s difficult to figure out who coined most of these terms, and it’s even harder to prove that there’s a canonical definition.

I don’t find it useful to attempt to sort tests into strict categories; however, I do find it useful to use a variety of tools and angles to test applications.

The style used to test something ranges from completely integrated to completely isolated. Most tests don’t touch either extreme; they just trend towards one pole or another.

In general, as your tests become more integrated, meaning that they test more components working together in a realistic fashion:

  • They will make your production code more bug-free.
  • They will be easier to write.
  • They will run slower.
  • They will be harder to maintain.
  • They will not improve your production code.

In general, as your tests become more isolated, meaning that they test fewer components more directly:

  • They will make your production code easier to write.
  • They will improve the design of your individual components.
  • They will run faster.
  • They will be easier to maintain.
  • They will not be effective at catching regressions.
  • They will be harder to write.

As a tool, capybara can’t really be used to write unit tests. It requires a rack application, and it will be easiest to use when most of your components are actually working together. This is because it’s entirely UI-driven. Given that, we favor integration-style tests with capybara.

The rest of our tests usually trend more towards isolation, but some could be regarded as “component tests,” because:

  • They frequently leave the database unstubbed, particularly for model tests.
  • They usually don’t stub out or inject all of their collaborators. For example, our controller and view tests generally use actual model instances rather than pure stubs.

In summary:

We try to write a few, high-level tests using capybara from the perspective of many components working together, which we call integration tests. We use these to determine which components are necessary for high level requirements and to prevent regressions.

We write a lot of low-level unit tests testing as few components as possible, which we call uint tests. We use these to fuel our TDD process, improve the design of our code, and provide a reasonably fast test suite which will catch most major mistakes.

4 Likes