---
title: "Acceptance Tests with Cucumber"
url: "https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/acceptance-tests-with-cucumber.md"
canonical: "https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/acceptance-tests-with-cucumber/"
tags: []
author: "Roy Osherove"
description: "Lesson 10 of 15 in TDD and BDD in Ruby (Day 4 - Acceptance Tests and Continuous Delivery), 13:41. Free video 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/"
---

# Acceptance Tests with Cucumber

1. [Courses](https://courses.osherove.com/#courses)
2. [TDD and BDD in Ruby](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/)
3. Day 4 - Acceptance Tests and Continuous Delivery

Lesson 10 of 15

Duration: 13:41 [Watch on YouTube](https://www.youtube.com/watch?v=az3ZYVATTcU)

Learn how to use cucumber features to starting doing real [Behavior Driven Development](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html "BDD: Behavior vs. Spec Frameworks (osherove.com)") with your customer. BDD is all about communication, and here we learn the basics of writing the glue between what the customer or product owner writes, and what developers implement.

## In this lesson

Roy Osherove describes [BDD](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html "BDD: Behavior vs. Spec Frameworks (osherove.com)") as having real conversations with the customer and introduces [Cucumber](https://osherove.com/blog/2013/3/29/acceptance-frameworks-vs-specification-apis.html "Acceptance Frameworks Vs. Specification APis (osherove.com)"), 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](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)") objects to a Sinatra application, while the scenarios stay abstract because more technical scenarios are less [maintainable](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-8 "Maintainability (The Art of Unit Testing, 3rd ed., ch. 8)").

## Transcript

1,749 words

[\[00:04\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=4s) So up until now we've we've done specification based testing but it wasn't really [BDD](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html "BDD: Behavior vs. Spec Frameworks (osherove.com)") behavior driven development because BDD in its core is not about just developers being in a bubble talking to themselves and writing specs for themselves. It's about having real conversations with the customer. So what we're going to look at is one tool that enables having easier conversations with the customer or the product owner. That's a tool called [Cucumber](https://osherove.com/blog/2013/3/29/acceptance-frameworks-vs-specification-apis.html "Acceptance Frameworks Vs. Specification APis (osherove.com)").

[\[00:36\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=36s) Now the nice thing about tools like Cucumber is that they allow you to write in almost plain text language things that you would like to have in your product just like I did in the drills that you've worked on. So, I actually wrote these drills in the same format that you would use in Cucumber. So, what we're going to do is we're going to see how we can actually make these specifications that I wrote here in the document that you've actually worked on and turn them into executable specifications.

[\[01:12\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=72s) So, imagine that I was the product owner. I wrote this and now you're taking this and you're putting it to automated use. Okay. And in the process, we'll take a look at the tool called cucumber. So cucumber is a gem. You basically do gem install cucumber. And what I've done already is that I've added a new features

[\[01:43\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=103s) Directory here. And in the features directory, I'm going to add one's file. And I just named it something whatever is the feature name is and called dot feature. And in there I basically pasted the text as it was. Now it works. You see? No actually still still a bit a bit to go. But this is the first step. What we're going to do is we're going to execute this scenario using cucumber and see what happens.

[\[02:19\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=139s) If I go to if I just type cucumber here, cucumber automatically detects that there is a features directory. He detects the feature and he tells me, "Look, there's a scenario here part of the feature title and he detects a scenario and he detects the special words when and then and it says look there's a scenario here that you haven't implemented yet." So, it's really undefined

[\[02:54\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=174s) And it has two substeps that you have to define. And it tells me what I can do to then translate these plain text language steps into Ruby steps and it gives me a piece of text here which I can basically copy. Okay. And what do these actually mean? Let's take a look by pasting them in a special folder called

[\[03:35\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=215s) In the step definitions, I'm going to add one file. You can call it first feature or we can say called spec say calculator steps. RB that's a regular Ruby file. And in that file, I'm just pasting in what I just got from cucumber. So, let's take a look at that. It basically has these for each step for each line under the scenario.

[\[04:10\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=250s) We don't need the extra end. And what it does is that it tries to to look for special strings inside the step. And it says, "Look, this is a regular expression. Look for these words in the feature file." And when it encounters these double quotes, it automatically thinks, "Oh, you put a string inside the feature. You might want to change this string later." So let me give you that string as an argument to a block in your Ruby code.

[\[04:47\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=287s) So it tries to generate a regular expression that captures whatever is inside double quotes here. And then I can have it as an argument. I can rename it to text. And by default the feature is pending. If I just save this and I go back and I run cucumber again, what I get back is a different type of message. It says I have a to-do. I have a pending

[\[05:17\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=317s) Pending here and a pending there. And then I have something that didn't run. Okay, so it was skipped. Now if I remove the word pending just from this line and I save it and I run that again you can see now that this has become green when the [string calculator](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)") add method is called and the rest is yellow. If I remove that,

[\[05:50\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=350s) You can see that it says scenario passed with two steps that passed. But that's not good because it hasn't really passed. We're just lying to ourselves. So, we're going to put back the word pending here. But here, we get to do whatever we want in this step. We can use [integration testing](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_25 "Integration tests (The Art of Unit Testing, 3rd ed., ch. 1)") to go using selenium or Capybara to web page scrape the page. We can use we can execute command lines that use nodejs zombiejs to use a web browser scraping.

[\[06:21\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=381s) We can use Sinatra and Capybara to run things in memory without a web server. And we can literally just execute objects from our application such as creating a calculator. Okay. So if I say here string calculator dot new street calculator two depths new with

[\[06:53\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=413s) A logger and a web service. I can say add and I just give it text. It says I do need to [fake](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)") the logger. So I might say logger equals and I might put it in a class variable. So I might say logger equals fake slow.

[\[07:34\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=454s) Let's do the web service web service. Because I have them with the ad sign now I can actually go and say look this is a piece of text. So I can now actually assert that logger should have received

[\[08:10\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=490s) Right with text. Okay. So it's right now what I'm doing is I'm translating my unit tests into running them through cucumber because the point I want you to see is that you can write whatever you want in those steps. It's up to you to decide which level of the application you're actually attaching to. But the abstraction of pure text belongs to the customer. So you let the customer write things in the in an abstract way.

[\[08:43\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=523s) You do not have to know anything about the technical features of the application. Okay. So if I if I save it and I try to run it, I'm going to have a lot of dependency issues. I need to do all their requires etc. But you see undefined method fake etc. But it does run the code inside the webs. So now it's just a matter of getting all the code to run correctly. But it's almost like asserting because I can use RSpec matchers, use whatever matching mechanism I want.

[\[09:16\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=556s) Okay. Now the same thing can go for an application like Sinatra applications. So if I do and I go back refresh that show you a bit more of a complete demo. If I have a this is more of the feature that I planned.

[\[09:49\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=589s) So I have string called steps here. This is what it would look like. I might fake the logger, fake the calculator, call add. But I can also do the same with the Sinatra application. So I can say using Sinatra with Capybara. In order to easily test our web app, we will use Capybara. But that's not something that the customer would write. This is just a demo. The customer might say feature having a main page and then scenario main page.

[\[10:20\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=620s) When I go to the main page, notice that the customer doesn't care what is the URL of the main page. I could have specified it here, but I don't want the scenarios to be very very technical. I want them to be abstractions. The more technical the scenarios are, the less [maintainable](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-8#ch08lev1sec2 "Writing maintainable tests (The Art of Unit Testing, 2nd ed., ch. 8)") they become. Okay. So, when I go to the main page is better than when I go to this URL and I should see the default greeting is better than I should see this exact text. because the default greeting is something that might change a long time.

[\[10:54\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=654s) Okay. And then I just put more steps here. When I go to the main page, I would use a gem called Capybara and say just visit this. And if I wanted to check the default reading, I would say page.sh should have content and I would just look at this default reading. Now to enable things like Sinatra I would have an extra directory called support and in there I would have an n.rb RB

[\[11:26\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=686s) Where we do all the requires and then there is a world do and in the world do this is part of the cucumber thing and Capybara as well is that I would configure Capybara to use my SAP application so it doesn't have to run a web server or anything like that but I could just as well have connected to a Rails application to a command line application to anything as long as I can automate it. I can do whatever I want through the cucumber scenarios.

[\[12:01\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=721s) For example, in cucumber, I might say I'm not going to use RSpec at all. I might just use objects and say this object I call it and then I this object has that the database is has that state. And then it would fail and then to make it pass I would have a lot of specs subspecs going until finally that feature passed. Okay. So what I want you to do now is to literally copy the

[\[12:31\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=751s) Create a feature page from the first feature with two scenarios that we have and I want you to implement them through cucumber. Okay, you can I want you to prove that they work for me as a customer instead of just a technical person. Okay, questions. >> The relationship between when

[\[13:04\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=784s) >> Yeah. When is the range and then is >> there has to be. Yeah. But you don't have to do a given and you don't have to do end. You don't have to do any of them really, right? But you usually need them at least because they're they're the thing that you would need to to say something about the application, about the state of the world. >> Other questions? >> You start from that like the first >> Yeah, you start from the first one. >> Yeah. >> Well, you can just add features directory to the current directory you're working on.

[\[13:37\]](https://www.youtube.com/watch?v=az3ZYVATTcU&t=817s) >> Whatever you want. >> Okay, good luck.

## Related

- [Acceptance Frameworks Vs. Specification APis](https://osherove.com/blog/2013/3/29/acceptance-frameworks-vs-specification-apis.html) · osherove.com

    Roy's post contrasting Cucumber-style tools, which make you talk to the customer through plain-text specs and step adapters, with spec APIs like RSpec.

- [BDD: Behavior vs. Spec Frameworks](https://osherove.com/blog/2008/10/4/bdd-behavior-vs-spec-frameworks.html) · osherove.com

    Roy's earlier post on behavior frameworks for user stories versus spec frameworks for unit-level specs, where Cucumber's features belong.

### Also linked in this lesson

#### The Art of Unit Testing, 3rd ed.

- [Maintainability](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-8), ch. 8
- [Integration tests](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_25), ch. 1

#### The Art of Unit Testing, 2nd ed.

- [The difference between mocks and stubs](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-4#ch04lev1sec2), ch. 4
- [Writing maintainable tests](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-8#ch08lev1sec2), ch. 8

#### osherove.com

- [TDD Kata 1 - String Calculator](https://osherove.com/tdd-kata-1)

[Previous lesson Bogus and Class Methods](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/bogus-and-class-methods/) [Next lesson Testing Sinatra with Capybara and Cucumber](https://courses.osherove.com/courses/tdd-and-bdd-in-ruby/testing-sinatra-with-capybara-and-cucumber/)


---

## 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/
