Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Exercise boundary conditions, error handling, and varying inputs at the unit or functional level.

Integration specs tests should demonstrate user-visible system behavior.

Remember that integration tests run much more slowly than unit tests, so prefer to test more thoroughly at the unit level.

Integration tests should be placed in the "spec/features/" folder. All other tests should go in the default locations generated by Rails (e.g. "spec/models/")

Build meaningful sentences with

...

Jest blocks.

The chain of RSpec Jest "describe" and " context" blocks leading up to the final "ittest" block should form a human-readable sentence. This is particularly true for integration specs where we are documenting system behavior spec names.

Consider an example where we don't use this style.

Bad Example:

describe "('Account creation" do', () => {context "messages" dodescribe('messages', () => {it "test('should display success messages"', () => { … })
        it "test('should display failure messages"', () => { … })
      end})
      it "test('recovers passwords"', () => { … }
      it "test('should send emails to users"', () => { … }
    end})

Consider the sentences produced by the above:

  1. Account creation messages should display success messages.
  2. Account creation messages should display failure messages.
  3. Account creation recovers passwords.
  4. Account creation should send emails to users.

The spec test fails to describe the system. Reading the sentences, we don't know why a particular behavior might happen. Some of the sentences don't entirely make sense.

We fix the problem by using more descriptive contexts and paying attention to the sentences we're constructing with our specstests.

Improved Example:

describe ("Account creation" do
      …
      context "describe('for users providing valid information" do', () => {
        it "test('displays a success message"', () => { … }
        it "test('sends an email to the user"', () => { … }
      end})
      context "describe('for users providing duplicate user names" do', () => {
        it "test('displays an informative error message"', () => { … }
        it "test('prompts users to recover their passwords"', () => { … }
      end})
    end})

Consider the sentences produced by the above:

...

  1. Test varying inputs and edge cases at the unit or functional level, rather than the integration level.
  2. Avoid running integration tests with Javascript enabled unless Javascript is necessary for the feature under test.
  3. Avoid calling external services, particularly ones which cannot be run in a local environment. Use mocks for these services.
  4. Avoid loading external images, CSS, and Javascript in integration tests.
  5. Avoid or disable interactions and interface elements that will cause Capybara to wait. For instance, disable animations or transitions.
  6. Skip to the page under test in integration tests, there is no need to start at the home page for every spec test (though you should have a spec test which verifies you can start at the home page).
  7. Avoid increasing timeouts to fix intermittent problems. Find other means.
  8. Time your tests.
  9. Follow this style guide for performant HTML, CSS, and Javascript.

...

If you see a failure and you suspect it was caused by some intermittent problem, e.g. a timeout that is too short or an external service being down, it is not enough to simply re-run the tests. Fix the problem. If a problem truly cannot be fixed, document why, catch the specific error that cannot be fixed, and throw a more meaningful one.

Exercise all CSS, HTML components, Rails partials, and Rails helpers in

the Pattern Portfolio

Factor non-trivial HTML into partials and helpers and demonstrate its use in the Pattern Portfolio. This allows other developers to find and reuse partials and ensure that new code does not break existing code.

Display Javascript components in the Pattern Portfolio

Catalog custom Javascript components in the Pattern Portfolio. Show examples of configuration options, if appropriate.

Test Javascript components using Jasmine in offline pages

Create offline pages, similar to the Pattern Portfolio, to exercise Javascript components in their various states. Avoid requiring a running application instance or performing server communication in Jasmine specs.

Integration specs should still perform simple checks on Javascript components, but the bulk of Javascript testing should be performed offline.

HTML and ERB

Demonstrate markup patterns in the Pattern Portfolio.

...