GithubHelp home page GithubHelp logo

ctco / cukes Goto Github PK

View Code? Open in Web Editor NEW
106.0 18.0 64.0 1.35 MB

Cucumber DSL for testing RESTful Web Services

License: Apache License 2.0

Java 87.68% Groovy 4.04% Gherkin 8.28%
cukes-rest cucumber cucumber-jvm java restapi api-testing

cukes's Introduction

Join the chat at https://gitter.im/ctco/cukes wercker status Maven

cukes-rest logo

cukes-rest takes simplicity of Cucumber and provides bindings for HTTP specification. As a sugar on top, cukes-rest adds steps for storing and using request/response content from a file system, variable support in .features, context inflation in all steps and a custom plug-in system to allow users to add additional project specific content.

Resources

Sample Test

Feature: Gadgets are great!

  Background:
    Given baseUri is http://my-server.com/rest/

  Scenario: Should create another Gadget object
    Given request body from file gadgets/requests/newGadget.json
    And content type is "application/json"

    When the client performs POST request on /gadgets
    Then status code is 201
    And header Location contains "http://localhost:8080/gadgets/"

    When the client performs GET request on {(header.Location)}
    Then status code is 200
    And response contains property "id" with value other than "2000"
    And response contains property "name" with value "Nexus 9"
    And response does not contain property "updatedDate"

There are three sections available to be used in a Feature files:

  • Feature - a description of a feature under test
  • Background - set of steps to be executed before every scenario (usually these are preconditions)
  • Scenario - a single automated test case

As well as three groups of steps available

  • Given - building up a HTTP request to be performed
  • When - executing the request
  • Then - assertions based on a response received

More information can be found in the presentation right here!

Prerequisites

  • JDK 1.6+

Dependency

The dependencies are stored in Maven Central

cukes-rest: core dependency with all you need to get started with the framework (Maven)

<dependency>
    <groupId>lv.ctco.cukes</groupId>
    <artifactId>cukes-rest</artifactId>
    <version>${cukes-rest.version}</version>
</dependency>

Getting Started

There are two options to start local server with Sample Application:

  1. Run SampleApplicaiton.java with following params server server.yml from $MODULE_DIR$
  2. Execute Package/Install Maven phase of the parent project cukes-rest-all

Running tests

Precondition: in order for all tests to pass successfully, please make sure you started fresh instance of Sample Application.

  • To start a specific Feature/Scenario, either change CucumberOption in RunCukesTest.java or run Feature file directly from you IDE
  • To start all tests run RunCukesTest.java from sub-project cukes-rest-sample
  • To start all tests right from Maven, execute test phase in project cukes-rest-sample

cukes's People

Contributors

alexeybuzdin avatar anatoly-antonov avatar andrey-suprun avatar bavhel avatar ctco-scm-github avatar dependabot[bot] avatar eduardrindtata avatar gitter-badger avatar igorgursky avatar igorssh avatar jromero avatar mafnaa avatar martinzg avatar medveduska avatar mike-hmelov avatar ordtesters avatar quesar avatar rhajas avatar richardflint avatar sergeytrasko avatar waffle-iron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cukes's Issues

Show error messege in test

In case than on server side occurs an error we would like to have a possibility to print the error message in test. Right now we just see that status code is not like expected.

When we wait for 200 response with certain value and if that value is matched "FAILURE", then print element from that response (e.g. here "errors")

Number of tests (total, failed, etc.) vary wildly

When running our tests, the reported numbers of test executions vary wildly. Here are some outcomes, based on the same code base, server and test client:

Tests run: 2622, Failures: 14, Errors: 0, Skipped: 8
Tests run: 2609, Failures: 4, Errors: 0, Skipped: 1
Tests run: 2302, Failures: 0, Errors: 404, Skipped: 1268
Tests run: 2623, Failures: 0, Errors: 0, Skipped: 0
Tests run: 2302, Failures: 0, Errors: 404, Skipped: 1268
Tests run: 2609, Failures: 4, Errors: 0, Skipped: 5

I haven't figured out the math here. Adding up the numbers don't match the overall number of tests. Any explanations? Any idea how to fix/improve this? Thanks.

Support for configuration profiles

Add possibility to use different configuration.
Should be configured by system property cukes.profile:
if cukes.profile is null,
then use default cukes.properties
else use filename cukes-${cukes.profile}.properties

Add additional Logging information on async operations

I'd like to see a log entry that tells me how long it finally took to get the correct result.

Hence, with a statement as the following

Given should wait at most 30 seconds with interval 1 seconds until property "status" equal to "SUCCEEDED"

I should see after how many seconds the status finally switched to SUCCEEDED.

Query parameters aren't encoded properly

Hi!

Really like cuke-rest. While writing a test for the JIRA API I think I encountered a bug though...

It seems like the queryParam Type=Shipment AND createdDate>=-1d is encoded "once more" before put in the URL (the % is encoded to %25 and + is encoded to %2B ).
Query params: jql=Type%3DShipment+AND+createdDate%3E%3D-1d
But
Request Url: http://40.68.84.149:8080/rest/api/2/search?jql=Type%253DShipment%2BAND%2BcreatedDate%253E%253D-1d

Se also full log snippet.

test.feature

    Given baseUri from property "jira.base_url"
    And content type is "application/json"
    And queryParam "jql" is "Type=Shipment AND createdDate>=-1d"
    When the client performs GET request on "/search"

cukes.properties

#default - false
cukes.url_encoding_enabled=false
#cukes.relaxed_https=false

Log snippet.

method:	GET
Request params:	<none>
Query params:	jql=Type%3DShipment+AND+createdDate%3E%3D-1d
Form params:	<none>
Path params:	<none>
Multiparts:		<none>
Request URI:	http://40.68.879.149:8080/rest/api/2/search?jql=Type%253DShipment%2BAND%2BcreatedDate%253E%253D-1d
X-AREQUESTID: 911x168628x1
X-ASEN: SEN-8958841
Set-Cookie: atlassian.xsrf.token=B4ZF-PZLU-TF1H-TP28|edfdaca36c2e0ad606d4ffd05c54f7abeda83a4a|lout;path=/
X-AUSERNAME: anonymous
Cache-Control: no-cache, no-store, no-transform
X-Content-Type-Options: nosniff
Content-Encoding: gzip
Vary: User-Agent
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 18 May 2017 15:11:26 GMT
Connection: close
{
    "errorMessages": [
        "Error in the JQL Query: The character '%' is a reserved JQL character. You must enclose it in a string or use the escape '\%' instead. (line 1, character 5)"
    ],
    "errors": {
        
    }
}
HTTP/1.1 400 

Wonder how to create integer variable or other kinds of variables instead of string type via GlobalWorld

@Singleton
class GlobalWorld {

    private final Map<String, String> context = new ConcurrentHashMap<String, String>(); //Source code

    private final Map<String, Object> context = new ConcurrentHashMap<String, Object>(); //wanta it like this

Example:
GivenSteps:

@Given("^let variable \"([^\"]+)\" equal to \"([^\"]+)\"$")
    public void var_assigned(String varName, String value) {
        world.put(varName, value);
    } // ----------------------------------------------------------------------------source code

wanta it support like this

@Given("^let variable \"([^\"]+)\" equal to (\\d+)$")
    public void var_assigned(String varName, int value) {
        world.put(varName, value);
    }

And then in the feature file as below:

  Scenario: add highseas demo
    Given let variable "intVal" equal to 123
    Given request body "{"age":{(age)}}"

I can get the integer value via {(age)} instead of the string type

EOFException when response on POST request has empty body and is gzip encoded

When a POST request returns with response with empty body, a EOFException exception is thrown. See exception stack trace below.

The response on this POST request is valid, the response is returned with "Content-Encoding: gzip", and the information for the newly created resource is returned in the "Location" header.

A workaround might be to deactivate gzip encoding support on the client side via the Accept-Encoding header. I didn't find out how to do that in my 5 min Google research campaign. I appreciate any input to this.

Exception stack trace:
Caused by: java.io.EOFException
at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:279)
at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:269)
at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:175)
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:90)
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:102)
at com.jayway.restassured.internal.http.GZIPEncoding$GZIPDecompressingEntity.getContent(GZIPEncoding.java:66)
at org.apache.http.conn.BasicManagedEntity.getContent(BasicManagedEntity.java:87)
at com.jayway.restassured.internal.http.HTTPBuilder.parseResponse(HTTPBuilder.java:544)
at com.jayway.restassured.internal.RequestSpecificationImpl$RestAssuredHttpBuilder.super$2$parseResponse(RequestSpecificationImpl.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1210)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:132)
at com.jayway.restassured.internal.RequestSpecificationImpl$RestAssuredHttpBuilder.parseResponse(RequestSpecificationImpl.groovy:2034)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
at com.jayway.restassured.internal.RequestSpecificationImpl$RestAssuredHttpBuilder.doRequest(RequestSpecificationImpl.groovy:1970)
at com.jayway.restassured.internal.http.HTTPBuilder.post(HTTPBuilder.java:341)
at com.jayway.restassured.internal.http.HTTPBuilder$post$2.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at com.jayway.restassured.internal.RequestSpecificationImpl.sendRequest(RequestSpecificationImpl.groovy:1137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1210)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:810)
at com.jayway.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:149)
at com.jayway.restassured.internal.filter.SendRequestFilter.filter(SendRequestFilter.groovy:30)
at com.jayway.restassured.filter.Filter$filter$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:73)
at com.jayway.restassured.filter.time.TimingFilter.filter(TimingFilter.java:56)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:73)
at com.jayway.restassured.filter.log.RequestLoggingFilter.filter(RequestLoggingFilter.java:101)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:73)
at com.jayway.restassured.filter.FilterContext$next.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at com.jayway.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1574)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1210)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:810)
at com.jayway.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48)
at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:58)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
at com.jayway.restassured.internal.RequestSpecificationImpl.post(RequestSpecificationImpl.groovy:163)
at com.jayway.restassured.internal.RequestSpecificationImpl.post(RequestSpecificationImpl.groovy)
at lv.ctco.cukesrest.internal.HttpMethod.doRequest(HttpMethod.java:23)
at lv.ctco.cukesrest.internal.ResponseFacade$1.call(ResponseFacade.java:79)
at lv.ctco.cukesrest.internal.ResponseFacade$1.call(ResponseFacade.java:72)
at lv.ctco.cukesrest.internal.ResponseFacade.doRequest(ResponseFacade.java:49)
at lv.ctco.cukesrest.internal.context.InflateContextInterceptor.invoke(InflateContextInterceptor.java:30)
at lv.ctco.cukesrest.api.WhenSteps.perform_Http_Request(WhenSteps.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at cucumber.runtime.Utils$1.call(Utils.java:37)
at cucumber.runtime.Timeout.timeout(Timeout.java:13)
at cucumber.runtime.Utils.invoke(Utils.java:31)
at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:38)
at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
at cucumber.runtime.Runtime.runStep(Runtime.java:299)
at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
at cucumber.runtime.model.CucumberScenarioOutline.run(CucumberScenarioOutline.java:46)
at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
at cucumber.runtime.Runtime.run(Runtime.java:121)
at cucumber.api.cli.Main.run(Main.java:36)
at cucumber.api.cli.Main.main(Main.java:18)

[cukes-rest-loadrunner] Fails to generate LoadRunner scripts on async statement

Feature: createContract

  Background:
    Given content type is "application/json"

  Scenario Outline: shouldCreateSimpleContract
    Given request body from file <contractFile>
    When the client performs POST request on api/contracts
    Then status code is 202

    And should wait at most 30 seconds with interval 1 seconds until property "status" equal to "SUCCEEDED"
    And let variable "NextLocation" equal to header "Location" value

    When the client performs GET request on {(NextLocation)}
    Then status code is 200
    And let variable "contractLink" equal to property "link.find{l->l.rel=='contract'}.href" value

    And the client performs GET request on {(contractLink)}
    Then status code is 200
    And response contains properties from file <contractFile>

  Examples:
    | contractFile                                          |
    | contracts/jsonFiles/contractMinimalAttributes.json    |
    | contracts/jsonFiles/treatyContractSpecialSymbols.json |

Built-in step (Given?) to generate random UUID into variable

Useful for synthetic test data, like

Scenario: Hello world
  Given let variable "paramName" to be random UUID
  And queryParam "name" is "{(paramName)}"
  When the client performs GET request on "/hello"
  Then response equals to "Hello, {(paramName)}"

Wrong error message when field exists but not expected

Unexpected error message appears when field exists but it shouldn't.

For example, step:
And response does not contain property "myNumber"
raise an exception:
java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.String
in case if myNumber is BigDecimal and exists/not null.

Cukes does not suport complex regex expressions

When I try to verify the value 255

Scenario: test
When the client performs GET request on api/contracts/-1
Then status code is 200
And response contains property "sections[?(@.sectionId == -1)].coveredGeoscopes[?(@.coveredGeoscope == 255)].coveredGeoscope" with value "255"

cukes give an error:
java.lang.IllegalArgumentException: Invalid JSON expression:
Script1.groovy: 1: expecting EOF, found '[' @ line 1, column 35.
sections[?(@.sectionId == -1)].coveredGeoscopes[?(@.coveredGeoscope == 255)].coveredGeoscope
^

but when I use the same query in http://jsonpath.herokuapp.com/

it easily find the needed value.
JSON file I can send by e-mail if needed.

Type checks should use JSON instead of JVM types

It seems to me like the following step should take the basic javascript/json data types and not the JVM datatypes. From an outside (business or engineer) when writing test steps you might want to check whether a value is a "number" but according to JSON there is no differentiation based on length instead it's simply a "number" type.

Current:

And response contains property "timeMs" of type "bigdecimal"

Proposal:

And response contains property "timeMs" of type "number"

Full list of accepted types based on http://www.w3schools.com/js/js_datatypes.asp :

  • number
  • string
  • object
  • array
  • null (special case)

Consider using "mockito-core" rather than "mockito-all"

Hello again!

While debugging a NoSuchMethodError with @yegeniy and @iantabolt, I wanted to offer a suggestion to use the mockito-core library rather than mockito-all. mockito-all includes Hamcrest classes, which can clash with Hamcrest classes pulled in as a transitive dependency of JUnit 4.11+ (see below dependency tree for JUnit 4.12).

[INFO] \- junit:junit:jar:4.12:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test

Specifically, cukes-rest version 0.2.13 uses mockito-all version 1.10.8, which includes old Hamcrest classes (I think from 1.1). Notice that the below 1.10.8 version of mockito-all's Hamcrest Matcher class is missing the describeMismatch method.

public interface Matcher<T> extends SelfDescribing {
  boolean matches(Object var1);
  // Missing describeMismatch method!!
  void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

This manifests itself in the following NoSuchMethodError exception when a test fails using JUnit 4.11+.

Scenario: currentTeam hydration                                                        # features/person.feature:2
Given queryParam "hydrate" is "currentTeam"                                            # GivenSteps.query_Param(String,String)
When the client performs GET request on /v1/people/8471675                             # WhenSteps.perform_Http_Request(String,String)
Then response contains property "people[0].currentTeam.teamName" with value "Penguins" # ThenSteps.response_Body_Contains_Property(String,String)
  java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)
    at lv.ctco.cukesrest.internal.AssertionFacadeImpl.bodyContainsPathWithValue(AssertionFacadeImpl.java:103)
    at lv.ctco.cukesrest.internal.switches.SwitchedByInterceptor.invoke(SwitchedByInterceptor.java:33)
    at lv.ctco.cukesrest.internal.context.InflateContextInterceptor.invoke(InflateContextInterceptor.java:30)
    at lv.ctco.cukesrest.api.ThenSteps.response_Body_Contains_Property(ThenSteps.java:64)
    at ✽.Then response contains property "people[0].currentTeam.teamName" with value "Penguins"(features/person.feature:5)

When fixing the dependency, we get a much more helpful error message.

Scenario: currentTeam hydration                                                          # features/person.feature:2
  Given queryParam "hydrate" is "currentTeam"                                            # GivenSteps.query_Param(String,String)
  When the client performs GET request on /v1/people/8471675                             # WhenSteps.perform_Http_Request(String,String)
  Then response contains property "people[0].currentTeam.teamName" with value "Penguins" # ThenSteps.response_Body_Contains_Property(String,String)
    java.lang.AssertionError:
    Expected: Path people[0].currentTeam.teamName contains equal to ignoring type Penguins
         but: was null
      at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
      at org.junit.Assert.assertThat(Assert.java:956)
      at org.junit.Assert.assertThat(Assert.java:923)
      at lv.ctco.cukesrest.internal.AssertionFacadeImpl.bodyContainsPathWithValue(AssertionFacadeImpl.java:103)
      at lv.ctco.cukesrest.internal.switches.SwitchedByInterceptor.invoke(SwitchedByInterceptor.java:33)
      at lv.ctco.cukesrest.internal.context.InflateContextInterceptor.invoke(InflateContextInterceptor.java:30)
      at lv.ctco.cukesrest.api.ThenSteps.response_Body_Contains_Property(ThenSteps.java:64)
      at ✽.Then response contains property "people[0].currentTeam.teamName" with value "Penguins"(features/person.feature:5)

Step format inconsistency

First off, I want to say thank you for the work put into this already.

We initially had our own Http Steps implementations and moved to cuke-rest for the number of features provided out of the box. One of our challenges in moving to this library were in part the inconsistencies when writing a step.

What I mean by this are the following:

  • Some steps use double quotes, others don't
  • Some steps use a colon (:) to denote it accepts a Docstrings

I know it seems minor but a major part of our use of cucumber/guerkin is to make it externally presentable. Also, without proper IDE support it becomes a nightmare to remember nuances.

Examples:

Quotes

And content type is "application/json"
vs
And header Location is not empty

Docstrings

And request body:
"""
{
  "something": "value"
}
"""

vs

And response contains properties from json
"""
{
  "id": 1,
  "userId": "u1",
  "sku": "6mszh9v1sv",
  "store": "apple",
  "storeTransactionId": "t1",
  "status": "current"
}
"""
``

Stop polling queue in case response is recieved

STEP:
And should wait at most 30 seconds with interval 1 seconds until property "status" equal to "SUCCEEDED"

Problem description:
When, for whatever reason, a write operation fails, the test don't stop polling the queue, but the status already received and it is "FAILED".
We would like to have that the test stop polling a queue in case response is received.

LoadRunner - random UUID generation produces duplicates under load

Current implementation relies on time.
Here is corrected version (tested under load):

char *lr_guid_gen()
{
    typedef struct _GUID
    {
        unsigned long Data1;
        unsigned short Data2;
        unsigned short Data3;
        unsigned char Data4[4];
    } GUID;
    char guid[50];
    GUID m_guid;
    lr_load_dll ("ole32.dll");
    CoCreateGuid(&m_guid);
    sprintf (guid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
    m_guid.Data1, m_guid.Data2, m_guid.Data3,
    m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
    m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
    return guid;
}
random_Generator(char* paramname, int length) {
lr_save_string(lr_guid_gen(), paramname);
return 0;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.