I am working with:
Spock Core
Spock Reports
Spock Spring
Spring MVC Testing
and I have the following code:
def "findAll() Expected"(){
given: "The URL being used is: /personas/xml/personas"
url = PersonaUrlHelper.FINDALL;
when: "When the URL is being calling with a GET"
resultActions = mockMvc.perform(get(url)).andDo(print())
then: "something..."
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(RequestMappingProducesJsonUtf8.PRODUCES_JSON_UTF_8))
}
Two observations:
One: observe given: "The URL being used is: /personas/xml/personas" where the URL/URI value has been added manually.
Two: the url variable has been defined how an instance variable, because it is common in many test methods. Therefore def String url
My question is:
how I can display the url variable in a Spock's label/block? how (given, then…)? It to be printed through Spock Reports and improve my testing documentation
I have read the following:
Spocklight: Extra Data Variables for Unroll Description
It working around #Unroll. But I did realize all work around the where label/block.
I already have tried something like:
given: "The URL being used is: $url"
given: "The URL being used is: ${url}"
And does not work
I want to work around with a syntax similar like the following:
def "findAll() Expected"(){
url = PersonaUrlHelper.FINDALL;
given: "The URL being used is: $url"
…. something
when: "When the URL is being calling with a GET"
So what could be the correct configuration?
Asume I do a refactor for PersonaUrlHelper.FINDALL used in some Spring's #RequestMapping and in this test method. I don't want update manually the text in the given label/block
So what is the correct syntax?
Quick answer:
I guess the where-block approach will be the right one. Use something like
where: "When the URL is being calling with a GET"
url << PersonaUrlHelper.FINDALL
And remove the definition of url from the test. You will be able to use the url variable, since it is definied in the where-block. And you will be able to reference it from the test description as #url:
#Unroll
def "findAll() Expected"(){
given: "The URL being used is: #url"
//removed url definition
when: "When the URL is being calling with a GET"
resultActions = mockMvc.perform(get(url)).andDo(print())
then: "something..."
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(RequestMappingProducesJsonUtf8.PRODUCES_JSON_UTF_8))
where: "When the URL is being calling with a GET"
url << [PersonaUrlHelper.FINDALL]
}
Another more hacky way would be to print the url just through a println url - this output is also captured afaik, but it wouldn't be as nice.
Update: please take a look at the following spock console script: https://meetspock.appspot.com/script/5146767490285568 :
import spock.lang.*
class PersonalUrlHelper {
final static String FINDALL = 'http://example.com'
}
class MyFirstSpec extends Specification {
#Unroll
def "findAll() Expected #url "(){
given:"The URL being used is: #url"
when: "When URL (#url) is assigned to a"
def a = url
then: "a equals the URL (#url)"
a == url
where: "the URL is fetched from another class or map in this case"
url << [PersonalUrlHelper.FINDALL]
}
}
I tried to mock your script - without having your code.
As you can see, the content of the URL is printed out in the test name. AFAIK, it will also be reflected in the texts of the different test blocks when printed out through spock-reports.
BTW: the [] are important since they turn the returned string into a list with one element. Otherwise the string will be interpreted as lsit and the test will iterate through each character.
Does this help?
Related
My scenario in the top feature file looks like this:
Scenario: Fetch a cat type id and create a cat
* driver.intercept({ patterns: [{ urlPattern: '*api/graphql*'}], mock:
'Mock.feature' })
When I click on the button to add a cat (//first graphql call happens. This gets cat types from the mock as expected)
And input a name
And select the cat type
And click create (//second graphql call happens here. But this returns the cat types again)
Then I see a success message
Here is the mock.feature:
Scenario: karate.match("request contains operationName: 'getCatTypes'")
def response = call read ('response.json')
Scenario: karate.match("request contains operationName: 'AddCat'")
def response = call read ('response1.json')
We use karate standalone jar and on version v1.2.0.RC1 (tried with 1.1.0 as well).
Appreciate any suggestions/directions.
Your use of karate.match() is wrong, note that it does not directly return a boolean. Read this for more: https://stackoverflow.com/a/50350442/143475
Try this change:
Scenario: karate.match("request contains operationName: 'getCatTypes'").pass
I also think there are much better ways to do the above, so read this also: https://stackoverflow.com/a/63708918/143475
I have a rather simple question regarding output step messages in Codeception for which I found no answer in the documentation.
To be more precise: Is there anyway to "alter" the steps output in codeception using an alias?
This:
public function tryToTest(ApiTester $I)
{
$I->sendPOST('/', ['foo' => 'bar']);
$I->seeResponseCodeIs(200);
}
Will output:
I send post "/",{"foo":"bar"}
I see response code is 200
But I would like to alter the "content" with an alias so it can output:
I send post "/", NewCustomerRequest
I see response code is 200
Does Codeception have this capabilities?
No, Codeception has no such capability.
However the right place for such description is in the name of the test.
public function NewCustomerRequest(ApiTester $I)
Also you can use comment actions to add description to the output - amGoingTo, expect, expectTo and comment
https://codeception.com/docs/03-AcceptanceTests#Comments
I am working with:
Spock Core
Spock Reports
Spock Spring
Spring MVC Testing
and I have the following code:
#FailsWith(java.lang.AssertionError.class)
def "findAll() Not Expected"(){
given:
url = PersonaUrlHelper.FINDALL;
when:
resultActions = mockMvc.perform(get(url)).andDo(print())
then:
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_XML))
}
Here the code fails (how is expected) because the method being tested really returns (MediaType.APPLICATION_JSON) instead of (MediaType.APPLICATION_XML).
So that the reason of #FailsWith(java.lang.AssertionError.class).
Even if I use #FailsWith(value=java.lang.AssertionError.class, reason="JSON returned ...") I am not able to see the reason through Spock Reports
Question One: how I can see the reason on Spock Reports?.
I know Spock offers the thrown() method, therefore I am able to do:
then:
def e = thrown(IllegalArgumentException)
e.message == "Some expected error message"
println e.message
Sadly thrown does not work for AssertionError.
If I use thrown(AssertionError) the test method does not pass, unique way is through #FailsWith but I am not able to get the error message from AssertionError
Question Two how is possible get the Error Message from AssertionError?
I know I am able to do something like
then: "Something to show on Spock Reports"
But just curious if the question two can be resolved..
regarding Question one:
if you look at FailsWithExtension#visitFeatureAnnotation you can see that only value from the #FailsWith is evaluated, reason is not touched at all. What you could do is introduce you own type of annotation (custom one, e.g. same as #FailsWith) and override AbstractAnnotationDrivenExtension#visitFeatureAnnotation. There you have access to reason parameter.
regarding Question two:
please look at this link: http://spock-framework.3207229.n2.nabble.com/Validate-exception-message-with-FailsWith-td7573288.html
additionally maybe you could override AbstractAnnotationDrivenExtension#visitSpec and add custom listener (overriding AbstractRunListener). Then you have access to AbstractRunListener#error method whose documentation says:
Called for every error that occurs during a spec run. May be called multiple times for the same method, for example if both
* the expect-block and the cleanup-block of a feature method fail.
Didn't test for Question two, but it may work. I've used sth similar.
Enjoy,
Tommy
In SoapUI, I have a host Test Case, which executes another external Test Case (with several test steps) using the "Run Test Case" test step. I need to access a response from the external TC from within my host TC, since I need to assert on some values.
I cannot transfer the properties since they are in XML. Could I get some pointers as to how I could leverage Groovy/SoapUI for this.
For Response you can use the below code.
testRunner.testCase.getTestStepByName("test step").testRequest.response.responseContent
In you external TC create another property and at the end of the TC use Transfer Property step to transfer your XML node to it. In your host TC, just read that property as you would any other.
I also had a look around to see if this can be done from Groovy. SoapUI documentation says that you need to refer to the external name of the testsuite / testcase:
def tc = testRunner.testCase.testSuite.project.testSuites["external TestSuite"].testCases["external TestCase"]
def ts = tc.testSteps["test step"]
But I could not find how to get at the Response after that.
In addition to Guest and SiKing answers, I share a solution to a problem that I've met:
If your step is not of type 'request' but 'calltestcase' you cannot use Guest answer.
I have a lot of requests contained each in a testCase and my other testCases call these testCases each time I need to launch a request.
I configured my request testCases in order to return the response as a custom property that I call "testResponse" so I can easily access it from my other testCases.
I met a problem in the following configuration :
I have a "calltestcase" step that gives me a request result.
Further in the test I have a groovy script that needs to call this step and get the response value
If I use this solution :
testRunner.runTestStepByName("test step")
followed by testRunner.testCase.getTestStepByName("test step").testRequest.response.responseContent
I'm stuck as there is no testRequest property for the class.
The solution that works is :
testRunner.runTestStepByName("test step")
def response_value = context.expand( '${test step#testResponse#$[\'value\']}' )
another solution is :
testRunner.runTestStepByName("test step")
tStep = testRunner.testCase.getTestStepByName("test step")
response = tStep.getPropertyValue("testResponse")
Then I extract the relevant value from 'response' (in my case, it is a json that I have to parse).
Of course it works only because I the request response as a custom property of my request test case.
I hope I was clear enough
I'm very new at JMeter issues.
In a test script i have a BeanShell PreProcessor element that updates some variables previously defined at a "User Defined Variables" element.
Latter those variables are used in "Http Requests". However, the value that is used in the http request is the default one.
The scripts seems to be working due to some debug print();
My question is if it's necessary to delay the script to be sure that the BeanShell finishes?
Thanks a lot for your attention
There is no need to put any delay to Beanshell Pre-Processor as it's being executed before request. I'd recommend to check your jmeter.log file to see if there are any scripting issues as Beanshell Pre-Processor does not report errors anywhere including View Results Tree listener.
There are at least 2 ways to assure that everything is fine with your Beanshell script:
Put your debug print code after variables replace logic to see if it fires
Use JMeter __Beahshell function right in your HTTP request. If it's ok - View Results Tree will demonstrate beanshell-generated value. If not - the field will be blank and relevant error will be displayed in the log.
Example test case:
Given following Test Plan structure:
Thread Group with 1 user and 1 loop
HTTP GET Request to google.com with path of / and parameter q
If you provide as parameter "q" following beanshell function:
${__BeanShell(System.currentTimeMillis())}
and look into View Results Tree "Request" tab you should see something like:
GET http://www.google.com/?q=1385206045832
and if you change function to something incorrect like:
${__BeanShell(Something.incorrect())}
you'll see a blank request.
The correct way of changing existing variable (or creating new if variable doesn't exist) looks like
vars.put("variablename", "variablevalue");
*Important: * JMeter Variables are Java Strings, if you're trying to set something else (date, integer, whatever) to JMeter Variable you need to cast it to String somehow.
Example:
int i = 5;
vars.put("int_i", String.valueOf(i));
Hope this helps.
You can update the vale of a "user defined variable".
You have to create a bean shell sampler
vars.put("user_defined_variable", "newvalue");
#theINtoy got it right.
http://www.blazemeter.com/blog/queen-jmeters-built-componentshow-use-beanshell
I'm new to jmeter too but as I know variables defined in "User defined variables" are constants, so you can't change them. I recommend to use "User Parameters" in preprocessors or CSV Data Set Config.