I read pull requests every day. I read much more pull requests that I create. I am often amazed how specs are not treated as first class citizens in project. Ofcourse every engineer will said it is not true because he sees the value in specs. But, do they?

Every programmer tries to craft his codebase to keep it clean, robust and well structured. But in some degree of limitation. All the application code is always clean, developers knows tons of great patterns, conventions etc. to keep application code clean. Sometimes even it is really clean! But when I look into specs … man, most of them look like created using the potato stamp. Mixed, complicated, long, hard to understand after some time … But after all they are green, no failure, green dots in out. Why bother to something more?

Consider this simple, almost pseudo-code rspec example:

describe SomeCleanClass do
  let(:dependency_a) { DependencyA.new }
  let(:dependenby_b) { DependencyB.new }
  subject { described_class.new(dependency_a, dependency_b) }

  describe '#method_a' do
    # testing the method_a goes here

    context 'when something something' do
      let(:dependency_a) { SomeSpecificCaseDependencyA.new }
    end

    context 'when something other' do
    end
  end

  describe '#method_b' do
    let(:dependency_a) { SomeOtherDependencyA.new }

    # testing the method_b goes here
  end
end

There is one particular thing I would like to bring to your attention. This test is optimized for code duplication, not code readability. After all why to bother? It produces a green, little dot in output. Well … code is read much more often than written. Same applies to specs, maybe even in more degree. Often I see that developers struggle to generalize tests source code because repetition is a source of all evil of 2020 year! Don’t repeat yourself, they said. Sometimes I even think that there are developers with DRY tatoo!

In above example it is not so visible. rspec is a great tool for testing, it also has a ability to generate lines of code like creazy. When you test object with two or three methods it is easy to product more than one screen of code. You are working with one method spec and constantly you are jumping to the top of file to check definition, then check the overidden values. Mindblow!

describe SomeCleanClass do
  let(:dependency_a) { DependencyA.new }
  let(:dependenby_b) { DependencyB.new }
  subject { described_class.new(dependency_a, dependency_b) }

  describe '#method_a' do
    let(:dependency_a) { DependencyA.new }
    let(:dependenby_b) { DependencyB.new }
    subject { described_class.new(dependency_a, dependency_b) }

    context 'when something something' do
      let(:dependency_a) { SomeSpecificCaseDependencyA.new }
    end

    context 'when something other' do
    end
  end

  describe '#method_b' do
    let(:dependency_a) { DependencyA.new }
    let(:dependenby_b) { DependencyB.new }
    subject { described_class.new(dependency_a, dependency_b) }
  end
end