<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <link>http://persumi.com/u/fredwu/tech/e/blog/t/tests</link>
    <generator>Persumi - Level up your writing and blogging with AI</generator>
    <category>Blog</category>
    <category>Tech</category>
    <pubDate>Mon, 01 Jun 2026 03:11:02 +0000</pubDate>
    <description/>
    <title>Blog (tests) - Fred Wu&apos;s Tech</title>
    <atom:link type="application/rss+xml" rel="self" href="http://persumi.com/u/fredwu/tech/e/blog/t/tests/feed/rss"></atom:link>
    <item>
      <pubDate>Wed, 18 Sep 2013 06:50:00 +0000</pubDate>
      <guid>http://persumi.com/u/fredwu/tech/e/blog/p/protip-faster-ruby-tests-with-databasecleaner-and-databaserewinder</guid>
      <comments>http://persumi.com/u/fredwu/tech/e/blog/p/protip-faster-ruby-tests-with-databasecleaner-and-databaserewinder</comments>
      <category>Blog</category>
      <category>Tech</category>
      <author>ifredwu@gmail.com (Fred Wu)</author>
      <description>&lt;![CDATA[&lt;p&gt;
&lt;em&gt;Please also see &lt;a href=&quot;/blog/2013-09-06-protip-ruby-devs-please-tweak-your-gc-settings/&quot;&gt;this blog post on tweaking your ruby GC settings&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
I use and love &lt;a href=&quot;https://github.com/bmabey/database_cleaner&quot;&gt;DatabaseCleaner&lt;/a&gt;, although historically I had never paid too much attention on the performance of its varies cleaning strategies - I’d always used &lt;code class=&quot;inline&quot;&gt;truncation&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
We use Postgres, and after digging around and finding out &lt;a href=&quot;http://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886&quot;&gt;the difference between DELETE and TRUNCATE&lt;/a&gt;, I ended up improving our test suite speed by about 30-40% simply by tweaking the cleaning strategies.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;RSpec.configure do |config|
  config.before :suite do
    DatabaseCleaner.clean_with :truncation
    DatabaseCleaner.strategy = :transaction
  end

  config.before do
    if example.metadata[:js] || example.metadata[:type] == :feature
      DatabaseCleaner.strategy = :deletion
    else
      DatabaseCleaner.strategy = :transaction
      DatabaseCleaner.start
    end
  end

  config.after do
    DatabaseCleaner.clean
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Essentially, we want to &lt;code class=&quot;inline&quot;&gt;truncate&lt;/code&gt; the DB only once before the whole suite runs to ensure a clean slate DB, then we only want to use &lt;code class=&quot;inline&quot;&gt;deletion&lt;/code&gt; on Capybara tests, everything else should just use &lt;code class=&quot;inline&quot;&gt;transaction&lt;/code&gt; which is the fastest strategy.&lt;/p&gt;
&lt;p&gt;
Now, as a bonus, I have just discovered @amatsuda’s &lt;a href=&quot;https://github.com/amatsuda/database_rewinder&quot;&gt;DatabaseRewinder&lt;/a&gt; which is a lightweight alternative that supports only ActiveRecord. It offers comparable performance with a much similar API.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;RSpec.configure do |config|
  config.before :suite do
    DatabaseRewinder.clean_all
  end

  config.after do
    DatabaseRewinder.clean
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
By the way, we also use &lt;a href=&quot;https://github.com/grosser/parallel_tests&quot;&gt;parallel_tests&lt;/a&gt; to scale our test suite to multiple processes, even on Travis CI and Wercker.&lt;/p&gt;
&lt;p&gt;
Hooray to faster tests! :)&lt;/p&gt;
]]&gt;</description>
      <link>http://persumi.com/u/fredwu/tech/e/blog/p/protip-faster-ruby-tests-with-databasecleaner-and-databaserewinder</link>
      <title>Protip: Faster Ruby Tests with DatabaseCleaner and DatabaseRewinder</title>
    </item>
    <item>
      <pubDate>Fri, 06 Sep 2013 11:13:37 +0000</pubDate>
      <guid>http://persumi.com/u/fredwu/tech/e/blog/p/protip-ruby-devs-please-tweak-your-gc-settings-for-tests</guid>
      <comments>http://persumi.com/u/fredwu/tech/e/blog/p/protip-ruby-devs-please-tweak-your-gc-settings-for-tests</comments>
      <category>Blog</category>
      <category>Tech</category>
      <author>ifredwu@gmail.com (Fred Wu)</author>
      <description>&lt;![CDATA[&lt;p&gt;
It was made apparent to me that many ruby devs either aren’t aware or couldn’t be bothered to tweak their ruby garbage collector settings.&lt;/p&gt;
&lt;p&gt;
Well, if you are using MRI, please start tweaking your GC settings. Here’s what I use (on my 15” Macbook Pro Retina):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;shell language-shell&quot;&gt;export RUBY_GC_MALLOC_LIMIT=90000000
export RUBY_FREE_MIN=200000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Not only can you tweak it for your local dev machine, you can also tweak Jenkins, &lt;a href=&quot;http://travis-ci.com/&quot;&gt;Travis CI&lt;/a&gt;, &lt;a href=&quot;http://wercker.com/&quot;&gt;Wercker&lt;/a&gt; and other CI solutions, making instant speed gain for your test suite!&lt;/p&gt;
&lt;p&gt;
Here’s what we get:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;shell language-shell&quot;&gt;            Before After
Local:      8m22s 5m52s
Travis CI:  10m10s 6m0s
Wercker:    8m45s 6m24s&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
YMMV depending on your system and available RAM.&lt;/p&gt;
]]&gt;</description>
      <link>http://persumi.com/u/fredwu/tech/e/blog/p/protip-ruby-devs-please-tweak-your-gc-settings-for-tests</link>
      <title>Protip: Ruby Devs, Please Tweak Your GC Settings for Tests!</title>
    </item>
    <item>
      <pubDate>Mon, 26 Aug 2013 14:11:00 +0000</pubDate>
      <guid>http://persumi.com/u/fredwu/tech/e/blog/p/writing-sensible-tests-for-happiness</guid>
      <comments>http://persumi.com/u/fredwu/tech/e/blog/p/writing-sensible-tests-for-happiness</comments>
      <category>Blog</category>
      <category>Tech</category>
      <author>ifredwu@gmail.com (Fred Wu)</author>
      <description>&lt;![CDATA[&lt;p&gt;
Writing good, sensible tests is hard. As a Rubyist, I feel lucky to be part of a community that embraces tests. Though at the same time, I have come across too many projects that suffered from not having sensible tests.&lt;/p&gt;
&lt;h2&gt;
What are Sensible Tests?&lt;/h2&gt;
&lt;p&gt;
There often isn’t a silver bullet when it comes to software development. Technical stuff aside, many things contribute to the solution to a given problem - the team, the project and the business to name a few. This article does not attempt to present any insights into &lt;em&gt;the&lt;/em&gt; best practices for testing, rather it collects a few tips I believe would benefit those who are not yet comfortable with writing tests.&lt;/p&gt;
&lt;p&gt;
To me, sensible tests often have the following characteristics:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
it does not replicate implementation details;  &lt;/li&gt;
  &lt;li&gt;
it does not provide false sense of security;  &lt;/li&gt;
  &lt;li&gt;
it runs reasonably quickly;  &lt;/li&gt;
  &lt;li&gt;
it does not slow down the development significantly;  &lt;/li&gt;
  &lt;li&gt;
it guides the programmer towards a better architecture;  &lt;/li&gt;
  &lt;li&gt;
and, it does not make you &lt;em&gt;sigh&lt;/em&gt; every time you want to modify your tests.  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Art and Science, TDD or Not TDD&lt;/h2&gt;
&lt;p&gt;
Just like writing production code, writing tests is also a combined form of art and science. It takes not only &lt;em&gt;experience&lt;/em&gt;, but also &lt;em&gt;intuition&lt;/em&gt; to write sensible tests. You have to remember that not all projects and programmers are equal - &lt;strong&gt;take what you get, practise, and reflect on your findings&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
Many times I had come across seasoned programmers practising TDD, only to find themselves cornered into a bad design that ultimately had to be thrown away. TDD does not save you from writing bad code, this article is not about TDD, it’s about testing in general.&lt;/p&gt;
&lt;p&gt;
I am most comfortable with using RSpec, FactoryGirl, Capybara and Turnip, so I’m going to use these tools in the code. The principles however apply to any testing framework.&lt;/p&gt;
&lt;h2&gt;
Test as Little as Possible to Reach a Given Level of Confidence&lt;/h2&gt;
&lt;p&gt;
Kent Beck, the inventor (or more correctly, ‘rediscoverer’) of TDD &lt;a href=&quot;http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565&quot;&gt;once said&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I used to prefer testing almost everything, but over the recent years I find myself increasingly &lt;strong&gt;look for key areas of the system that need the test coverage the most&lt;/strong&gt;. Typically, our systems would have:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
unit and functional tests for model behaviours  &lt;/li&gt;
  &lt;li&gt;
unit and functional tests for services  &lt;/li&gt;
  &lt;li&gt;
integration tests for controller actions  &lt;/li&gt;
  &lt;li&gt;
request tests for API endpoints  &lt;/li&gt;
  &lt;li&gt;
isolated JavaScript tests  &lt;/li&gt;
  &lt;li&gt;
high level integration/acceptance tests in Gherkin  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Model and service level tests are arguably the most important ones so we make sure we have really good test coverage for those. For controller tests we rely heavily on reusable production &lt;em&gt;and&lt;/em&gt; test code for maintainability and sanity. For API endpoints we mostly test presented data structure - as business logic and data integrity should have been covered in model, service and controller layers. Isolated JavaScript tests take care of both presentational business logic and tricky UI tasks. And finally, acceptance tests handle happy-path user interactions.&lt;/p&gt;
&lt;h2&gt;
Do Not Test Framework and Library Code&lt;/h2&gt;
&lt;p&gt;
Writing application-specific business logic is difficult enough, you really should not test functionalities provided by the framework or libraries. Below is an example of such bad tests:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  it { should belong_to(:approval) }
  it { should_not validate_presence_of(:approval) }
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Similarly to how you would add useful comments, i.e. describe &lt;em&gt;why&lt;/em&gt; instead of &lt;em&gt;what&lt;/em&gt;, these tests should be replaced by tests that cover actual functionalities, for instance the reason why an &lt;code class=&quot;inline&quot;&gt;ApprovalStakeholder&lt;/code&gt; doesn’t need an &lt;code class=&quot;inline&quot;&gt;Approval&lt;/code&gt; to be presence should be demonstrated in the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;shared_examples_for &quot;non-approval specific stakeholder&quot; do
  its(:action_that_does_not_care_about_approval) { should be_true }
end

describe ApprovalStakeholder do
  let(:approval) { create(:approval) }
  let(:user) { create(:user) }
  let(:role) { create(:role) }

  subject do
    build(:approval_stakeholder,
      :user_id =&gt; user.id,
      :role_id =&gt; role.id
    )
  end

  context &quot;with an approval&quot; do
    before { subject.approval = approval }

    it_behaves_like &quot;non-approval specific stakeholder&quot;

    its(:action_that_does_care_about_approval) { should be_true }
  end

  context &quot;without an approval&quot; do
    it_behaves_like &quot;non-approval specific stakeholder&quot;

    its(:action_that_does_care_about_approval) { should be_false }
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Ensure What You are Testing Makes Sense&lt;/h2&gt;
&lt;p&gt;
The test case below showcases the original developer’s lack of attention and awareness on designing a functional and secure system. It actually tests the reference keys for the &lt;code class=&quot;inline&quot;&gt;ApprovalStakeholder&lt;/code&gt; object are allowed to be mass assignable, which is a recipe for disaster.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  it { should allow_mass_assignment_of(:user_id) }
  it { should allow_mass_assignment_of(:role_id) }
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
De-Duplicate Test Cases&lt;/h2&gt;
&lt;p&gt;
Looking at the example below, the first thing you’d notice is the amount of duplication.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  it &quot;#traveller&quot; do
    stakeholder = create(:approval_stakeholder,
      :approval =&gt; approval,
      :user_id =&gt; traveller.id
    )
    stakeholder.stub(:user).and_return(traveller)
    approval.stub(:stakeholders_as).and_return([stakeholder])

    approval.traveller.should == traveller
  end

  it &quot;#authoriser&quot; do
    stakeholder = create(:approval_stakeholder,
      :approval =&gt; approval,
      :user_id =&gt; authoriser.id
    )
    stakeholder.stub(:user).and_return(authoriser)
    approval.stub(:stakeholders_as).and_return([stakeholder])

    approval.authoriser.should == authoriser
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
It’s true that tests act as a form of specification therefore should be optimised for clarity, in this case however, we could still maintain the clarity with significantly reduced duplication:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  let(:stakeholder) do
    create(:approval_stakeholder,
      :approval =&gt; approval,
      :user_id =&gt; user.id
    )
  end

  subject { approval }

  before do
    stakeholder.stub(:user).and_return(user)
    approval.stub(:stakeholders_as).and_return([stakeholder])
  end

  describe &quot;#traveller&quot; do
    let(:user) { traveller }

    its(:traveller) { should == traveller }
  end

  describe &quot;#authoriser&quot; do
    let(:user) { authoriser }

    its(:authoriser) { should == authoriser }
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Do Not Replicate Implementation Details&lt;/h2&gt;
&lt;p&gt;
I am often surprised to see many seasoned developers “enjoy” writing tests that essentially replicate the production code logic without much benefit. See below:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  it &quot;references a user&quot; do
    approval_stakeholder = build :approval_stakeholder, :user_id =&gt; 1
    User.should_receive(:find).with(1)
    approval_stakeholder.user
  end

  it &quot;references a role&quot; do
    approval_stakeholder = build :approval_stakeholder, :role_id =&gt; 1
    Role.should_receive(:find).with(1)
    approval_stakeholder.role
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Rather than creating noisy tests, tests with actual assertions seem much more meaningful and readable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe ApprovalStakeholder do
  subject do
    build(:approval_stakeholder,
      :approval =&gt; approval,
      :user_id =&gt; user.id,
      :role_id =&gt; role.id,
    )
  end

  its(:name) { should == &quot;#{user.first_name} #{user.last_name}&quot; }
  its(:role_name) { should == role.name }
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Reduce the Reliance on Mocks and Stubs&lt;/h2&gt;
&lt;p&gt;
This is a difficult and often-debated subject. In my experience, having too many mocks and stubs even though speeds up the test suite, usually leaves too many holes in your tests and makes the test suite less accurate and effective. Fortunately, by using more service objects (described below), mocking and stubbing become more manageable as you use them mostly on external objects and interfaces.&lt;/p&gt;
&lt;h2&gt;
Take Apart the System, One Service at a Time&lt;/h2&gt;
&lt;p&gt;
If you’re a Rails developer, you are already familiar with MVC. But just relying on MVC to hold your application architecture is probably not going to be sufficient for an average modern day web application. Many people like &lt;a href=&quot;http://en.wikipedia.org/wiki/Service-oriented_architecture&quot;&gt;Service-oriented architecture&lt;/a&gt;, so do I.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
Services are unassociated, loosely coupled units of functionality that are self-contained.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
In my experience, as long as you are disciplined in having services do one and only one thing really well, testing becomes much easier.&lt;/p&gt;
&lt;p&gt;
For instance, we have a &lt;code class=&quot;inline&quot;&gt;Bouncer&lt;/code&gt; service that is responsible for safeguarding resources - ensuring read-only attributes don’t get overridden.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;module Services
  class Bouncer
    def self.guard(resource, options = {})
      if options[:existing_resource]
        resource.readonly_attributes.each do |attr_name|
          resource.send(&quot;#{attr_name}=&quot;, options[:existing_resource].send(attr_name))
        end
      end

      resource
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
The corresponding tests for this service are both fast and self-contained:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe Services::Bouncer do
  class BouncerDude
    include Mos::Entity

    set_readonly_attributes :age, :gender

    attribute :name
    attribute :age
    attribute :gender
  end

  let(:resource) { BouncerDude.new(name: &apos;Penny&apos;, age: 28, gender: &apos;female&apos;) }
  let(:existing_resource) { BouncerDude.new(name: &apos;Sheldon Cooper&apos;, age: 34, gender: &apos;male&apos;) }
  subject { Services::Bouncer.guard(resource, existing_resource: existing_resource) }

  describe &quot;#guard&quot; do
    its(:name) { should == &apos;Penny&apos; }
    its(:age) { should == 34 }
    its(:gender) { should == &apos;male&apos; }
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Recognise Common Patterns and Refactor Them into Services&lt;/h2&gt;
&lt;p&gt;
One of the reasons why service-oriented architecture is so popular is because things are broken down into smaller, more manageable and more testable pieces. It is especially helpful for TDD practitioners as it significantly reduces the amount of coupling between your production code and your tests due to having simpler internals per test subject.&lt;/p&gt;
&lt;p&gt;
Take a look at the below example, which is hard to read, hard to test and error-prone:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;module ApplicationHelper
  def branch_logo_options(branch)
    BranchLogo.where(branch_id: branch.id).map { |logo| [logo.file, logo.id] }
  end

  def branch_options(agency)
    BranchRepository.find(agency_id: agency.id, archived: false).map do |b|
      [b.name, b.id]
    end
  end

  def agency_user_options(agency, filtered_users)
    filtered_user_ids = filtered_users.compact.map(&amp;:id) || []
    AgencyUserRepository.find(agency_id: agency.id, archived: false).select do |u|
      !filtered_user_ids.include?(u.id)
    end.map { |u| [u.full_name, u.id] }
  end

  def current_agency_user_options(filtered_users = [])
    agency_user_options(current_agency, filtered_users)
  end

  def current_agency_trust_bank_account_options
    BankAccountRepository.find(
      agency_id: current_agency.id,
      archived: false,
      account_type: BankAccount::TRUST_ACCOUNT).map do |b|
      [b.account_name, b.id]
    end
  end

  def code_options_for(klass)
    klass.all.map { |cc| [&quot;#{cc.code} - #{cc.name}&quot;, cc.id] }.sort
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Let’s refactor it into something more manageable, by introducing a service &lt;code class=&quot;inline&quot;&gt;ShowGirl&lt;/code&gt; for fetching and presenting data collections:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;module CollectionOptionsHelper
  def branch_logo_options(branch)
    Services::ShowGirl.present(branch, from: BranchLogo, show: :file)
  end

  def branch_options
    Services::ShowGirl.present(current_agency, from: BranchRepository)
  end

  def consultant_options(excluded_users = [])
    Services::ShowGirl.present(
      current_agency,
      from: AgencyUserRepository,
      show: :full_name
    ) do |collection|
      collection.reject { |user| user.id.in?(Array.wrap(excluded_users).map(&amp;:id)) }
    end
  end

  def trust_bank_account_options
    Services::ShowGirl.present(
      current_agency,
      from: BankAccountRepository,
      show: :account_name,
      filters: { account_type: BankAccount::TRUST_ACCOUNT },
    )
  end

  def code_options_for(name)
    Services::ShowGirl.present(
      current_agency,
      from: Admin::Configurations::Essential.descendants.find { |d| d.name =~ /::#{name.to_s.classify}/ },
      show: -&gt; (item) { &quot;#{item.code} - #{item.name}&quot; }
    )
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Better yet, we can clean it up even further by introducing another service, &lt;code class=&quot;inline&quot;&gt;BusBoy&lt;/code&gt; for just serving the data, and leaving &lt;code class=&quot;inline&quot;&gt;ShowGirl&lt;/code&gt; for only presenting the data:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;module CollectionOptionsHelper
  def branch_logo_options(branch)
    Services::ShowGirl.present(
      Services::BusBoy.serve(:branch_logos, branch: branch)
    )
  end

  def branch_options
    Services::ShowGirl.present(
      Services::BusBoy.serve(:branches, agency: current_agency)
    )
  end

  def consultant_options(excluded_users = [])
    Services::ShowGirl.present(
      Services::BusBoy.serve(:consultants, agency: current_agency),
      show: :full_name
    ) do |collection|
      collection.reject { |user| user.id.in?(Array.wrap(excluded_users).map(&amp;:id)) }
    end
  end

  def trust_bank_account_options(account_type)
    Services::ShowGirl.present(
      Services::BusBoy.serve(:bank_accounts,
        { agency: current_agency, BankAccount::TRUST_ACCOUNT }
      ),
      show: :account_name
    )
  end

  def code_options_for(name, options = {})
    Services::ShowGirl.present(
      Services::BusBoy.serve(name, agency: current_agency), options
    )
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Basic Controller CRUD Actions&lt;/h2&gt;
&lt;p&gt;
In one of our projects we have lots and lots of forms. Consequently we have lots and lots of CRUD actions. In order to keep our sanity as well as to make basic CRUD controllers maintainable, we have a custom DSL to make CRUD actions portable and testable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;module Profiles
  class TravellersController &lt; BaseController
    authorize_resource class: Traveller

    datamappify_resources entity: Traveller,
                          repository: TravellerRepository,
                          filter_by: :agency_id,
                          filter_value: -&gt; { current_user.agency_id }
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Most of our controller tests look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;require &apos;spec_helper&apos;

describe Profiles::AccountsController do
  let(:existing_resources) { [] }
  let(:create_resource) { Mos::Data.create_account }
  let(:create_resources) { Mos::Data.create_accounts(2) }
  let(:a_resource) { assigns(:resource) }
  let(:invalid_param) { { name: &apos;&apos; } }
  let(:params_key) { :account }
  let(:redirect_path) { profiles_accounts_path }

  it_behaves_like &apos;datamappify resources controller&apos;
  it_behaves_like &apos;searchable resources controller&apos;, :name,
                                                      :profile_id,
                                                      :branch_id,
                                                      :activated

  describe &quot;permission&quot; do
    context &apos;as a manager&apos; do
      before do
        sign_in_as :manager
      end

      it_behaves_like &apos;with write access&apos;
      it_behaves_like &apos;with read access&apos;
      it_behaves_like &apos;with index access&apos;
    end

    context &apos;as a consultant&apos; do
      before do
        sign_in_as :consultant
      end

      it_behaves_like &apos;without write access&apos;
      it_behaves_like &apos;with read access&apos;
      it_behaves_like &apos;with index access&apos;
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
API Endpoint Tests&lt;/h2&gt;
&lt;p&gt;
One of our projects at work is an API service that is essential to our platform. Naturally, we not only need to test the models, services and controllers, we also need to ensure the API endpoints do what they are supposed to do - mostly exposing the correct data structure.&lt;/p&gt;
&lt;p&gt;
During the early stage of the development, I had come up with &lt;a href=&quot;https://github.com/fredwu/api_taster&quot;&gt;ApiTaster&lt;/a&gt; - a super useful gem for visually testing our Rails application’s APIs. Later on, as we continued to grow our API endpoints, we started utilising ApiTaster for our automated test suite too.&lt;/p&gt;
&lt;p&gt;
In essence, we have one API spec file responsible for describing which endpoints are tested and missed according to the information given by ApiTaster:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;describe &quot;API&quot; do
  load &apos;db/seeds.rb&apos;
  load &apos;spec/api_endpoints.rb&apos;

  ApiTaster::Route.map_routes

  ApiTaster::Route.defined_definitions.each do |route|
    it &quot;api endpoint #{route[:verb]} #{route[:path]}&quot; do
      params = ApiTaster::Route.params_for(route).first
      expectation = ApiTaster::Route.metadata_for(route)[:expectation]
      setup = ApiTaster::Route.metadata_for(route)[:setup]
      verb = route[:verb].downcase
      path = parse_path_with_url_params(route[:path], params[:url_params])

      setup.call if setup

      send verb, path, params[:post_params]

      response.body.should match_json_expression(expectation)
    end
  end

  # warn about undefined definitions
  ApiTaster::Route.missing_definitions.each do |route|
    pending &quot;api endpoint #{route[:verb]} #{route[:path]}&quot;
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Then, we have a bunch of endpoint test files to do the actual testing, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby language-ruby&quot;&gt;resource_response = ResponseHash[
  :response =&gt; {
    :id =&gt; Integer,
    :name =&gt; String,
    :token =&gt; String
  }
]

get &apos;/:version/company&apos;, {}, {
  :expectation =&gt; resource_response
}

post &apos;/:version/companies&apos;, {
  :model =&gt; FactoryGirl.attributes_for(:company)
}, {
  :expectation =&gt; resource_response
}

put &apos;/:version/companies/:id&apos;, {
  :id =&gt; 1,
  :model =&gt; { :name =&gt; &apos;New Company&apos; }
}, {
  :expectation =&gt; resource_response.with(:name =&gt; &apos;New Company&apos;)
}

delete &apos;/:version/companies/:id&apos;, {
  :id =&gt; 1
}, {
  :expectation =&gt; resource_response
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Notice that for API endpoint tests we don’t test the business logic or data integrity - these should be tested in models, services and controllers. What we do test are correct endpoints are exposed, correct parameters are accepted and correct data structures are returned.&lt;/p&gt;
&lt;h2&gt;
Isolated JavaScript Tests&lt;/h2&gt;
&lt;p&gt;
Many developers prefer to rely on their integration test suite to do JavaScript / UI testing. This approach is fine until you start making lots of front-end changes and constantly need to pinpoint the relevant feature spec.&lt;/p&gt;
&lt;p&gt;
Having an isolated JavaScript test suite (which should be run as part of your continuous integration process) is extremely beneficial and often saves debugging time.&lt;/p&gt;
&lt;p&gt;
I like &lt;a href=&quot;https://github.com/visionmedia/mocha&quot;&gt;Mocha&lt;/a&gt; so we use &lt;a href=&quot;https://github.com/jfirebaugh/konacha&quot;&gt;Konacha&lt;/a&gt; in our Rails app. Though Mocha with &lt;a href=&quot;http://chaijs.com/&quot;&gt;Chai&lt;/a&gt; is really not that different to &lt;a href=&quot;https://github.com/pivotal/jasmine&quot;&gt;Jasmine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
Custom JavaScript behaviour is obviously a good candidate for isolated testing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;coffeescript language-coffeescript&quot;&gt;#= require spec_helper

describe &quot;form toggle&quot;, -&gt;
  beforeEach -&gt;
    $(&quot;body&quot;).append(JST[&quot;templates/form/toggle&quot;])

  it &quot;hides the collapsible field by default&quot;, -&gt;
    $(&quot;.control-group.branch_deactivation_date&quot;).hasClass(&apos;in&apos;).should.be.false

  it &quot;does not override if there is already a value&quot;, -&gt;
    value = $(&quot;input#agency_deactivation_date&quot;).val()
    $(&quot;input#agency_activated&quot;).click()
    $(&quot;input#agency_deactivation_date&quot;).val().should.equal(value)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Sometimes it’s also useful to ensure library code is initiated and triggered correctly, if you have other custom JS interact with it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;coffeescript language-coffeescript&quot;&gt;#= require spec_helper
#= require bootstrap-datepicker

describe &quot;form dates&quot;, -&gt;
  beforeEach -&gt;
    @dateFormat = &apos;DD/MM/YYYY&apos;
    $(&quot;body&quot;).append(JST[&quot;templates/form/dates&quot;](dateFormat: @dateFormat))

  it &quot;has a placeholder&quot;, -&gt;
    $(&quot;input&quot;).attr(&quot;placeholder&quot;).should.equal(@dateFormat)

  it &quot;defaults to today&apos;s date&quot;, -&gt;
    $(&quot;input#empty&quot;).focus()
    $(&quot;input#empty&quot;).focus()
    $(&quot;input#empty&quot;).val().should.equal(moment().format(@dateFormat))

  it &quot;does not override if there is already a value&quot;, -&gt;
    value = $(&quot;input#filled&quot;).val()
    $(&quot;input#filled&quot;).focus()
    $(&quot;input#filled&quot;).val().should.equal(value)&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
“Real” UI Tests&lt;/h2&gt;
&lt;p&gt;
Isolated JavaScript tests are super fast and useful. However, there are times when having pure JavaScript tests simply isn’t enough, due to the complicated nature of DOM interaction and template rendering.&lt;/p&gt;
&lt;p&gt;
A while ago our calendar widget was broken due to a production and UAT environment issue that was not picked up by our JavaScript test suite. Since then we started adding dedicated UI tests in our acceptance test suite (we use &lt;a href=&quot;https://github.com/jnicklas/turnip&quot;&gt;Turnip&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;gherkin language-gherkin&quot;&gt;@ui
Feature: UI
  Background:
    Given I am signed in
      And I go to agency consultants page
      And I click on &quot;Add New Consultant&quot;

  Scenario: Calendar
      When I click &quot;#agency_user_start_date&quot;
      And I click &quot;.day.active&quot; within &quot;.datepicker&quot;
      Then I should see today as part of the date field&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Effective Acceptance Tests&lt;/h2&gt;
&lt;p&gt;
Writing acceptance tests - also known to many Rubyists as “&lt;a href=&quot;https://github.com/cucumber/cucumber&quot;&gt;Cucumber&lt;/a&gt; tests”, is a double-edged sword - it’s extremely useful, but very few developers can write good, maintainable &lt;a href=&quot;https://github.com/cucumber/gherkin&quot;&gt;Gherkin&lt;/a&gt;-style acceptance tests.&lt;/p&gt;
&lt;p&gt;
Here’s an example of a badly written feature spec with too much implementation details and noise:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;gherkin language-gherkin&quot;&gt;Feature: Session
  Background:
    Given I visit &quot;/&quot;
      And there is a user &quot;admin&quot; &quot;password&quot;

  Scenario: Sign in with valid credentials
      When I fill in &quot;Username&quot; with &quot;admin&quot;
      And I fill in &quot;Password&quot; with &quot;password&quot;
      And I click &quot;Sign In&quot;
      Then I should be on &quot;/dashboard&quot;

  Scenario: Sign in with invalid credentials
      When I fill in &quot;Username&quot; with &quot;admin&quot;
      And I fill in &quot;Password&quot; with &quot;invalid_password&quot;
      And I click &quot;Sign In&quot;
      Then I should not be on &quot;/dashboard&quot;

  Scenario: Sign out
      When I fill in &quot;Username&quot; with &quot;admin&quot;
      And I fill in &quot;Password&quot; with &quot;password&quot;
      And I click &quot;Sign In&quot;
      And I click &quot;Sign Out&quot;
      Then I should be on &quot;/sign_in&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
A much cleaner version with only high level, descriptive steps:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;gherkin language-gherkin&quot;&gt;Feature: Session
  Background:
    Given I am on the homepage
      And there is a user &quot;admin&quot; with password &quot;password&quot;

  Scenario: Sign in with valid credentials
      When I sign in as &quot;admin&quot; with password &quot;password&quot;
      Then I should be signed in

  Scenario: Sign in with invalid credentials
      When I sign in as &quot;admin&quot; with password &quot;invalid_password&quot;
      Then I should not be signed in

  Scenario: Sign out
    Given I am signed in as &quot;admin&quot; with password &quot;password&quot;
      When I sign out
      Then I should be signed out&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Final Thoughts&lt;/h2&gt;
&lt;p&gt;
Writing good, sensible tests is hard. These examples and tips are by no means the silver bullet, and you might actually find some of them counter-intuitive in your particular situation. So again, take what you get, practise, and reflect on your findings. &lt;strong&gt;For Happiness!&lt;/strong&gt; :)&lt;/p&gt;
&lt;p&gt;
Do you have any tips to share? If so please feel free to add a few comments!&lt;/p&gt;
]]&gt;</description>
      <link>http://persumi.com/u/fredwu/tech/e/blog/p/writing-sensible-tests-for-happiness</link>
      <title>Writing Sensible Tests for Happiness</title>
    </item>
  </channel>
</rss>