Don't test your code by running the exact same code
- Name
- Dennis Paagman
- @djfpaagman
Test Driven Development and Unit Testing are great. There’s an issue I see every now and then that’s sometimes very subtle. The problem is testing code by executing the exact same code. This leads to a false sense of test coverage, if the underlying implementation changes your test will still be green.
Instead, write tests that test the actual expected output. This probably means hard coding your test data bit more, and writing more explicit tests.
Take this example class that multiplies two values:
class Multiplier
def self.multiply(a, b)
a * b
end
end
A simple test can look something like this:
RSpec.describe Multiplier do
it "multiplies" do
expect(Multiplier.multiply(2, 2)).to eq(2*2)
end
end
The problem is that it’s duplicating the exact same code as in the class. If the underlying implementation of *
changes (which is a stretch, but totally doable in Ruby), the test still passes.
A better test would check against the actual output you expect. This tests that the code actually does what you’d expect in real life.
RSpec.describe Multiplier do
it "multiplies" do
expect(Multiplier.multiply(2, 2)).to eq(4)
end
end
One more greatly simplified example:
RSpec.describe Event do
it "includes the name in the decorated name" do
event = Event.create!(name: "Meeting")
# `full_name` includes some other data as well
expect(event.full_name).to include event.name
end
end
If something happens that changes the name, the test will never fail because it will run the exact same code and compare against the changed value. A better test would test against the actual value:
RSpec.describe Event do
it "includes the name in the decorated name" do
event = Event.create!(name: "Meeting")
# `full_name` includes some other data as well
expect(event.full_name).to include "Meeting"
end
end
These examples are simplified, usually it’s less obvious when this is happening. A great red flag to notice this pattern is when the right side of the expectation runs code.