$30 off During Our Annual Pro Sale. View Details »

Getting Started with Cukes-REST

Getting Started with Cukes-REST

Alexey Buzdin

March 14, 2016
Tweet

More Decks by Alexey Buzdin

Other Decks in Programming

Transcript

  1. Testing RESTful API • Acceptance Tests, tests API • End-two-end

    by design • Black Box approach • State is stored on the client
  2. Tools Prerequisites • Low knowledge entry level • Minimum QA

    dependency on developers • Platform / IDE agnostic (Portable) • CI integration • CLI support • License free
  3. REST-assured • Uses Java infrastructure (CLI, CI, etc) • Powerful

    API • Apache License Java library for testing of REST based services. Supports standard HTTP requests types and can be used to validate and verify the response of these requests. Pros • Extensive Java skills requires /Java lib only • No guidelines for tests • Code-as-a-test Cons
  4. • Provide portable/platform agnostic solution for REST-assured tests • Define

    strict RESTful service test guidlines • Lower entry level for new QA engineers • Adopt spec-as-a-test approach with plain text used as definition language Cucumber wrapper for REST-assured library with additional step definition and features Why?
  5. Architecture Overview Cucumber DSL Internal Utilities (File, JSON, XML APIs,

    Templating engine, Context) REST Testing Engine Interface REST-assured implementation ? ? Plugin Interface ..
  6. Architecture Goals • Cucumber RESTful service testing DSL independent of

    Testing Engine provider • REST-assured Testing Engine by default. Possibility to switch providers with no effect on end users • Internal Utilities for JSON, XML processing as well as file API and Tempting engine • Support for custom Recipes and additional functions defined by Testing Engine • Plugin system adds hooks for other developers to add custom project specific logic to the brew
  7. Distribution • Simple JAR dependency • Available in Maven Central

    <dependency>
 <groupId>lv.ctco.cukesrest</groupId>
 <artifactId>cukes-rest</artifactId>
 <version>X.X.X</version>
 <scope>test</scope>
 </dependency> Java Project Non-Java Project • xxx-cukes submodule for API tests inside main project • Separate Maven or Gradle project
  8. Required Tooling • JDK • Maven or Gradle • IntelliJ,

    Eclipse for autocomplete or CLI * Not Supported yet
  9. Gherkin syntax http://docs.behat.org/en/latest/guides/1.gherkin.html Feature: Some terse yet descriptive text of

    what is desired
 In order to realize a named business value
 As an explicit system actor
 I want to gain some beneficial outcome which furthers the goal
 
 Additional text...
 
 Background: everything in place 
 
 Scenario: Some determinable business situation
 Given some precondition
 And some other precondition
 When some action by the actor
 And some other action
 And yet another action
 Then some testable outcome is achieved
 And something else we can check happens too
 
 Scenario: A different situation
 ... my.feature
  10. Gherkin syntax • Feature - Describes the feature for which

    test scenarios are grouped • Background - Describes preconditions for each test scenario • Scenario - single test case
  11. Gherkin syntax Feature: Some terse yet descriptive text of what

    is desired
 In order to realize a named business value
 As an explicit system actor
 I want to gain some beneficial outcome which furthers the goal
 
 Additional text...
 
 Background: everything in place 
 
 Scenario: Some determinable business situation
 Given some precondition
 And some other precondition
 When some action by the actor
 And some other action
 And yet another action
 Then some testable outcome is achieved
 And something else we can check happens too
 
 Scenario: A different situation
 ... my.feature
  12. Scenario syntax Standard BDD style: • Given - precondition /

    set-up • When - testable action • Then - assertion • And, But - additional precondition / testable action / assertion
  13. Multiple Steps inside Scenario Scenario: Some determinable business situation
 Given

    some precondition
 When some action by the actor
 Then some testable outcome is achieved
 Given some other precondition
 When some other action by the actor
 Then something else we can check happens too
  14. The

  15. Comparison Scenario: Server returns OK status code
 When the client

    performs GET request on http://localhost:4567/hello
 Then status code is 200 @Test
 public void serverReturnsOkStatusCode() throws Exception {
 when().get(“http://localhost:4567/hello").
 then().statusCode(200);
 } REST-assured Inspired by REST-assured naming conventions
  16. Sample feature Feature: Simple Resource working
 
 Background:
 Given baseUri

    is http://localhost:4567
 
 Scenario: Server returns OK status code
 When the client performs GET request on /hello
 Then status code is 200
 
 Scenario: Server greets user
 When the client performs GET request on /hello
 Then response equals to "Hello World"
 
 Scenario: Server greets user by name
 Given queryParam "name" is "John"
 When the client performs GET request on /hello
 Then response contains "John"
  17. Variable support Scenario: Server greets user by name
 Given variable

    {(person_name)} is John
 And queryParam "name" is "{(person_name)}"
 When the client performs GET request on /hello
 Then response contains "{(person_name)}" Variable names - alphanumeric (\w+)
  18. Capturing Variables From Response Scenario: 1. New Customer is retrieved

    by ID
 Given request body from file customers/json/newCustomer.json
 When the client performs POST request on /customers
 Then status code is 201
 And header Location end with pattern customers/(.+)
 And let variable “{(location)}" equal to header Location
 
 When the client performs GET request on {(location)}
 Then status code is 200
 And response contains properties from file customers/json/newCustomer.json
  19. Files API Scenario: Request Body
 Given request body “[“id”:”1”]”
 Given

    request body from file C://files/my.txt
 Given request body:
 """
 [ “id”: “1” ]
 """
 
 Given resources root is C://files/
 Given request body from file my.txt
  20. Variable support in Files {
 "id" : "{(client_ID)}",
 "name" :

    "Smith"
 } my.json Scenario: Request Body 
 Given variable {(client_ID)} is 1 Given resources root is src/test/resources/
 Given request body from file my.json …
  21. JSONPath support Scenario: 2. The Customer is updated
 ...
 When

    the client performs GET request on {(location)}
 Then status code is 200
 And response body contains property ”name” equal to “John”
 responseBody {
 "id" : 1,
 "name" : "John"
 }
  22. JSON contains matcher Scenario: 2. The Customer is updated
 ...


    When the client performs GET request on {(location)}
 Then status code is 200
 And response contains properties from file customers/json/updatedCustomer.json
 {
 "name" : "Smith"
 } updatedCustomer.json responseBody {
 "id" : 1,
 "name" : "Smith"
 } Match everything by JSONPath
  23. How

  24. <project …>
 
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 <cucumber.options>--plugin pretty --glue lv.ctco.cukesrest.api

    src/test/resources</cucumber.options>
 <surefire.fork.count>10</surefire.fork.count>
 </properties>
 
 <dependencies>
 <dependency>
 <groupId>lv.ctco.cukesrest</groupId>
 <artifactId>cukes-rest</artifactId>
 <version>X.X.X</version>
 <scope>test</scope>
 </dependency>
 </dependencies>
 
 <build>
 <plugins>
 <plugin>
 <!-- block unit tests execution -->
 <artifactId>maven-surefire-plugin</artifactId>
 <version>2.18.1</version>
 <configuration>
 <forkCount>${surefire.fork.count}</forkCount>
 <reuseForks>false</reuseForks>
 <systemPropertyVariables>
 <cucumber.options>${cucumber.options}</cucumber.options>
 </systemPropertyVariables>
 <includes>
 <include>**/*CukesTest.java</include>
 </includes>
 </configuration>
 </plugin>
 </plugins>
 </build>
 </project>
  25. cukes.properties #default - http://localhost:80
 cukes.base_uri=http://localhost:8080
 
 #default - src/test/resources/
 cukes.resources_root=src/test/resources/features


    
 #cukes.proxy
 
 #default - false
 #cukes.url_encoding_enabled
 #cukes.relaxed_https
 
 #cukes.auth_type
 #cukes.username
 #cukes.password
  26. Parallel tests @RunWith(Cucumber.class)
 @CucumberOptions (tags = {"@misc"})
 public class MiscCukesTest

    {
 } @RunWith(Cucumber.class)
 @CucumberOptions (tags = {"@customers"})
 public class CustomersCukesTest {
 }
 @customers
 Feature: Server provides Customer resource
 ... @misc
 Feature: Simple Resource Working
 ...
  27. Q&A