Friday, November 8, 2024
HomeRuby On RailsWhy Write Rails View Assessments

Why Write Rails View Assessments



Window cleaners in Lisboa, Portugal

There are a lot of methods to check a Ruby on Rails software, however there may be one
method that’s not so typically mentioned. That’s the method of testing Rails views.
Sure – there are controller, mannequin, and different sorts of assessments, however we not often see
the view layer assessments. Let’s give them extra consideration and see what they’re all
about.

You may ask – properly, why don’t you write integration assessments and take a look at view layer
with them? I may, however working integration assessments may be gradual, and writing a
easy view ‘unit’ take a look at may be extra simple. Plus, RSpec has nice assist for
writing a view spec. What’s much more attention-grabbing, I created
an instance venture to check these out. Let’s see what I came upon.

New Mission, Who This

I created new Rails 6.1 venture, put in RSpec, and generated the E-book mannequin with:

bin/rails generate scaffold E-book title:string description:textual content download_url:string standing:string

And have a look at what I acquired generated:

...

    create      spec/views/books/edit.html.erb_spec.rb
    create      spec/views/books/index.html.erb_spec.rb
    create      spec/views/books/new.html.erb_spec.rb
    create      spec/views/books/present.html.erb_spec.rb

...

If we check out one of many specs, we will discover the next code:



require 'rails_helper'

RSpec.describe "books/index", sort: :view do
  earlier than(:every) do
    assign(:books, [
      Book.create!(
        title: "Title",
        description: "MyText",
        download_url: "Download Url",
        status: "Status"
      ),
      Book.create!(
        title: "Title",
        description: "MyText",
        download_url: "Download Url",
        status: "Status"
      )
    ])
  finish

  it "renders an inventory of books" do
    render
    assert_select "tr>td", textual content: "Title".to_s, depend: 2
    assert_select "tr>td", textual content: "MyText".to_s, depend: 2
    assert_select "tr>td", textual content: "Obtain Url".to_s, depend: 2
    assert_select "tr>td", textual content: "Standing".to_s, depend: 2
  finish
finish

There’s the sort: view that signifies the particular sort of specs. We’ll go
into this later a bit. You may distinguish assign and render strategies that
point out that they’re outlined internally and never one thing we must always
present. However, there may be additionally one factor sticking into my eyes as I’m going by way of
this take a look at.

What’s attention-grabbing right here, this assert_select matcher appears to be like a bit “deprecated”
or like it isn’t from the RSpec world. There’s no class count on(...).to
formation. What occurred right here is that the template for producing these specs
acquired a bit dusty. It didn’t change from 2010, when it was initially pushed to
the repo. Yow will discover the commit that introduced the assert_select
right here on GitHub.

No worries, I didn’t see many initiatives utilizing view specs, not to mention
producing fashions and counting on these generated view specs. I assume that’s
why no one took out the time to refactor or enhance the prevailing template. However,
since this weblog submit is about focusing our consideration on Rails view testing,
allow us to attempt to just do that.

Spring Cleansing

If we check out the docs for view specs in RSpec, we
can see that the majority of them use the next:

count on(rendered).to match /one thing/

We are able to use match and embody from RSpec. What we get is a take a look at that appears
like this:



require 'rails_helper'

RSpec.describe "books/index", sort: :view do
  earlier than(:every) do
    assign(:books, [
      Book.create!(
        title: "Rails Testing",
        description: "How to test Ruby on Rails applications.",
        download_url: nil,
        status: "draft"
      ),
      Book.create!(
        title: "Rails Patterns",
        description: "A book about patterns and anti-patterns in Ruby on Rails.",
        download_url: "rails-patterns.com/download",
        status: "published"
      )
    ])
  finish

  it "renders an inventory of books" do
    render

    count on(rendered).to match(/Rails Testing/)
    count on(rendered).to embody("Rails Patterns")

    count on(rendered).to match(/The best way to take a look at Ruby on Rails purposes./)
    count on(rendered).to embody("A guide about patterns and anti-patterns in Ruby on Rails.")

    count on(rendered).to embody("rails-patterns.com/obtain")

    count on(rendered).to embody("revealed")
  finish
finish

The earlier take a look at feels extra like a RSpec spec. However, we will discover is that we misplaced that
potential to verify whether or not the precise content material is inside a sure HTML tag.
assert_select offers us extra flexibility in matching the anticipated consequence.
There’s extra choices you may go to assert_select in
its docs.
I recommend you select the choice you are feeling offers you extra management.

Using Capybara

If in case you have Capybara put in, you may make the most of its selectors like so:

require "rails_helper"

RSpec.describe "books/index", sort: :view do
  earlier than(:every) do
    assign(:books, [
      Book.create!(
        title: "Rails Testing",
        description: "How to test Ruby on Rails applications.",
        download_url: nil,
        status: "draft"
      ),
      Book.create!(
        title: "Rails Patterns",
        description: "A book about patterns and anti-patterns in Ruby on Rails.",
        download_url: "rails-patterns.com/download",
        status: "published"
      )
    ])
  finish

  it "renders an inventory of books" do
    render

    count on(rendered).to have_selector("tr>td", textual content: "Rails Testing")
    count on(rendered).to have_selector("tr>td", textual content: "Rails Patterns")

    count on(rendered).to have_selector("tr>td", textual content: "The best way to take a look at Ruby on Rails purposes")
    count on(rendered).to have_selector("tr>td", textual content: "A guide about patterns and anti-patterns in Ruby on Rails.")

    count on(rendered).to have_selector("tr>td", textual content: "rails-patterns.com/obtain")

    count on(rendered).to have_selector("tr>td", textual content: "revealed")
  finish
finish

Now, you get each RSpec count on(...).to, and also you get the granularity of
asserting that textual content is inside a desk row. Yow will discover all the code and examples
within the repo right here. However why
would you utilize any of those? Let’s focus on under.

Why View Specs

We skimmed over a few the reason why you’ll write a view spec. The concept
is to check some conditional logic you’ve gotten in your views or partials. Writing
an integration take a look at that covers all of the branches inside your views may be gradual
to run and painful to jot down. The view specs deliver an amazing stability between:

  • 💸 value of growth,
  • 🏍 pace of execution, and
  • 🔀 conditional rendering protection.

In fact, you may not want view specs in any respect if in case you have decorators and think about
fashions, kind objects, and all different goodies that may transfer the logic out of the
view for you. However, typically, in the true world, not each code base is
completely designed, and you must minimize corners every now and then.

Whether or not it’s some sort of stakeholder respiration down your neck. Or it’s
the sophisticated legacy partial that may’t be so simply extracted to a design of
your selection. No matter the reason being, you may opt-in for the view spec to maneuver
quick and have the logic examined.

And when that day comes (or it already got here), you may resort again to this weblog
submit and use it to your liking.

When you appreciated the submit, you may share it on Twitter. Contemplate
subscribing to the e-newsletter to get new articles like this one.

Catch you within the subsequent one, cheers.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments