CSC/ECE 517 Fall 2012/ch2a 2w26 aj

From PG_Wiki
Jump to: navigation, search


SaaS 4.6 Enhancing Rotten Potatoes again


The article is intended to be an accompaniment to the SaaS video lecture 4.6  titled “Enhancing Rotten Potatoes again” [1], part of the SaaS video lecture series for the Software Engineering for SaaS hosted on the Coursera learning network. [2]
The Rotten Potatoes webpage, designed in the previous lectures is enhanced for implementing a new feature to add a new movie by looking up the TMDb database rather than manually entering the movie name. The flow of this article is as follows :

Note : All images used in this article have been taken from screen captures of Coursera video lectures available here. All content is owned by original authors and there is no copyright infringement intended. References have been provided in the image descriptions wherever necessary


The scope of this article is limited only to the scope covered in the video lecture. The lecture builds upon Behavior-Driven Development (BDD) basics discussed in the video lectures before it and sets the reader up for upcoming lectures concerning Test-Driven Development (TDD). Hence for the purpose of this article, it is assumed that the reader has already read the material and watched the video lectures before this one in the series. Hence the setup for Cucumber, Capybara and BDD basics are excluded from this article. The resources dealing with these can be found in the SaaS lectures 4.1 to 4.5 in the series. Similarly, the theory and implementation of TDD as well as further discussion on BDD is excluded from the scope of this article. More details on these can be found in lectures 4.7 to 5.11 of the SaaS lecture series .[3]

A Brief Recap

Behavior-Driven Development (BDD) is a specialized development process which concentrates more on the behavioral aspects of the application as against the actual implementation of the application. [4] Storyboards are used to show how UI changes based on user actions. Even if it is tedious to draw sketches and storyboards, it helps build a ‘bigger picture’ understanding of the flow of the application for the non-technical stakeholders.

Cucumber is one of the shining tools of Rails that is used for testing purposes. It acts as a halfway between the customer and the developer by converting user stories of 3x5 cards into tests. These tests act as Acceptance tests for ensuring the satisfaction of the customer. Also, the tests act as Integration tests that ensures the communication between modules is consistent and correct

The User Story

The aim of the User story described in the video is to add a new feature to the Rotten Potatoes web page, to add a new movie to the movies list on Rotten Potatoes page. But, for adding the movie to the list, it populates the data from TMDb rather than entering the information by hand. This is aimed at reducing repetitive work since the TMDb already has a good database of movies. To do so, the ability to search TMDb from Rotten Potatoes home page needs to be incorporated in the webpage. Users can then search in TMDb if the movie is present in it and then its details can be imported into Rotten Potatoes. For integrating this feature into the application, first, a Lo-Fi UI and Storyboard is designed, which is described next.

The Storyboard

The Storyboard is to be interpreted as follows When a person wants to add a new movie to the Movies list on Rotten Potatoes, he/she will enter the new movie name and click “Search”. The controller method should search the TMDb database for the given movie. If a match is found, i.e. the movie is present in the TMDb, then the “Match” page is displayed. If there is no match, otherwise “No Match” page is displayed. These two scenarios, are the Happy Path and Sad Path implementations respectively.

The Storyboard for the User Story. (Click Image to expand) Source :

Happy Path, Sad Path and Bad path

Many of us are aware of the test cases being categorized as Positive or Negative test cases. Similarly, for testing using Rails Cucumber, the tests cases are being categorized as Happy, Sad of Bad[5]. A test case that results in a positive result is called a Happy Path. E.g. On entering correct username and password on login page, the application logs the user in. A test case that yields no result is called a Sad Path. E.g. Entering invalid username or password on login page, which normally returns an ‘Incorrect username or password’ message A test case to handle an exceptional condition or situation, which the system should handle elegantly and show some message to the user is a Bad Path. E.g. Uploading image size exceeds a limited amount. User can then take corrective action.

Elaboration of the User Story

Let us consider the sad path scenario for the Search TMDb User Story Feature.

Feature: User can add movie by searching in The Movie Database(TMDb)
User Story:
As a movie fan
So that I can add new movies without manual tedium
I want to add movies by looking up their details in TMDb
Scenario: Try to add non-existent movie (sad path)
Given I am on the RottenPotatoes home page
Then I should see "Search TMDb for a movie"
When I fill in "Search Terms" with "Movie That Does Not Exist"
And I press "Search TMDb"
Then I should be on the RottenPotatoes home page
And I should see "'Movie That Does Not Exist' was not found in TMDb."

The Test shown above has 6 steps (The logic and code for implementing this is provided in the TDD lectures in the Coursera series).

The Cucumber Test with Features and Scenarios. (Click Image to expand)

When we run the test, since there is already a home page, the first step of the scenario passes.

Step for Home Page Passes. (Click Image to expand)

In the second step of the scenario, there is no link on the view for adding a new movie. Hence the second step fails and the following steps are skipped.

However Step for the "search_tmdb" link fails and others after that are skipped. (Click Image to expand)

Now, we add the link for the “search_tmdb” action. For this, the HAML for Search TMDb page should contain the following:

%h1 Search TMDb for a movie
= form_tag :action => 'search_tmdb' do
  %label{:for => 'search_terms'} Search Terms
  = text_field_tag 'search_terms'
  = submit_tag 'Search TMDb'

These are added into the end of app/views/movies/index.html.haml

The last two lines in the above code will be expanded into the HTML code:

<label for='search_terms'>Search Terms</label>
<input id="search_terms" name="search_terms"type="text" />

Now there is a page and a link in place for the test. On running the test using Cucumber again, the test fails again. This is because there is still no method defined in the controller (movies_controller.rb) for actually searching in TMDb.

The Link for search_tmdb is added to the view, but there is no method for search_tmdb in controller. Also there is no route. Hence these steps fail or are skipped. (Click Image to expand)

However the video tutorial in this discussion considers only the sad path scenario. To test this Sad path implementation, a dummy/fake method is defined in the movies_controller.rb which fails everytime, i.e. the search for the movie in TMDb never returns a match.

So, the following code for the fake controller method is added to the movies_controller.rb:

def search_tmdb
  # hardwire to simulate failure
  flash[:warning] = "'#{params[:search_terms]}' was not found in TMDb."
  redirect_to movies_path

and since a new method has been added, we need to add a route to this controller method too. The following route is added to routes.db, just before or just after ‘resources :movies’:

# Route that posts 'Search TMDb' form
post '/movies/search_tmdb'

Now, on running the test again using Cucumber, every time the method is called, it returns a failure message (since it is hard-coded). This implies that the sad path implementation passed.

Dummy method added to controller for 'search_tmdb' and then a route is also added. The dummy method fails everytime thereby satisfying the sad path scenario. (Click Image to expand)

The actual code and logic for implementation of this action (search_tmdb) is discussed in later lectures which discuss the TDD (Test Driven Development) process

So far we have considered the Sad path scenario.

Let us consider the happy path scenario for the Search TMDb User Story Feature.

Feature: User can add movie by searching in The Movie Database(TMDb)
User Story:
As a movie fan
So that I can add new movies without manual tedium
I want to add movies by looking up their details in TMDb
Scenario: Try to add existing movie (happy path)
  When I fill in "Search Terms" with "Inception"
  And I press "Search TMDb"
  Then I should be on the RottenPotatoes home page
  And I should see "Inception"
  And I should see "PG-13"

For implementation of this, instead of the hard coded Controller method, an actual controller method will have to written which searches TMDb and returns the details of the movie which will then be added to the Rotten Potatoes database. (However, this implementation is out of scope for our article. Further details of this can be found in the TDD lectures of this series.)

Now, the Happy and the Sad paths have some code in common which violates the DRY principle. So, to make it DRY, Cucumber offers a solution called Background [6]. The steps which are common to both the paths are written in Background and those steps will run in the background before all the other scenarios. No matter what scenario one runs, the steps in the Background will run first, which will DRY out the code. This also helps in reducing the effort in case any steps leading up to the scenarios (setup) are to be modified. The tester will only have to change the code in one location. In this example there is only one happy path and sad path scenario i.e. only two scenarios. However, in real world examples, there would be a larger list of scenarios which could have the same ‘setup’. The advantages of the Background facility are more pronounced in this case.

The Cucumber Background. (Click Image to expand)


In summary, this article demonstrates the BDD/Cucumber test behaviour with the help of examples. It discusses the enhancement of Rotten Potatoes webpage for implementing a new feature, which is addition of a new movie by looking up the TMDb database rather than manually entering the movie name. This includes designing a Lo-Fi UI, writing scenarios and step definitions, even writing new methods for successfully executing the test cases using Cucumber. The article also introduces and explains the concept of Background in Cucumber, which helps in DRYing out the repeated code in scenarios of the same feature. The next chapter will discuss the TDD/RSpec behaviour and the approach to make all the scenarios pass.

Topical References

  1. Enhancing Rotten Potatoes again,
  2. Coursera,
  3. Software Engineering for SaaS,
  4. Software Engineering for SaaS,
  6. Background in Cucumber,

Further Reading

Capybara : Capybara introduction .

Railscast on testing in Capybara : Railscast on testing in Capybara.

Capybara and Cucumber : Capybara and Cucumber.

The Truth about BDD : The Truth about BDD.

BDD and RSpec : BDD and RSpec.

Cucumber and Capybara for Rails : Cucumber and Capybara for Rails.

Smelly Cucumbers : Smelly Cucumbers.

Cucumber : Cucumber.

Beginning with Cucumber : Testing with Cucumber.

Personal tools