Forms (Engineering Software as a Service §4.6)

Slides:



Advertisements
Similar presentations
JQuery MessageBoard. Lets use jQuery and AJAX in combination with a database to update and retrieve information without refreshing the page. Here we will.
Advertisements

Chapter 3: Editing and Debugging SAS Programs. Some useful tips of using Program Editor Add line number: In the Command Box, type num, enter. Save SAS.
© 2013 Armando Fox & David Patterson, all rights reserved
Forms (Engineering Software as a Service §4.6) © 2013 Armando Fox & David Patterson, all rights reserved 1.
A Guide to Oracle9i1 Introduction To Forms Builder Chapter 5.
Inventory Throughout this slide show there will be hyperlinks (highlighted in blue) follow the hyperlinks to navigate to the specified Topic or Figure.
Creating a Web Page HTML, FrontPage, Word, Composer.
Form Handling, Validation and Functions. Form Handling Forms are a graphical user interfaces (GUIs) that enables the interaction between users and servers.
RUBY ON RAILS Mark Zhang. In this talk  Overview of Ruby on Rails  Core ideas  Show a tiny bit of example code  Touch on several general web development/
Ruby on Rails. What is Ruby on Rails? Ruby on Rails is an open source full-stack web framework. It is an alternative to PHP/MySQL. It can render templates,
1 Web Developer & Design Foundations with XHTML Chapter 6 Key Concepts.
M. Taimoor Khan * Java Server Pages (JSP) is a server-side programming technology that enables the creation of dynamic,
Reading Data in Web Pages tMyn1 Reading Data in Web Pages A very common application of PHP is to have an HTML form gather information from a website's.
Chapter 6: Forms JavaScript - Introductory. Previewing the Product Registration Form.
Chapter 4.1 – Deeper into Rails Maciej Mensfeld Presented by: Maciej Mensfeld Deeper into Rails mensfeld.pl github.com/mensfeld senior.
1 PHP and MySQL. 2 Topics  Querying Data with PHP  User-Driven Querying  Writing Data with PHP and MySQL PHP and MySQL.
1 Dr Alexiei Dingli Web Science Stream Advanced ROR.
Lecture 10 Rails Projects Topics SaaSSaaS Readings: SaaS book Ch 2, 4 February 24, 2014 CSCE 740 Software Engineering.
Ruby on Rails Your first app. Rails files app/ Contains the controllers, models, views and assets for your application. You’ll focus on this folder for.
Lecture 11 Rails Topics SaaSSaaS Readings: SaaS book Ch February CSCE 740 Software Engineering.
Chapter 8 Collecting Data with Forms. Chapter 8 Lessons Introduction 1.Plan and create a form 2.Edit and format a form 3.Work with form objects 4.Test.
_______________________________________________________________________________________________________________ PHP Bible, 2 nd Edition1  Wiley and the.
Diagnostic Pathfinder for Instructors. Diagnostic Pathfinder Local File vs. Database Normal operations Expert operations Admin operations.
MEMBERSHIP AND IDENTITY Active server pages (ASP.NET) 1 Chapter-4.
COMP3241 E-Commerce Technologies Richard Henson University of Worcester November 2014.
8 Chapter Eight Server-side Scripts. 8 Chapter Objectives Create dynamic Web pages that retrieve and display database data using Active Server Pages Process.
Ruby on Rails. Web Framework for Ruby Designed to make it easier to develop, deploy, and maintain web applications Design with Model-View-Controller –almost.
Using Microsoft Office Word Assignment Layout. Target Create a Cover Page (Front Page) Create a Table of Contents Page Create a Table of Figures Page.
Text2PTO: Modernizing Patent Application Filing A Proposal for Submitting Text Applications to the USPTO.
Emdeon Office Batch Management Services This document provides detailed information on Batch Import Services and other Batch features.
Chapter 1 Getting Started with ASP.NET Objectives Why ASP? To get familiar with our IDE (Integrated Development Environment ), Visual Studio. Understand.
SchoolSuccess for Coordinators
Section 10.1 Define scripting
JavaScript, Sixth Edition
Managing State Chapter 13.
Development Environment
Running a Forms Developer Application
Unit 9.1 Learning Objectives Data Access in Code
GO! with Microsoft Office 2016
Learning to Program D is for Digital.
SQL and SQL*Plus Interaction
Practical Office 2007 Chapter 10
Data Virtualization Tutorial… CORS and CIS
Play Framework: Introduction
Mobile Application Development Chapter 5 [Persistent Data in Android]
COMP3241 E-Commerce Technologies
Computer Programming I
GO! with Microsoft Access 2016
– Officiating Management Software
Introduction to Programming the WWW I
CMPE 280 Web UI Design and Development October 24 Class Meeting
Intro to PHP & Variables
Key points.
Cookies BIS1523 – Lecture 23.
Unit 27 - Web Server Scripting
Completing the tasks for A452 with….
Unreal Engine and C++ We’re finally at a point where we can start working in C++ with Unreal Engine To get everything set up for this properly, we’re going.
WEB PROGRAMMING JavaScript.
Using Charts in a Presentation
Sirena Hardy HRMS Trainer
Getting Started: Amazon AWS Account Creation
MIS2502: Data Analytics MySQL and SQL Workbench
Web Development Using ASP .NET
Behavioral Driven Development (BDD) (Engineering Software as a Service §7) Philip Ritchey slides generously gifted by Jeff Huang.
Java IDE Dwight Deugo Nesa Matic Portions of the notes for this lecture include excerpts from.
Guidelines for Microsoft® Office 2013
QUICK GUIDE TO CIRCULATION IN ALMA
Chapter 1: Creating a Program.
Presentation transcript:

Forms (Engineering Software as a Service §4.6) © 2013 Armando Fox & David Patterson, all rights reserved

Dealing with Forms Creating a resource usually takes 2 interactions new: Retrieve blank form create: Submit filled form How to generate/display? How to get values filled in by user? What to “return” (render)?

Rails Cookery #3 To create a new submittable form: Identify the action that serves the form itself Identify the action that receives submission Create routes, actions, views for each Form elements’ name attributes will appear as keys in params[] Helpers provided for many common elements

Creating the Form Anatomy of a form in HTML the action and method attributes (i.e., the route) only named form inputs will be submitted Generating the form in Rails often can use URI helper for action, since it’s just the URI part of a route (still need method) form field helpers (see api.rubyonrails.org) generate conveniently-named form inputs http://pastebin.com/k8Y49EhE - how the form helpers are used to create a form - naming form fields as "movie[title]", "movie[rating]", etc. means you end up with params[:movies] as a hash ready to pass to create or update_attributes. This can lead to a security issue, discussed in Chapter 12. http://pastebin.com/3dGWsSq8

END

Which of these would be valid for generating the form that, when submitted, would call the Create New Movie action? = form_tag movies_path do ... end ☐ %form{:action => movies_path, :method => :post} ☐ %form{:action => '/movies', :method => 'post'} ☐ This will create a form with the /movies path and HTTP method post. Does the same thing. Movies_path evaluates to ‘/movies’. Does the same thing, since we can use the symbol :post or string ‘post’. Ultimately it will be converted to a string in HTML. All of the above is correct. All of the above ☐

END

© 2013 Armando Fox & David Patterson, all rights reserved Redirection, the Flash and the Session (Engineering Software as a Service §4.7) © 2013 Armando Fox & David Patterson, all rights reserved

Receiving the Form A neat trick: use debugger to inspect what’s going on start with rails server --debugger insert debugger where you want to stop details & command summary: ESaaS §4.7 NOTE: params[:movie] is a hash, because of the way we named form fields Conveniently, just what Movie.create! wants use ruby-debug to help understand what's going on - set a breakpoint right at the top of MoviesController#create, show that you can print out params[:movies], etc

What View Should Be Rendered for Create Action? Idiom: redirect user to a more useful page e.g., list of movies, if create is successful e.g., New Movie form, if unsuccessful Redirect triggers a whole new HTTP request How to inform user why they were redirected? Solution: flash[]—quacks like a hash that persists until end of next request flash[:notice] conventionally for information flash[:warning] conventionally for “errors” some actions, like create and update, COULD render their own view but that wouldn't be very helpful for the user, so it's idiomatic to use redirect_to to send the user elsewhere. since redirect starts a new http request, we need flash[] . “errors” in quotes because if, e.g., Movie creation fails, the *user* may have made an error but your *app* is working correctly. hence the name 'warning' note, you can put other keys in flash[], these are just the conventional ones. For New Movie form, note that movie was created, or note errors - movie already exists in RP (perhaps with different rating/date), or else the date is illegal (February 30).

Flash & Session session[]: like a hash that persists forever reset_session nukes the whole thing session.delete(:some_key), like a hash By default, cookies store entire contents of session & flash Alternative: store Rails sessions in DB table (Search “rails session use database table”) Another alternative: store sessions in a “NoSQL” storage system, like memcached  in prev lecture we briefly mentioned "NoSQL" storage solutions like sharding. session storage is a great use case for this since there is no sharing.  hence, valuable that rails provides a SEPARATE abstraction for it.

END

True - knock yourself out! Ben Bitdiddle says: “You can put arbitrary objects (not just “simple” ones like ints and strings) into the session[].” What do you think? True - knock yourself out! ☐ True - but a bad idea! ☐ False, because you can’t put arbitrary objects into a hash ☐ False. See the pitfall at the end of Chapter 4. True. See the pitfall at the end of Chapter 4. False. The session operates like a hash, which are key/value pairs, and the value can be any Ruby object type. False. The session can be used like a hash. False, because session[] isn’t really a hash, it just quacks like one ☐

END

Administrivia Get account for “public projects” on PivotalTracker.com, add me, TA Public projects are free Do not get 30 day evaluation account Get account on CodeClimate.com Provides code analysis Free for an open source (OSS) repo Sign in with your GitHub account

END

Finishing CRUD (Engineering Software as a Service §4.8) © 2013 Armando Fox & David Patterson, all rights reserved

Edit/Update Pair is Analogous to New/Create Pair What’s the same? 1st action retrieves form, 2nd action submits it “submit” uses redirect (to show action for movie) rather than rendering its own view What’s different? Form should appear with existing values filled in: retrieve existing Movie first Form action uses PUT rather than POST http://pastebin.com/VV8ekFcn http://pastebin.com/0drjjxGa

Destroy is Easy Remember, destroy is an instance method Find the movie first...then destroy it Send user back to Index def destroy @movie = Movie.find(params[:id]) @movie.destroy flash[:notice] = "Movie '#{@movie.title}' deleted." redirect_to movies_path end Note that @movie is still in memory after it is destroyed, so can still apply title method.

END

If you set an instance variable in a controller method, its value will be retained for how long? This request and all subsequent requests ☐ ☐ Only this request and the next request Only this request - once the view is rendered, the variable is reset to nil ☐ The instance variable will be retained as long as the controller instance is retained. The controller instance is available while the view is rendered (so the view can use the controller instance variables). If you want to save a value, you need to put it in the database or session[]. False. The controller instance is associated with this request. This might be confused with session[]. False. That is the flash[]. True. The controller instance is only active until the view is rendered. False. Ruby does not have static instance variables, in that the instance variables are only local to the instance and so disappear with the instance. It depends on whether the instance variable was declared static ☐

END

© 2013 Armando Fox & David Patterson, all rights reserved Fallacies, Pitfalls, and Perspectives on SaaS-on-Rails (Engineering Software as a Service §4.9 - 4.11) © 2013 Armando Fox & David Patterson, all rights reserved

Fat Controllers & Fat Views Really easy to fall into “fat controllers” trap Controller is first place touched in your code Temptation: start coding in controller method Fat views “All I need is this for-loop” “....and this extra code to sort the list of movies differently” “...and this conditional, in case user is not logged in” No! That’s for model, controller, helpers

Designing for Service-Oriented Architecture A benefit of thin controllers & views: easy to retarget your app to SOA Typically, SOA calls will expect XML or JSON (JavaScript Object Notation, looks like nested hashes) instead of HTML A trivial controller change accomplishes this We have talked about benefits of SOA, and how proper MVC separation makes it easier to turn a user-facing app into a service. Pastebin example shows use of controllers' respond_to() method to turn RottenPotatoes into a RESTful service. http://pastebin.com/bT16LhJ4

END

Only (a) and (b) Only (b) Only (b) and (c) Only (a) and (c) Which steps are ALWAYS required when adding a new action 'foo' to the Movie model of a Rails app: (a) Ensure there is a template to render in app/views/movies/foo.html.haml (or .html.erb, etc) (b) Ensure a route exists in config/routes.rb (c) Implement helper method to generate necessary route-helper URIs Only (a) and (b) ☐ Only (b) ☐ By convention over configuration, the foo action will render foo.html.xxx. A route is needed to specify a controller action. Helper methods are optional. They generate URIs, but the original URIs can be used. In the Rails framework, helper methods are automatically generated. True. False. Only (b) and (c) ☐ ☐ Only (a) and (c)

END

© 2013 Armando Fox & David Patterson, all rights reserved Introducing Cucumber & Capybara (Engineering Software as a Service §7.6) © 2013 Armando Fox & David Patterson, all rights reserved

User Stories => Acceptance Tests? Wouldn’t it be great to automatically map 3x5 card user stories into tests for user to decide if accept the app? How would you match the English text to test code? How could you run the tests without a human in the loop to perform the actions? Need to map from user stories to acceptance tests for test-driven design

Cucumber: Big Idea Tests from customer-friendly user stories Acceptance: ensure satisfied customer Integration: ensure interfaces between modules consistent assumptions, communicate correctly Cucumber meets halfway between customer and developer User stories are not code, so clear to customer and can be used to reach agreement Also not completely freeform, so can connect to real tests

Example User Story 1 Feature ≥1 Scenarios / Feature Feature: User can manually add movie Scenario: Add a movie Given I am on the RottenPotatoes home page When I follow "Add new movie" Then I should be on the Create New Movie page When I fill in "Title" with "Men In Black" And I select "PG-13" from "Rating" And I press "Save Changes" Then I should be on the RottenPotatoes home page And I should see "Men In Black" 1 Feature ≥1 Scenarios / Feature 3 to 8 Steps / Scenario Note that mapping from 3x5 cards to Cucumber can be erroneous, ultimately need user to test. This scenario assumes I can leave the movie date blank.

Cucumber User Story, Feature, and Steps User story: refers to single feature Feature: ≥1 scenarios that show different ways a feature is used Keywords Feature and Scenario identify respective components Kept in .feature files Scenario: 3 - 8 steps that describe scenario Step definitions: Ruby code to test steps Kept in X_controller.rb files

5 Step Keywords Given steps represent state of world before event: preconditions When steps represent event e.g., simulate user pushing a button Then steps represent expected postconditions; check if true / 5. And & But extend previous step

Steps => Step Definitions via Regular Expressions Regexes match English phrases in steps of scenarios to step definitions! Given /^(?:|I )am on the (.+)$/ “I am on the Rotten Potatoes home page” Step definitions (Ruby code) likely use captured string “Rotten Potatoes home page” (?: re) Groups regular expressions without remembering matched text. (?:|I ) will match “I “ and throw it away or match nothing, so strings starting with “I am on ...” will match, and so will “am on …” will match as well.

More on “Cuke” Need to install Cucumber Gem Just for test and development environment, not for production environment When Cucumber installed, it creates commonly used step definitions Need a test database to run app Then edit .features file to add features

Fake User to Try Scenarios? Need tool that pretends to be the user to follow scenarios of user stories Capybara simulates browser Can interact with app to receive pages Parse the HTML Submit forms as a user would Capybara – rat the size of a dog, largest rodent in the world, native to South America Webrat used to be tool for Ruby acceptance testing for web applications

END

Which is FALSE about Cucumber and Capybara? 1. Step definitions are in Ruby, and are similar to method calls, while steps are in English and are similar to method definitions 2. A Feature has one or more Scenarios, which are composed typically of 3 to 8 Steps 3. Steps use Given for current state, When for actions, and Then for consequences of actions False. Step definitions are like method definitions, and steps are like method calls. True. Cucumber matches step definitions to scenario steps using regexes, and Capybara pretends to be a user that interacts with the SaaS app accordingly 4.

END

Running Cucumber and Capybara (Engineering Software as a Service §7.7) © 2013 Armando Fox & David Patterson, all rights reserved

Red-Yellow-Green Analysis Cucumber colors steps Green for passing Yellow for not yet implemented Red for failing (then following steps are Blue) Goal: Make all steps green for pass (Hence green vegetable for name of tool)

Demo Add feature to cover existing functionality Note: This example is doing it in wrong order – should write tests first Just done for pedagogic reasons (Or can look at screencast: http://vimeo.com/34754747) Time for demo in Fall 2012: 10.5 minutes (need to be smoother – turn on mirroriing – practice window selection, copy and paste (or memorize short cuts. Like a navigator ) Type in password saasbook. Start with clear window and center window Mention preconditions, actions, postconditions Create .feature file (Addmovie.feature) Tells you want to do Copies the error message name Find route via rake route Have terminal windows already open for 1) In rottenpotatoes 2) Addmovie.feature in editor in features directory 3) paths.rb in editor in features/support directory Go to VM, tab show feature going to try to run with Cuke Go to Tab to run Cuke on AddMovie.feature Note error message, copy the missing page Go to routes.rb to edit when /^the RottenPotatoes home page/ Go to rake routes to find index mapping '/movies' Try again Go to routes.rb to edit  when /^the Create New Movie page/ Go to rake routes to find new mapping  '/movies/new' Try again – all should pass

END

© 2013 Armando Fox & David Patterson, all rights reserved Enhancing Rotten Potatoes Again (Engineering Software as a Service §7.8) Start at 3:00, end at 9:00, so takes 6 minutes © 2013 Armando Fox & David Patterson, all rights reserved

Add a Real New Feature? What if we add something harder? e.g., includes form to fill in e.g., needs a User Interface e.g., needs to add route to connect view to controller e.g., includes both a happy path and a sad path

Integrated with The Movie Database (TMDb) New Feature: Populate from TMDb, versus enter information by hand Need to add ability to search TMDb from Rotten Potatoes home page Need LoFi UI and Storyboard

Storyboard TMDb Figure 7.6 of Engineering Software as a Service The home page of Rotten Potatoes, which lists all movies, will be augmented with a search box where we can type some title keywords of a movie and a “Search” button that will search TMDb for a movie whose title contains those keywords. If the search does match—the so-called “happy path” of execution—the first movie that matches will be used to “pre-populate” the fields in the Add New Movie page that we already developed If the search doesn’t match any movies—the “sad path”—we should be returned to the home page with a message informing us of this fact. Easy Story Board

Search TMDb User Story (Fig. 7.7 ESAAS) Feature: User can add movie by searching in The Movie Database (TMDb) 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 nonexistent 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." Usually start with happy path; but we’d have to implement method for searching and matching TMDb, which we’ll do in next chapter. (Have to explain both BDD and TDD, so we’ll do BDD first – so don’t do sad path) Instead, do a sad path where can’t find it, and put in dummy method that always fails to find, which makes sad path work. BDD next will go further in TDD to build the method you need. Not a good idea, but works for this chapter. In future, will go back and forth between BDD design and TDD implementation

Haml for Search TMDb Page (Fig. 7.8 ESAAS) -# add to end of app/views/movies/index.html.haml: %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' We will need a new view to go with new UI, and then include a form to fill in Haml – more concise version of Markup Language than HTML, 1st line is search movie. Need to make a name for the action, we’ll call it “search_tmdb” Label is form where fill in the information for movie when it does match Line 3: %h1 Search TMDb for a movie is the text that allows Then I should see “Search TMDb for a movie” to pass. As with any user interaction in a view, we need a controller action that will handle that Web interaction. In this case the interaction is submitting the form with search keywords. Line 5 = form_tag :action => 'search_tmdb' do says that when the form is submitted, the controller action search_tmdb will receive the form submission. http://pastebin/18yYBVbC

Haml Expansion Last Two Lines This Haml: = text_field_tag 'search_terms' = submit_tag 'Search TMDb’ Turns into this HTML: <label for='search_terms'>Search Terms</label> <input id="search_terms" name="search_terms" type="text" /> for attribute of label tag matches id attribute of input tag, from text_field_tag helper (above) 2) the use of the HTML label tag. Figure 2.14 in Chapter 2 tells us that lines 7 and 8 (=...) will expand to the following more verbose HTML markup (<… The key is that the for attribute of the label tag matches the id attribute of the input tag, which was determined by the first argument to the text_field_tag helper called in line 8 of Figure 7.8. This correspondence allows Cucumber to determine what form field is being referenced by the name “Search Terms” in line 11 of Figure 7.7: When I fill in “Search Terms”. . . .

Try Cucumber? If try Cucumber, it fails Missing the route Also MoviesController#search_tmdb is controller action that should receive form, yet not in movies_controller.rb Should use Test Driven Development (future lecture) to implement method search_tmdb Instead, to finish sad path, add fake controller method that always fails

Trigger Fake Controller When Form is POSTed (Fig. 7.9) # add to routes.rb, just before or just after 'resources :movies' : # Route that posts 'Search TMDb' form post '/movies/search_tmdb' http://pastebin/FrfkF6pd we have to make sure there is a route to this new controller action. Above is the line you must add to config/ routes.rb to add a form submission (POST) route to that action

Fake Controller Method: Will Fail Finding Movie (Fig. 7.9) # add to movies_controller.rb, anywhere inside # 'class MoviesController < ApplicationController': def search_tmdb # hardwired to simulate failure flash[:warning] = "'#{params[:search_terms]}' was not found in TMDb." redirect_to movies_path end For now, use fix It to fail, which let’s us complete the sad path. This “fake” controller method always behaves as if no matches were found. It retrieves the keywords typed by the user from the params hash (as we saw in Chapter 3), stores a message in the flash[], and redirects the user back to the list of movies. Recall from Chapter 3 that we added code to app/views/layouts/application.html.haml to display the contents of the flash on every view. http:/pastebin/smwxv70i

END

Which statement is TRUE? 1. Usually you complete the Behavior Driven Design phase with Cucumber before starting the Test Driven Development phase with RSpec 2. Usually you code the sad paths first 1. False. We usually iterate, going back and forth between BDD & TDD. See Figure 7.1. 2. False. We usually code the happy path first. This allows us to get the story basics implemented first. 3. True. That is the example; we put in a dummy method to let us move ahead. 4. False. 3 are true. 3. A sad path can pass without having code written needed to make a happy path pass 4. None of the above is true

END

Running Rotten Potatoes Again (Engineering Software as a Service §7.8) 7 minutes, + 2 minutes Q&A © 2013 Armando Fox & David Patterson, all rights reserved

Demo Add feature to search for movie in TMDb Note: This will be a sad path, in that won’t find it Will use fake method (until future when implement it using TDD) (Or can look at screencast: http://vimeo.com/34754766) When adding a feature, usually need to write new UI, new step definitions, and new controller method. Be sure to save edits. Use tabs from pastebin First step OK, since on RP page {Then I should see ``Search TMDb for a movie'’} should fail (red), because we haven't yet added this text to the home page Try to run cuke on new feature: cucumber features/search_tmdb.feature Says 1 passed, rest failed 2. In book says to fix that view, need to copy code from Figure 7.7, which is in PasteBin. It modifies app/views/movies/index.html.haml. If use vi, be sure to put in paste mode - :set paste (:set nopaste changes mode) Try to run cuke Now complains no route 3. In book says to fix route, need to copy code from Figure 7.9 (top). It modifes config/routes.rb 4. We will also set dummy controller method now from Figure 7.9 (bottom). It modifies app/controllers/movies_controller.rb Try to run cuke, all steps green

Happy Path of TMDb Find an existing movie, should return to Rotten Potatoes home page But some steps same on sad path and happy path How to make it DRY? Background means steps performed before each scenario

TMDb w/2 Scenarios: Background (Fig. 7.10) http://pastebin/icQGrYCV Feature: User can add movie by searching for it in The Movie Database (TMDb) 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 Background: Start from the Search form on the home page Given I am on the RottenPotatoes home page Then I should see "Search TMDb for a movie” Scenario: Try to add nonexistent movie (sad path) 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.” Scenario: Try to add existing movie (happy path) When I fill in "Search Terms" with "Inception" And I should see "Inception”

Cucumber Summary New feature => UI for feature, write new step definitions, even write new methods before Cucumber can color steps green Usually do happy paths first Background lets us DRY out scenarios of same feature BDD/Cucumber test behavior; TDD/RSpec in folllowing chapter is how write methods to make all scenarios pass

END

And in Conclusion Cucumber – “magically” maps 3x5 card user stories onto acceptance tests and integration tests for the application