Lesson 1
Introduction to Test Driven Development in Ruby
Introduction to TDD

Welcome to the first lesson of our course on Test Driven Development (TDD) in Ruby using RSpec. TDD is an iterative software development process where tests are written before the actual code. This approach enables programmers to focus on the requirements before diving into implementation, ultimately leading to code that is more reliable and maintainable.

In this lesson, we will introduce you to the essential elements of TDD, including the Red-Green-Refactor cycle, which forms the backbone of this methodology. We'll also introduce the tools we'll be using: Ruby and RSpec. Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity. RSpec is a popular testing framework in the Ruby community that provides a clean and readable syntax for writing tests. Alternatives like MiniTest exist, but RSpec's expressiveness and community support make it an excellent choice for this course. Let's begin by exploring TDD's core components with an example.

Writing the First Test (Red)

In TDD, the journey begins with writing a test that fails. This "Red" stage allows you to clarify your objective before implementation. Let's start by writing a test for a sum method, which will eventually add two numbers.

Create a file named math_spec.rb in the spec directory:

Ruby
1require_relative '../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

This test script:

  • Requires the sum method, which we haven't defined yet.
  • Uses RSpec.describe to organize related test cases.
  • Contains an it block for a specific test: ensuring sum(2, 3) returns 5.

Run this test even without a sum method. It will fail, reflecting the "Red" phase, indicating the need for implementation.

Output:

1sum method 2  adds two numbers correctly (FAILED - 1) 3 4Failures: 5 6 1) sum method adds two numbers correctly 7 Failure/Error: expect(sum(2, 3)).to eq(5) 8 9 NoMethodError: 10 undefined method `sum' for #<RSpec::ExampleGroups::SumMethod:...> 11 12Finished in 0.00123 seconds (files took 0.12345 seconds to load) 131 example, 1 failure 14 15Failed examples: 16 17rspec ./spec/math_spec.rb:5 # sum method adds two numbers correctly

This is an expected failure and shows that our test is working properly to identify unimplemented features.

Making the Test Pass (Green)

Our next goal is to write just enough code to make the test pass — the "Green" step. In TDD, this means implementing the simplest functionality that satisfies the test requirements. Let's define the sum method in a new file math.rb in the root directory:

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

This solution might seem odd because it doesn't genuinely add two numbers. However, it exemplifies the TDD focus on passing the test with the minimal implementation. By achieving this, we've fulfilled the current test condition.

Re-running our test will yield the following:

Output:

1 2sum method 3 adds two numbers correctly 4 5Finished in 0.00187 seconds (files took 0.12799 seconds to load) 61 example, 0 failures

Seeing the test pass confirms that our code satisfies the current test scenario. We can later iterate on our implementation as new tests impose stricter functionality requirements.

Refactoring and Code Improvement (Refactor)

The last step, "Refactor," involves refining the code while ensuring existing behavior remains unchanged. In this instance, our sum method is quite efficient, but we can improve our test readability by assigning the output of the sum method to a variable:

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

This small refactoring illustrates how minor adjustments can enhance clarity, as it isolates the act (execution) from the assert (verification). When dealing with more complex functions, refactoring might involve breaking down a method, renaming variables for clarity, or improving test readability. Our Red-Green-Refactor cycle for this example is now complete.

Review and Next Steps

In this lesson, we've explored the basic tenets of TDD using the Red-Green-Refactor workflow with Ruby and RSpec. Let's recap:

  • Red: Begin by writing a test that fails.
  • Green: Develop minimal code sufficient to pass the test.
  • Refactor: Enhance your code and maintain passing tests.

As you advance, practicing TDD principles in the practice exercises will strengthen your understanding and ability to write robust, maintainable code. Remember to integrate these concepts into your daily coding practices to enhance code quality and reliability.

With this foundation, you're ready to delve into more complex scenarios we will explore in future lessons. Keep honing your skills to become an adept practitioner of TDD.

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