Testing Views and View Markup

Get started with view testing and learn how to plan and write view tests.

RSpec view testing

We’ve tested a helper for project status, but the new status DOM elements don’t show up when we go to the browser. This is because we haven’t placed our new helper in the view template itself. Naturally, we would like the dazzling two-line helper to be incorporated into the view. From a TDD perspective, we have the following few options:

  • Write no further tests. Insert the helper into the view template. Technically we’re not adding logic, so we can kind of squeak by with this one. We don’t mean to be glib here. Having no extra test may be the right choice when the test is expensive, trivial in the larger scheme of things, and easy to inspect visually.
  • Write an integration test using Capybara, as we saw in the chapters “Test-Driven Rails", and “Integration Testing with Capybara and Cucumber”.We may already have an integration test in place if we’ve been using outside-in development.
  • Write a Rails view test. This has the advantage of being somewhat faster than the integration test, and we may be able to piggyback it on existing controller tests.

Controller testing views

RSpec allows us to specify view tests independent of controllers. Though we can get views to run from controller tests, it’s not the default, and it’s not recommended. The RSpec convention is to place view tests in the spec/views folder, with one spec file to a view file, so the view in app/views/projects/index.html.erb is specified in spec/views/projects/index.html.erb_spec.rb.

Hard approach

We rarely write these tests. We find the file structure hard to maintain, and what logic we do have in views is often tested between objects like presenters and integration tests. In general, we find full TDD on views difficult. We often have to see a scratch implementation of a view before we know exactly what to test. They are surprisingly easy to write because they have no dependency on any other part of the code, and if we think of the ERB template as a function, they are basically unit tests for views. Let’s try one to get a better idea.

Test planning

Let’s take a second to plan this test. What does it need to do?

  • Given: We need just two projects, one that is on schedule and one that’s not. That allows us to verify both halves of the helper. The projects we create need to be visible to the controller method, meaning we either need to put the data in the database or do some clever mocking. Fixtures could be used too, but we don’t want to create fixtures because we don’t want this project data to be global. Let’s start with the database, it’s simpler for the moment.

  • When: We need to hit the index action of the controller.

  • Then: Our on-schedule project has the on-schedule DOM class, and the behind-schedule class has the behind-schedule one.

In code, that becomes the following:

Get hands-on with 1400+ tech skills courses.