TDD Basics : Code Mutation
- To illustrate the need to mutate the code when the test passes without failing.
The test is written before the code and if it passes without failing, then we don't know if the test is correct. In such cases, you must modify the production code to make the test fail to make sure that it is testing the right thing.
ruby_extensions_spec.rb with the following contents:
require_relative 'ruby_extensions' describe 'Ruby extensions' do it 'return a list of elements common to both arrays without duplicates' do a = [1,1,3,5] b = [1,2,3] result = a.intersection(b) result.should == [1, 3] end end
To make the test pass, create
ruby_extensions.rb with the following contents:
class Array def intersection(another) self & another end end
The & operator is used for intersection operation in Array. The builtin Array class does not have intersection method. We are opening the Ruby's Array class and defining a intersection method. The test should pass.
Add the second spec for the boundary condition like this:
require_relative 'ruby_extensions' describe 'Array extensions' do # First spec same as before # Here is the new spec it 'returns no common element if there is no common elements between the two arrays' do a = [1,1,3,5] b = [7,9] result = a.intersection(b) result.should ==  end end
Run the specs now. The new test passes without failing. The question is how do you know if this test is correct? We don't have a test to test this test. To validate the test, we have to mutate the production code to make it fail for the scenario under test.
ruby_extensions.rb so that only the second spec fails like this:
class Array def intersection(another) return  self & another end end
Here we short-circuit the code to bypass the correct implementation and provide a wrong value as the answer.
Now run the specs. The second spec now breaks with the error:
1) Array Array extensions returns no common element if there is no common elements between the two arrays Failure/Error: result.should ==  expected:  got:  (using ==)
Delete the line below from the
Run the specs. It should now pass.
In this article we saw:
- What to do when the test passes without failing?
- How to open classes that preserves the semantics of the core classes?
- Intention revealing variable and method names.
So we learned why and when to mutate the production code. If you had followed the Transformation Priority Premise, this problem would not have occurred at all.
- Google the term 'Transformation Priority Premise' and watch the videos to learn about this principle.
- Think of edge cases for the
- Write specs for the edge cases. When the spec passes without failing, mutate the code to make only the boundary condition for that particular test fail. Then make all the specs pass.
Ace the Technical Interview
- Easily find the gaps in your knowledge
- Get customized lessons based on where you are
- Take consistent action everyday
- Builtin accountability to keep you on track
- You will solve bigger problems over time
- Get the job of your dreams
Take the 30 Day Coding Skills Challenge
Gain confidence to attend the interview