/
Forms  (Engineering Software as a Service §4.6) Forms  (Engineering Software as a Service §4.6)

Forms (Engineering Software as a Service §4.6) - PowerPoint Presentation

articlesnote
articlesnote . @articlesnote
Follow
342 views
Uploaded On 2020-08-28

Forms (Engineering Software as a Service §4.6) - PPT Presentation

2013 Armando Fox amp David Patterson all rights reserved 1 Dealing with Forms Creating a resource usually takes 2 interactions new Retrieve blank form create Submit filled form How to generatedisplay ID: 810200

search movie tmdb user movie search user tmdb add form steps feature movies cucumber amp action path terms method

Share:

Link:

Embed:

Download Presentation from below link

Download The PPT/PDF document "Forms (Engineering Software as a Servic..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

Forms (Engineering Software as a Service §4.6)

© 2013 Armando Fox & David Patterson, all rights reserved

1

Slide2

Dealing with Forms

Creating a resource usually takes 2 interactionsnew: Retrieve blank formcreate: Submit filled formHow to generate/display?How to get values filled in by user?What to “return” (render)?2

Slide3

Rails Cookery #3To create a new

submittable form: Identify the action that serves the form itself Identify the action that receives submission Create routes, actions, views for eachForm elements’ name attributes will appear as keys in params[]Helpers provided for many common elements

3

Slide4

Creating the FormAnatomy of a form in HTML

the action and method attributes (i.e., the route)only named form inputs will be submittedGenerating the form in Railsoften 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 inputshttp://pastebin.com/k8Y49EhEhttp://pastebin.com/3dGWsSq84

Slide5

5

END

Slide6

%form{:action =>

movies_path

,

:method => :post}

%form{:action => '/movies',

:method => 'post'}

All of the above

=

form_tag

movies_path

do

... end

6

Which of these would be valid for generating the form that, when submitted, would call the Create New Movie action?

Slide7

7

END

Slide8

Redirection, the Flash and the Session(Engineering Software as a Service §4.7)

© 2013 Armando Fox & David Patterson, all rights reserved

8

Slide9

Receiving the FormA neat trick: use debugger to inspect what’

s going onstart with rails server --debuggerinsert debugger where you want to stop details & command summary: ESaaS §4.7NOTE: params[:movie] is a hash, because of the way we named form fieldsConveniently, just what Movie.create! wants 9

Slide10

What View Should Be Rendered for Create

Action?Idiom: redirect user to a more useful pagee.g., list of movies, if create is successfule.g., New Movie form, if unsuccessfulRedirect triggers a whole new HTTP requestHow to inform user why they were redirected?Solution: flash[]—quacks like a hash that persists until end of next requestflash[:notice] conventionally for informationflash[:warning] conventionally for “errors”10

Slide11

Flash & Session

session[]: like a hash that persists foreverreset_session nukes the whole thingsession.delete(:some_key), like a hashBy default, cookies store entire contents of session & flashAlternative: store Rails sessions in DB table(Search “rails session use database table”)Another alternative: store sessions in a “NoSQL” storage system, like memcached

11

Slide12

12

END

Slide13

True - but

a bad idea!

False, because you

can’

t

put arbitrary objects into a hash

False, because

session[]

isn’

t

really a hash, it just quacks like one

True - knock

yourself out!

13

Ben

Bitdiddle

says:

You can put arbitrary objects (not just

simple

ones like

ints

and strings) into the

session[]

.

What do you think?

Slide14

14

END

Slide15

AdministriviaGet account for “public projects” on PivotalTracker.com,

add me, TAPublic projects are freeDo not get 30 day evaluation accountGet account on CodeClimate.comProvides code analysisFree for an open source (OSS) repoSign in with your GitHub account15

Slide16

16

END

Slide17

Finishing CRUD(Engineering Software as a Service §4.8)

© 2013 Armando Fox & David Patterson, all rights reserved

17

Slide18

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 viewWhat’s different?Form should appear with existing values filled in: retrieve existing Movie firstForm action uses PUT rather than POSThttp://pastebin.com/VV8ekFcn

http://pastebin.com/0drjjxGa

18

Slide19

Destroy is EasyRemember, destroy is an

instance methodFind the movie first...then destroy itSend user back to Index def destroy @movie = Movie.find(params[:id]) @movie.destroy flash[:notice] = "Movie '#{@movie.title}' deleted." redirect_to movies_path end 19

Slide20

20

END

Slide21

Only this request and the next request

Only this

request - once

the view is rendered, the variable is reset to nil

It depends on whether the instance variable was declared stati

c

This request and all subsequent requests

21

If you set an instance variable in a controller method, its value will be retained for how long?

Slide22

22

END

Slide23

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

23

Slide24

Fat Controllers & Fat Views

Really easy to fall into “fat controllers” trapController is first place touched in your code Temptation: start coding in controller methodFat 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, helpers24

Slide25

Designing for Service-Oriented Architecture

A benefit of thin controllers & views: easy to retarget your app to SOATypically, SOA calls will expect XML or JSON (JavaScript Object Notation, looks like nested hashes) instead of HTMLA trivial controller change accomplishes thishttp://pastebin.com/bT16LhJ425

Slide26

26

END

Slide27

Only (b)

Only (b) and (c)

Only (a) and (c)

Only (a) and (b)

27

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

Slide28

28

END

Slide29

Introducing Cucumber & Capybara

(Engineering Software as a Service §7.6)

29

© 2013 Armando Fox & David Patterson, all rights reserved

Slide30

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?

30

Slide31

Cucumber: Big IdeaTests from customer-friendly user stories

Acceptance: ensure satisfied customerIntegration: 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

31

Slide32

Example User Story

Feature: User can manually add movieScenario: 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"

32

3 to 8 Steps / Scenario

≥1 Scenarios / Feature

1 Feature

Slide33

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 componentsKept in .feature filesScenario: 3 - 8 steps that describe scenarioStep definitions: Ruby code to test stepsKept in X_controller.rb files

33

Slide34

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

34

Slide35

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”

35

Slide36

More on “Cuke”

Need to install Cucumber GemJust for test and development environment, not for production environmentWhen Cucumber installed, it creates commonly used step definitionsNeed a test database to run appThen edit .features file to add features

36

Slide37

Fake User to Try Scenarios?Need tool that pretends to be the user

to follow scenarios of user storiesCapybara simulates browserCan interact with app to receive pagesParse the HTMLSubmit forms as a user would

37

Slide38

38

END

Slide39

A Feature has one or more Scenarios, which are composed typically of 3 to 8 Steps

Steps use

Given

for current state,

When

for actions, and

Then

for consequences of actions

Cucumber matches step definitions to scenario steps using regexes, and Capybara pretends to be

a user

that interacts with

the SaaS

app

accordingly

Step definitions are in Ruby, and are similar to method calls, while steps are in English and are similar to method definitions

39

Which is FALSE about Cucumber and Capybara?

1.

2.

3.

4.

Slide40

40

END

Slide41

Running Cucumber and Capybara

(Engineering Software as a Service §7.7)

41

© 2013 Armando Fox & David Patterson, all rights reserved

Slide42

Red-Yellow-Green Analysis

Cucumber colors stepsGreen for passingYellow for not yet implementedRed for failing (then following steps are Blue)Goal: Make all steps green for pass (Hence green vegetable for name of tool)

42

Slide43

DemoAdd feature to cover existing functionality

Note: This example is doing it in wrong order – should write tests firstJust done for pedagogic reasons(Or can look at screencast: http://vimeo.com/34754747)

43

Slide44

44

END

Slide45

Enhancing Rotten Potatoes Again(Engineering Software as a Service §7.8)

45

© 2013 Armando Fox & David Patterson, all rights reserved

Slide46

Add a Real New

Feature?What if we add something harder?e.g., includes form to fill ine.g., needs a User Interfacee.g., needs to add route to connect view to controllere.g., includes both a happy path and a sad path

46

Slide47

Integrated with The Movie Database (TMDb)

New Feature: Populate from TMDb, versus enter information by handNeed to add ability to search TMDb from Rotten Potatoes home pageNeed LoFi UI and Storyboard

47

Slide48

Storyboard TMDb

Figure 7.6 ofEngineering Software as aService

48

Slide49

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 TMDbScenario: 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."

49

Slide50

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

'

50

http://pastebin/

18yYBVbC

Slide51

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)

51

Slide52

Try Cucumber?If try Cucumber, it fails

Missing the routeAlso MoviesController#search_tmdb is controller action that should receive form, yet not in movies_controller.rbShould use Test Driven Development (future lecture) to implement method search_tmdbInstead, to finish sad path, add fake controller method that always fails

52

Slide53

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' formpost '/movies/search_tmdb'

53

http://pastebin/

FrfkF6pd

Slide54

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_pathend

54

http:/pastebin/

smwxv70i

Slide55

55

END

Slide56

56

Which statement is TRUE?

Usually you code the sad paths first

A sad path can pass without having code written needed to make a happy path pass

None of the above is true

Usually you complete the Behavior Driven Design phase with Cucumber before starting the Test Driven Development phase with

RSpec

1.

2.

3.

4.

Slide57

57

END

Slide58

Running Rotten Potatoes Again(Engineering Software as a Service §7.8)

58

© 2013 Armando Fox & David Patterson, all rights reserved

Slide59

DemoAdd feature to search for movie in

TMDbNote: This will be a sad path, in that won’t find itWill use fake method(until future when implement it using TDD)(Or can look at screencast: http://vimeo.com/34754766)

59

Slide60

Happy Path of TMDbFind an existing movie, should return to Rotten Potatoes home page

But some steps same on sad path and happy pathHow to make it DRY?Background means steps performed before each scenario

60

Slide61

TMDb w/2 Scenarios: Background (Fig. 7.10)

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 TMDbBackground: 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 press "Search

TMDb

"

  Then I should be on the

RottenPotatoes

home page  And I should see "Inception”

61

http://pastebin/

icQGrYCV

Slide62

Cucumber SummaryNew feature => UI for feature, write new step definitions, even write new methods before Cucumber can color steps green

Usually do happy paths firstBackground lets us DRY out scenarios of same featureBDD/Cucumber test behavior; TDD/RSpec in folllowing chapter is how write methods to make all scenarios pass

62

Slide63

63

END

Slide64

And in ConclusionCucumber –

“magically” maps 3x5 card user stories onto acceptance tests and integration tests for the application

64