Wednesday, 16 September 2015

cucumber bdd


1.  feature files
feature: <brief title>
    as a <role>
    i want a <feature>
    so that i can get <expected benefit>

    # additional background information
    <optional description>

    # acceptance criteria
    scenario: <brief title>
    <optional description>
        given <describe prerequisites>
        when <describe interaction or state change>
        then <describe intended results with "should">


2. scenario
  • each scenario consists a list of steps
  • steps start with keyword 'given', 'and', 'when', 'then', 'but'

3. step definition (generation)
  • each 'given' 'when' 'and' 'then' step can be auto generated but need to be implemented
  • cucumber search feature file and step definitions in classpath when run
  • also mark /src dir as source root so that step function can be found by ide (see link)
  • get rid of the 'throw new pendingException()' at the end of auto generated step function, otherwise junit/testNG will not run
  • how runner find where step definition is: glue = {"com/restassured/example"}
com.nab.ewcs.ubankac.se.FeatureRunner -t @mytest -g classpath:com/nab/ewcs/ubankac/se classpath:features -f html:cucumber-reports/cucumber-pretty --glue /Users/P781889/repo/tracker-SE-test/src/test/java/com/nab/ewcs/ubankac/se/ /Users/P781889/repo/tracker-SE-test/src/test/resources/features

4. background

feature: multiple site support
    as a multiple site owner
    i want to host blogs for different people
    in order to make gigantic piles of money

background:
    given a global administrator named "Greg"
    and a blog named "Greg's anti-tax rants"

scenario: Dr. Bill posts to his own blog
    given I am logged in as Dr. Bill
    when I try to post to "Expensive Therapy"
    then I should see "Your article was published."
  • background is run before each scenarios but after any Before Hooks

5. scenario outline - a list of scenarios

scenario outline: feeding a suckler cow
    given the cow weighs <weight> kg
    when we calculate the feeding requirements
    then the energy should be <energy> MJ
    and the protein should be <protein> kg

    examples:
    | weight | energy | protein |
    | 450      | 26500  | 215      |
    | 500      | 29500  | 245      |


6. 'before' and 'after' hooks

public class StepDefinitions {
     @before("@hook1")
     public void beforeScenario() {
     }

     @after("@hook1")
     public void afterScenario() {
     }
}
    • @before will be run before 1st step of each scenario
    • @before and @after can be used in same manner as in testng to setup and teardown
    • @before hook is useful to setup env while @after hook is useful to clean up env after each run

      7. capture groups

      given User enters Number 123 and String "abc"

      @given("^User enters Number (\\d+) and String \"([^\"]*)\"$") .      //match something in double quote
      public void user_enters_UserName_and_Password(int arg1, String arg2) throws Throwable {
          // write code here that turns the phrase above into concrete actions
          throw new PendingException();
       }

      given a blog post named "Random" with Markdown body  //doc string
       """
      some title, eh?
      ===============
      here is the first paragraph of my blog post.
      lorem ipsum dolor sit amet, consectetur adipiscing elit.
      """

      @given("^a blog post named \"([^\"]*)\" with markdown body$")
      public void a_blog_post_named_with_Markdown_body(String arg1) throws{ }

      given the following animals:   // data table
      | cow   |
      | horse |
      | sheep |

      @given("the following animals:")
      public void the_following_animals(List<String> animals) { }

      given the following users exist:   // data table
      | name  | email | twitter |
      | Aslak | aslak@cucumber.io | @aslak_hellesoy |
      | Julien | julien@cucumber.io | @jbpros |
      | Matt | matt@cucumber.io | @mattwynne |

      @given("^the following users exist:$")
      public void the_following_users_exist(DataTable arg1){ }
      • captured groups are captured 'arguments'
      • capture groups are strings (even when they match digits like \d+). for statically typed languages, cucumber will automatically transform those strings into the appropriate type
      
      
      8. regular expression

      ^I'm logged in$     //begin to end
      .                   //any char
      *                   //preceding token 0 or more times
      +                   //preceding token 1 or more times 
      d                   //any digit
      ?                   //previous token optional
      [^abc]              //anything but abc
      \d                  //match a digital char, same as [0-9]



      9. junit test runner
          @RunWith(Cucumber.class)
          @CucumberOptions(
              features = "Feature"
              ,glue={"stepDefinition"}
              )
          public class CucumberTest {
          }
      •  be careful when using maven, 'cucumber' lib version need to be compatible
          <dependency>
              <groupId>info.cukes</groupId>
              <artifactId>cucumber-java</artifactId>
              <version>1.2.4</version>
          </dependency>
      
          <dependency>
              <groupId>info.cukes</groupId>
              <artifactId>cucumber-junit</artifactId>
              <version>1.2.4</version>
          </dependency>
      
      
      
      10. testNG tester runner
          @CucumberOptions(
          features = "Feature"
          ,glue={"stepDefinition"}
          )
          public class NewTest extends AbstractTestNGCucumberTests{
          }
          <dependency>
              <groupId>info.cukes</groupId>
              <artifactId>cucumber-java</artifactId>
              <version>1.2.4</version>
          </dependency>
          <dependency>
              <groupId>info.cukes</groupId>
              <artifactId>cucumber-testng</artifactId>
              <version>1.2.4</version>
              <scope>test</scope>
          </dependency>  


      11. do not mix Junit and TestNG runner in same Maven project
      • junit runner will need 'cucumber-junit' dependency
      • testNG runner will need 'cucumber-testng' dependency
      • if both dependencies are included in same Maven project, one or both runner will not run properly

      12. writing feature file
      • wording should not be implementation specific
      • ask yourself, will this wording need to change if the implementation does?
      • user parameter to reduce duplicate step functions 
         When I am on "A" website
         Then I check page title is "title_A" 
         When I am on "B" website 
         Then I check page title is "title_B"

      13. @CucumberOptions(tags)
         @CucumberOptions(tags={"@one","@two"}
         Has @one AND @two tag
         @Cucumber.Options(tags = {"@one, @two"}) 
         Has @one OR @two tag 
      
      
      
      

      16. cucumber-jvm convension (works for maven)

      Example
      └───src
          ├───main
             └───java
          └───test
              ├───java
                 └───com
                     └───bensnape
                         └───example
                                 MyStepdefs.java
              
              └───resources
                  └───com
                      └───bensnape
                          └───example
                                  example.feature

      17. cucumber best practice
      • write "declarative" feature in domain specific language
      • insert a narrative
      • use background when necessary

      18. dependency injection in cucumber
      • a single INSTANCE of class is shared between many step definition class that use it
      • you will never need to create the INSTANCE using 'new'
            <dependency>
                  <groupId>info.cukes</groupId>
                  <artifactId>cucumber-picocontainer</artifactId>
                  <version>${cucumber.version}</version>
                  <scope>test</scope>
            </dependency>
            <dependency>
                  <groupId>org.picocontainer</groupId>
                  <artifactId>picocontainer</artifactId>
                  <version>${picocontainer.version}</version>
                  <scope>test</scope>
            </dependency>

            class AccountSteps {
                  KnowsTheDomain helper;  //defined in another class file, can be shared state among
                                                              //many step classes

                  public AccountSteps(KnowsTheDomain helper) {
                        this.helper = helper;
                  }
            }
      • picoContainer created a new instance of KnowsTheDomain for each scenario and injected that instance into every step definition class that needed it

      19. cucumber maven plugin

      20. cucumberjs datatable


      21. cucumberjs rerun failed test cases
      • on the first run add the parameters --format rerun:@rerun.txt
      • after a failed run, remove any arguments specifying the locations of feature files and add @rerun.txt
      ./node_modules/.bin/cucumber-js acceptance-tests/features/*.feature --tags @mytest -r acceptance-tests/steps --format json:acceptance-tests/output/cucumber.json --format rerun:@rerun.txt

      ./node_modules/.bin/cucumber-js @rerun.txt --tags @mytest -r acceptance-tests/steps --format json:acceptance-tests/output/cucumber.json --format rerun:@rerun.txt


      22. junit runner rerun failed test (see link)

      23. cucumberjs run in parallel
      • --parallel 4


      References:
      1. cucumber reference 
      2. toolsQA cucumber java test example
      3. cucumber with testNG 
      4. cucumber java implementation 
      5. cucumber selenium testNG maven example
      6. cucumber "background" keyword
      7. cucumber hooks
      8. cucumber hooks example
      9. cucumber tutorials
      10. cucumber step definition 
      11. regular expression syntax
      12. what does this regex mean?
      13. 15 expert tips for using cucumber 
      14. define step function's location for cucumber jvm 
      15. youtube: cucumber jvm setup 
      16. just enough regex for cucumber
      17. my stackflow question
      18. test your frontend code
      19. cucumber in java - 10 min tutorial
      20. cucumberjs datatable
      21. cucumberjs rerun failed tests
      22. how to rerun failed test cases in cucumber
      23. cucumberjs run feature file in parallel
      24. use maven cucumber reporting plugin
      25. intelliJ cannot find any declarations

      No comments:

      Post a Comment