TDD and BDD in Ruby
15 lessons 4 h 9 min 6 sections
Some videos of this course are coming soon; those lessons are marked below.
Start course Watch on YouTube playlist (external link, opens in new tab)
Get Started with Ruby TDD (external link, opens in new tab), BDD (external link, opens in new tab) and Unit Testing (external link, opens in new tab) from scratch in 5 days.
About this course
Roy Osherove teaches unit testing (external link, opens in new tab), test-driven development (external link, opens in new tab) and behavior-driven development (external link, opens in new tab) in Ruby, starting with the three end results (external link, opens in new tab) of a unit of work (external link, opens in new tab), continuous testing with RSpec and Guard, and the string calculator kata (external link, opens in new tab) written test-first. The second and third days cover mocks (external link, opens in new tab), stubs (external link, opens in new tab) and fakes (external link, opens in new tab), first handwritten and then with isolation frameworks (external link, opens in new tab), where he prefers the non-strict (external link, opens in new tab) Bogus to RSpec mocks and Mocha, and ways to make RSpec specs more readable. The fourth day turns plain-text specifications into acceptance tests (external link, opens in new tab) with Cucumber and tests a Sinatra application with Capybara, and the fifth day starts a project with a shipping skeleton (external link, opens in new tab) and continuous delivery (external link, opens in new tab).
Curriculum
Section 1
Day 1 - Basic Building Blocks
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.
-
Day 1 Intro Duration 48:04 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.
-
Continuous Tests Duration 21:35 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.
-
The Basics of RSpec Duration 40:40 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.
-
Simplicity is Complicated Duration 9:33 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.
-
Common Questions and Answers about Test Driven Development Duration 26:25 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
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.
-
Mocks, Stubs and Fakes Duration 18:09 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.
-
Using Bogus Duration 15:25 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
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.
-
Advanced RSpec and Cleaning Up The Specs Duration 25:44 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.
-
Bogus and Class Methods Duration 2:05 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
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.
-
Acceptance Tests with Cucumber Duration 13:41 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.
-
Testing Sinatra with Capybara and Cucumber Duration 2:46 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
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.
-
Iteration Zero and Continuous Delivery Duration 25:06 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.
- Continuous Delivery with TeamCity Video coming soon
- Build Dependencies and Snapshot Dependencies Video coming soon
Section 6