---
title: "TDD and BDD in Ruby"
url: "https://courses.osherove.com/courses/tdd-and-bdd-in-ruby.md"
canonical: "https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/"
tags: []
author: "Roy Osherove"
description: "TDD and BDD in Ruby: 15 lessons, 4 h 9 min. 12 videos online so far, more coming soon. A free video course by Roy Osherove."
usage: "Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page)."
license: "https://creativecommons.org/licenses/by/4.0/"
---

# TDD and BDD in Ruby

[Courses](https://courses.osherove.com/#courses)

15 lessons 4 h 9 min 6 sections

Some videos of this course are coming soon; those lessons are marked below.

[Start course](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/day-1-intro/) [Watch on YouTube playlist](https://www.youtube.com/playlist?list=PLTkjoJUyKLBU)

![](https://courses.osherove.com/img/yt/g_dRMMURe48.jpg)

Get Started with Ruby [TDD](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec6 "Test-driven development (The Art of Unit Testing, 2nd ed., ch. 1)"), [BDD](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html "BDD: Behavior vs. Spec Frameworks (osherove.com)") and [Unit Testing](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec1 "Defining unit testing, step by step (The Art of Unit Testing, 2nd ed., ch. 1)") from scratch in 5 days.

## About this course

Roy Osherove teaches [unit testing](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_17 "Defining unit testing, step by step (The Art of Unit Testing, 3rd ed., ch. 1)"), [test-driven development](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_27 "Test-driven development (The Art of Unit Testing, 3rd ed., ch. 1)") and [behavior-driven development](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html "BDD: Behavior vs. Spec Frameworks (osherove.com)") in Ruby, starting with the three [end results](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_19 "Exit point types (The Art of Unit Testing, 3rd ed., ch. 1)") of a [unit of work](https://osherove.com/blog/2020/3/12/unit-testing-entry-points-and-exit-points "Unit Testing Entry and Exit Points (osherove.com)"), continuous testing with RSpec and Guard, and the [string calculator kata](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)") written test-first. The second and third days cover [mocks](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-4#sigil_toc_id_76 "Interaction testing, mocks, and stubs (The Art of Unit Testing, 3rd ed., ch. 4)"), [stubs](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-3#sigil_toc_id_62 "Reasons to use stubs (The Art of Unit Testing, 3rd ed., ch. 3)") and [fakes](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-4#ch04lev1sec2 "The difference between mocks and stubs (The Art of Unit Testing, 2nd ed., ch. 4)"), first handwritten and then with [isolation frameworks](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-5#sigil_toc_id_99 "Defining isolation frameworks (The Art of Unit Testing, 3rd ed., ch. 5)"), where he prefers the [non-strict](https://osherove.com/blog/2013/11/23/fifteen-things-i-look-for-in-an-isolation-framework.html "Fifteen things I look for in an Isolation framework (osherove.com)") Bogus to RSpec mocks and Mocha, and ways to make RSpec specs more readable. The fourth day turns plain-text specifications into [acceptance tests](https://osherove.com/blog/2013/3/29/acceptance-frameworks-vs-specification-apis.html "Acceptance Frameworks Vs. Specification APis (osherove.com)") with Cucumber and tests a Sinatra application with Capybara, and the fifth day starts a project with a [shipping skeleton](https://pipelinedriven.org/article/2014/3/2/pattern-shipping-skeleton "Pattern: Shipping Skeleton (pipelinedriven.org)") and [continuous delivery](https://pipelinedriven.org/article/continuous-delivery-values "Continuous Delivery Values (pipelinedriven.org)").

## Related reading

- [Exit point types](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_19) · The Art of Unit Testing, 3rd ed., ch. 1

    From the lesson [Day 1 Intro](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/day-1-intro/): The 3rd edition's section on exit point types: return values, state changes and third-party calls, the three end results of a unit described here.

- [Using describe()](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-2) · The Art of Unit Testing, 3rd ed., ch. 2

    From the lesson [Continuous Tests](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/continuous-tests/): The 3rd edition's section on grouping tests with describe(), the same nesting the lesson builds with RSpec's describe and context.

- [Measuring Simplicity in TDD](https://osherove.com/blog/2011/1/20/measuring-simplicity-in-tdd.html) · osherove.com

    From the lesson [Simplicity is Complicated](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/simplicity-is-complicated/): Roy's post on measuring the simplicity of a solution by how high in the function the code is, how indented it is and how many assumptions it makes, the rules taught here.

- [The importance of differentiating between mocks and stubs](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-4#sigil_toc_id_79) · The Art of Unit Testing, 3rd ed., ch. 4

    From the lesson [Mocks, Stubs and Fakes](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/mocks-stubs-and-fakes/): The 3rd edition's section on why to tell mocks from stubs, the distinction between a fake you assert against and any other fake taught here.

- [Fifteen things I look for in an Isolation framework](https://osherove.com/blog/2013/11/23/fifteen-things-i-look-for-in-an-isolation-framework.html) · osherove.com

    From the lesson [Using Bogus](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/using-bogus/): Roy's checklist for isolation frameworks, starting with whether they are strict or non-strict by default, the reason he prefers Bogus here.

## Curriculum

Section 1

### Day 1 - Basic Building Blocks

5 lessons · 2 h 26 min

The first day covers what a unit of work is and its three kinds of end results, the xUnit structure of arrange, act and assert, and setting up RSpec with Guard so that the specs run whenever a file changes. It then introduces test-driven development with the string calculator kata, explains how simplicity and assumptions lead to the next test, and answers common TDD questions, ending with numbers from an experiment that compared a team that used TDD with one that did not.

1. [Day 1 Intro Duration 48:04](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/day-1-intro/)

    Roy Osherove describes test-driven development as writing code as if the code you'd like to have already exists, a personal practice that was declared officially in extreme programming. He defines a unit as a unit of work that starts at a public API and ends in a return value, a state change noticeable at the same level of the API, or a call to a third party, the only place for mock objects. He questions claims that unit tests make bugs easier to find and code easier to maintain and understand, then introduces xUnit frameworks and their arrange, act, assert structure.

2. [Continuous Tests Duration 21:35](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/continuous-tests/)

    Roy Osherove installs the RSpec and Guard gems, lets RSpec create a spec helper and an options file, and lists the specs as a hierarchy with the documentation format. He writes a first spec for a calculator whose add method returns zero for numbers over a thousand, using describe, context and it so that the output reads almost like a sentence. He then creates a Guard file with only the RSpec configuration, has it watch the lib and spec directories, and runs Guard so that the specs run every time a file is saved.

3. [The Basics of RSpec Duration 40:40](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/the-basics-of-rspec/)

    Roy Osherove writes a failing spec for a bug in the calculator's second argument and removes the duplicated creation of the calculator, preferring a make calc factory method to a before block or let. He gives the three parts of test-driven development: no line of code without a failing test, solve it as simply as possible but no simpler, then refactor. He starts the string calculator kata with an empty string and then a single number, making as many assumptions as possible and removing them one spec at a time, and commits to git whenever the tests pass.

4. [Simplicity is Complicated Duration 9:33](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/simplicity-is-complicated/)

    Roy Osherove explains why he solves things in the simplest way possible but not simpler, since planning too much for the future can make the code bloated and complicated. He measures simplicity visually: a line at the beginning of a method is simpler than one in the middle and less nesting is simpler, as when students replaced all the new delimiters with commas in the first line of the string calculator. He describes TDD as breaking down one assumption at a time while wearing two hats, the laziest developer who writes the code and the person who writes the next test that proves an assumption wrong.

5. [Common Questions and Answers about Test Driven Development Duration 26:25](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/common-questions-and-answers-about-test-driven-development/)

    Roy Osherove answers why tests are written before the code: to test the test, to think about the problem before the solution, to be the first user of the API, and because there is never time to write them afterwards. He explains why he keeps only a single failing test at a time and uses TDD as a development technique for moving fast that usually tests the happy path rather than every invalid value. He also presents numbers from two teams at a company he consulted for, where the TDD team released two days earlier, in 24 days instead of 26, with 90% fewer bugs found in production.

Section 2

### Day 2 - Mocks, Stubs and Fakes

2 lessons · 34 min

The second day explains the difference between fakes, mocks and stubs with a handwritten fake logger and fake web service for the string calculator. It then moves to isolation frameworks, compares the strict RSpec mocks and Mocha with the non-strict Bogus, and recommends Bogus.

6. [Mocks, Stubs and Fakes Duration 18:09](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/mocks-stubs-and-fakes/)

    Roy Osherove adds a requirement that the string calculator writes to a slow logger and, without a framework, replaces the logger in the spec with a handwritten fake logger class that has the same interface and saves the values for the assert. He defines a fake as anything that looks like something else, a mock object as a fake that you assert against and a stub as any other fake, and passes the fake in through constructor injection. When a new requirement calls a web service if the logger raises an error, the fake web service becomes the mock and the fake logger a stub, and he advises no more than a single mock object per test.

7. [Using Bogus Duration 15:25](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/using-bogus/)

    Roy Osherove introduces isolation frameworks, which he prefers not to call mocking frameworks because they are mainly used to create stubs, and rewrites the first test with RSpec mocks, creating the fake logger with double and asserting with expect to have received. He explains that RSpec mocks and Mocha are strict, so a test has to be told about every method that will be called and breaks for the wrong reason, which he compares to throwing away a pizza because his six-year-old didn't say thank you. He recommends Bogus, which is non-strict and has safe faking that fails when a faked method doesn't exist or gets the wrong number of arguments.

Section 3

### Day 3 - Advanced RSpec and Faking

2 lessons · 28 min

The third day shows ways to make RSpec specs shorter and more readable with subject, let, specify and its, using fakes for the logger and the web service. It also shows how Bogus fakes class methods with fake class.

8. [Advanced RSpec and Cleaning Up The Specs Duration 25:44](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/advanced-rspec-and-cleaning-up-the-specs/)

    Roy Osherove refactors the string calculator specs, which have become long-winded, with subject, which by default is an instance of the described class, and lets for the fake logger and web service that can be overridden in a specific context, such as a logger that throws. He uses specify where the code says enough without a string and defines small methods such as adding so that each action is defined in one place. He notes a trade-off between the readability of the documentation report and of the code, and explains that its fits when a single action changes several attributes.

9. [Bogus and Class Methods Duration 2:05](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/bogus-and-class-methods/)

    Roy Osherove shows how Bogus fakes class methods, which are almost like static methods in other languages, by using fake class on a shared logger and asserting that it should have received write. He adds that the testing tool can give hints about the design but should not dictate it.

Section 4

### Day 4 - Acceptance Tests and Continuous Delivery

2 lessons · 16 min

The fourth day presents behavior-driven development as conversations with the customer and uses Cucumber to turn plain-text features into executable specifications, with step definitions written in Ruby. It then tests a Sinatra application through Capybara, checking that the main page shows the default greeting.

10. [Acceptance Tests with Cucumber Duration 13:41](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/acceptance-tests-with-cucumber/)

     Roy Osherove describes BDD as having real conversations with the customer and introduces Cucumber, which turns plain-text specifications, such as the drills written for the course, into executable specifications. He installs the gem, adds a feature file, pastes the step definitions that Cucumber suggests into a Ruby steps file, and shows how text in double quotes becomes a block argument and how pending steps are reported. He explains that the steps can attach to any level of the application, from string calculator objects to a Sinatra application, while the scenarios stay abstract because more technical scenarios are less maintainable.

11. [Testing Sinatra with Capybara and Cucumber Duration 2:46](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/testing-sinatra-with-capybara-and-cucumber/)

     Roy Osherove writes a Cucumber feature for the main page of a Sinatra application, which should show the default greeting, and uses Capybara in the steps to visit the page and check its content. He sets Capybara up in an env.rb file in the support folder under features and checks that the page contains hello world rather than equals an exact string, which he finds more maintainable.

Section 5

### Day 5 - Continuous Delivery

3 lessons

The fifth day's video describes how Roy Osherove starts a new project with a shipping skeleton, an empty hello world application that is taken through every step until it is released, from the first iteration. He discusses deployment as a form of compiling against reality, specs that keep changing with the customer, and why he does not offer unit tests as an option.

12. [Iteration Zero and Continuous Delivery Duration 25:06](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/iteration-zero-and-continuous-delivery/)

     Roy Osherove starts a new project with a shipping skeleton, an empty project that outputs hello world and is taken through every step until it is released, so that feedback starts in the first iteration. He calls deployment a form of compiling against reality, places Cucumber acceptance tests one level below the product owner's own tests, and argues that specs keep changing, so a program is never finished. Asked about customers who keep changing their minds, he says a team should ask about priorities instead of saying no, and he does not give people the option to remove unit tests.

13. [Continuous Delivery with TeamCity Video coming soon](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/continuous-delivery-with-teamcity/)
14. [Build Dependencies and Snapshot Dependencies Video coming soon](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/build-dependencies-and-snapshot-dependencies/)

Section 6

### Summary

1 lesson

15. [Summary Video coming soon](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/summary/)


---

## About the author

**Roy Osherove**: Senior Solutions Architect at AWS working on AI for production and AI-driven development; author of The Art of Unit Testing and Elastic Leadership, with about 20 years of consulting and training on unit testing, TDD, team leadership and continuous delivery.

### Sites

- [RobotPaper](https://robotpaper.ai/): This blog: AI patterns and anti-patterns, AI and coding agents, and engineering leadership.
- [osherove.com](https://osherove.com): Roy's personal site. Author of The Art of Unit Testing and Elastic Leadership; consulting and training on unit testing, TDD, team leadership and continuous delivery, plus about 20 years of blog posts.
- [The Art of Unit Testing](https://www.artofunittesting.com): The Art of Unit Testing, 3rd Edition (Manning): readable, maintainable, trustworthy unit tests, plus TDD workshops in C#, JavaScript, Java and Kotlin.
- [5whys.com](https://www.5whys.com): Roy's writing on software team leadership: self-organizing teams, surviving chaos, learning mode and the Elastic Leadership model.
- [Pipeline Driven](https://pipelinedriven.org): Continuous delivery and DevOps practices: build patterns, pipeline-friendly testing, DevOps metrics and enterprise DevOps.
- [Elastic Leadership](https://www.elasticleadership.com): Elastic Leadership, Roy's framework for software team leaders (survival, learning and self-organizing modes).

### Social

- X: https://x.com/royosherove
- LinkedIn: https://www.linkedin.com/in/osherove/

### Contact

- Contact form: https://forms.gle/jQSx5KoXvrVA1JCK7

### License

Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page). License: https://creativecommons.org/licenses/by/4.0/
