Lesson 2
Generalization in TDD with Ruby and RSpec
Introduction to Generalization in TDD

Welcome back to our course on Test-Driven Development (TDD) using Ruby and RSpec. In our previous lesson, we introduced the fundamentals of TDD and the Red-Green-Refactor workflow. Now, we will advance our TDD skills by focusing on generalizing solutions and enhancing the complexity of our testing scenarios.

As a brief reminder, TDD involves a repetitive cycle known as Red-Green-Refactor:

  • Red: Write a failing test to clarify the new functionality you aim to implement.
  • Green: Develop the smallest amount of code needed to make that test pass.
  • Refactor: Clean up the code, enhancing its quality while maintaining its functionality and ensuring all tests remain passing.

In this lesson, we will expand upon a simple sum function, demonstrating how to generalize it while following these TDD principles.

Examining the Current Code Structure

Before we dive into coding, let's review our current setup. We are going to create a simple sum method and tests associated with it in Ruby.

math_spec.rb

Ruby
1require './math' 2 3RSpec.describe 'sum method' do 4 it 'adds two numbers correctly' do 5 expect(sum(2, 3)).to eq(5) 6 end 7end

math.rb

Ruby
1def sum(a, b) 2 5 3end

This setup serves as a foundation. Now, we'll focus on expanding your understanding by generalizing the approach using TDD principles. Understanding where you've come from will help ensure future changes enhance our function without straying too far from the core logic.

Example: Red Phase - Adding a New Failing Test

To embrace the Red phase, let's introduce a new test case that will fail.

Update math_spec.rb to add an additional input scenario:

math_spec.rb

Ruby
1require './math' 2 3RSpec.describe 'sum method' do 4 it 'adds two numbers correctly' do 5 expect(sum(2, 3)).to eq(5) 6 end 7 8 it 'adds two other numbers' do 9 expect(sum(5, 6)).to eq(11) 10 end 11end

By including a new scenario with new inputs, this step is intentionally set to fail to define our target goal clearly.

Running this test with RSpec will demonstrate a failure, indicating the need for new functionality.

Example: Green Phase - Implementing a Solution to Pass Tests

Now, let's transition to the Green phase, where our goal is to ensure all tests pass, including our new one. We can update our sum function to perform a simple addition of the inputs.

math.rb

Ruby
1def sum(a, b) 2 a + b 3end

Running the tests again should now output a successful result. This illustrates how effective writing minimal code to pass tests can be.

Example: Refactor Phase - Generalizing the Solution

Finally, let's advance into the Refactor stage. The sum function is very simple, so there's nothing we can improve regarding the implementation. However, our tests can be refactored to remove duplication.

Let's use parameterized testing by iterating over a set of test data to reduce redundancy in our test cases. This approach allows us to maintain clarity as complexity escalates over iterations.

math_spec.rb

Ruby
1require './math' 2 3RSpec.describe 'sum method' do 4 [ 5 [2, 3, 5], 6 [5, 6, 11] 7 ].each do |a, b, expected| 8 it "adds #{a} and #{b} to equal #{expected}" do 9 expect(sum(a, b)).to eq(expected) 10 end 11 end 12end

For now, there's no functional change — but strategically refactoring in this way offers benefits, maintaining clarity as complexity escalates over iterations.

Review and Preparation for Practice

In this lesson, we explored advancing our TDD approach by generalizing solutions and scaling scenarios:

  • Red: Write a failing test to define new goals.
  • Green: Confirm new goals via minimal passing code.
  • Refactor: Support future needs by formalizing and improving code.

These principles remain central to creating robust, adaptable solutions in any software development process. Continue practicing these steps through additional tests and scenarios in your exercises. You're on the path to mastering evolving solution implementations and designing more comprehensive, generalized code with TDD. Keep applying these principles and practicing to further cement your understanding.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.