I have test data based on environments. Need to use respecitive environment test data for webservice testing in karate framework.
So I have config file which load variable based on environment. I have edited my feature file as runtime variable to get the path accordingly something like below. It looks I am missing something or might not using right way.
I have kept testdata based on environment in my folders as like below
TestData
|->DEV
|-> applicationFeature_scenorio1_Req.json
|->SIT
|-> applicationFeature_scenorio1_Req.json
|->UAT
|-> applicationFeature_scenorio1_Req.json
|->PROD
|-> applicationFeature_scenorio1_Req.json
Please help me on this how to pick data based on environment.
Config file
dev: {
baseUrl: 'https://applicationsit.company.com',
TestData : 'TestData/DEV'
},
sit: {
baseUrl: 'https://applicationsit.company.com',
TestData : 'TestData/SIT'
},
uat: {
baseUrl: 'https://applicationuat2.company.com',
TestData : 'TestData/UAT'
},
prod: {
baseUrl: 'https://applicationnewprod.company.com',
TestData : 'TestData/PROD'
}
Feature file
Background:
* def testdata = TestData
#smoke #prod
Scenario: This is success scenario
Given url baseUrl
Given path '/cryptoService'
And request read('#(testdata)/applicationFeature_scenorio1_Req.json')
When method POST
Then status 200
* def encryptedPayload = response
Error found in karate
And request read('#(testdata)/applicationFeature_scenorio1_Req.json')
js failed:
>>>>
01: read('#(testdata)/applicationFeature_scenorio1_Req.json')
<<<<
org.graalvm.polyglot.PolyglotException: java.io.FileNotFoundException: /tmp/workspace/application-prod-test/Continous_Testing/KarateConfigDir/#(testdata)/applicationFeature_scenorio1_Req.json (No such file or directory)
- com.intuit.karate.resource.FileResource.getStream(FileResource.java:98)
- com.intuit.karate.core.ScenarioFileReader.readFileAsStream(ScenarioFileReader.java:99)
- com.intuit.karate.core.ScenarioFileReader.readFileAsString(ScenarioFileReader.java:95)
- com.intuit.karate.core.ScenarioFileReader.readFile(ScenarioFileReader.java:53)
- com.intuit.karate.core.ScenarioEngine.lambda$new$0(ScenarioEngine.java:124)
- <js>.:program(Unnamed:1)
The '#(var)' system works only for JSON: https://github.com/karatelabs/karate#rules-for-embedded-expressions
Karate syntax is mostly JS and variables just work normally. With that in mind please make this change:
And request read(testdata + '/applicationFeature_scenorio1_Req.json')
I am trying to make a simplified version of test report where I am generating a single HTML file report containing only assertion and error response message when there is any (attempting to not publish all the logs and steps).
I understand that we have hooks in karate. However I have looked for karate objects in the github but unable to found any objects where I can extract the response from (to be passed to the js function called on hook)
What I am doing right now is this:
Config:
//karate-config.js
karate.configure('afterScenario', karate.call('classpath:hooks.js'));
Hook:
//hooks.js
//Looking on how to extract the response and log it here
function(){
var info = karate.tags;
karate.log('Tags', info);
}
Am I missing anything on the karate objects? Or this should be achieved in another way?
Thanks a lot!
Try this:
var response = karate.get('response');
EDIT better example:
Background:
* configure afterScenario = function(){ karate.log('***', karate.get("response.headers['X-Karate']")) }
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = 'test'
When method get
# this will fail
Then status 400
I have tried with both karate.get('response') and response directly, and both work. If you use karate.call() pass the response as a parameter.
This question already has an answer here:
How to get id in responseHeaders location?
(1 answer)
Closed last year.
I'm perfoming some test using Karate test.
1st a Post that is expecting a 201 and a location.
2nd use the location from response to perfom a get.
Does anyone know how can I do this with Karate?
The following code is my try, after many other.
Given path 'alpha/test'
And request
"""
{
"id": '#(uuid)',
"content": "test",
"isActive": true
}
"""
When method post
Then status 201
And def endpointLocation = responseHeaders['Location']
And print endpointLocation
Given url 'endpointLocation'
When method get
Then status 200
And match response ==
"""
{
"id": '#(uuid)'
}
"""
But i'm getting:
18:30:12.819 [main] ERROR com.intuit.karate - org.apache.http.client.ClientProtocolException, http call failed after 252 milliseconds for URL: endpointLocation
18:30:12.820 [main] ERROR com.intuit.karate - http request failed:
org.apache.http.client.ClientProtocolException
testApi.feature:263 -
org.apache.http.client.ClientProtocolException
I'm not figuring it out why.
[EDIT]
After sugestion from Peter, that I Thanks!
The print return:
08:59:33.610 [main] INFO com.intuit.karate - [print] [
"https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
Now I'm calling
Given url endpointLocation
and I'm getting
08:59:33.611 [main] ERROR com.intuit.karate - http request failed: java.net.URISyntaxException: Illegal character in scheme name at index 0: ["https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
fraudMgmtApi.feature:263 - java.net.URISyntaxException: Illegal character in scheme name at index 0: ["https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
I was trying also to trim the first and last caracters, creating a:
def trim =
"""
function(myText) { result = myText.substring(1, myText.length-1) }
"""
Or myText.slice(1,-1)
From the error message: http call failed after 252 milliseconds for URL: endpointLocation
It is clear you are setting the url wrong. First try hard-coding it, then make this change, if the endpointLocation variable is set correctly. You can print it to check.
Given url endpointLocation
This question already has an answer here:
How to upload CSV file as a post request in Karate 0.9.0 version?
(1 answer)
Closed 2 years ago.
I have an file upload endpoint (/document) in a controller defined as follows:
#RestController
public class FileUploadController {
#Autowired
private PersonCSVReaderService personCSVReaderService;
#PostMapping(value = "/document", consumes= {MediaType.MULTIPART_FORM_DATA_VALUE})
public void handleFileUpload3(#RequestPart("file") MultipartFile file, #RequestPart("metadata") DocumentMetadata metadata) {
System.out.println(String.format("uploading file %s of %s bytes", file.getOriginalFilename(), file.getSize()));
personCSVReaderService.readPersonCSV(file, metadata);
}
}
I can test this endpoint using Advanced Rest Client (ARC) or Postman by defining the "file" part referencing the people.csv file and a text part specifying some sample metadata JSON.
Everything works fine and I get a 200 status back with the people.csv file contents being written to the console output by the service method:
uploading file people.csv of 256 bytes
{Address=1, City=2, Date of Birth=6, Name=0, Phone Number=5, State=3, Zipcode=4}
Person{name='John Brown', address='123 Main St.', city='Scottsdale', state='AZ', zipcode='85259', phoneNumber='555-1212', dateOfBirth='1965-01-01'}
Person{name='Jan Black', address='456 University Dr.', city='Atlanta', state='GA', zipcode='30306', phoneNumber='800-1111', dateOfBirth='1971-02-02'}
Person{name='Mary White', address='789 Possum Rd.', city='Nashville', state='TN', zipcode='37204', phoneNumber='888-2222', dateOfBirth='1980-03-03'}
Now, I want to run this as an automated Karate test. I have specified a MockConfig :
#Configuration
#EnableAutoConfiguration
#PropertySource("classpath:application.properties")
public class MockConfig {
// Services ...
#Bean
public PersonCSVReaderService personCSVReaderService() {
return new PersonCSVReaderService();
}
// Controllers ...
#Bean
public FileUploadController fileUploadController() {
return new FileUploadController();
}
}
I also have a MockSpringMvcServlet in the classpath and my karate-config.js is :
function fn() {
var env = karate.env; // get system property 'karate.env'
if (!env) {
env = 'dev';
}
karate.log('karate.env system property was:', env);
var config = {
env: env,
myVarName: 'someValue',
baseUrl: 'http://localhost:8080'
}
if (env == 'dev') {
var Factory = Java.type('MockSpringMvcServlet');
karate.configure('httpClientInstance', Factory.getMock());
//var result = karate.callSingle('classpath:demo/headers/common-noheaders.feature', config);
} else if (env == 'stg') {
// customize
} else if (env == 'prod') {
// customize
}
return config;
}
Other karate tests run ok using the mock servlet.
However, when I try this test to test the /document endpoint:
Feature: file upload end-point
Background:
* url baseUrl
* configure lowerCaseResponseHeaders = true
Scenario: upload file
Given path '/document'
And header Content-Type = 'multipart/form-data'
And multipart file file = { read: 'people.csv', filename: 'people.csv', contentType: 'text/csv' }
And multipart field metadata = { name: "joe", description: "stuff" }
When method post
Then status 200
I get this error:
16:14:42.674 [main] INFO com.intuit.karate - karate.env system property was: dev
16:14:42.718 [main] INFO o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
16:14:42.719 [main] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
16:14:43.668 [main] INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
16:14:43.910 [main] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
16:14:44.483 [main] INFO o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
16:14:44.968 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
16:14:45.006 [main] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 2287 ms
16:14:45.066 [main] INFO c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
16:14:45.085 [main] DEBUG c.i.k.mock.servlet.MockHttpClient -
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data
16:14:45.095 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:13 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2
I can only assume that the arguments did not conform to what my endpoint was expecting - I never entered the endpoint in debug mode.
I tried this:
And multipart file file = read('people.csv')
And multipart field metadata = { name: "joe", description: "stuff" }
But that was a non-starter as well.
What am I doing wrong? The people.csv is in the same folder as fileupload.feature, so I am assuming it is finding the file. I also looked at upload.feature file in the Karate demo project given here:
Karate demo project upload.feature
But I could not make it work. Any help appreciated. Thanks in advance.
The Postman request looks like this:
EDIT UPDATE:
I could not get the suggested answer to work.
Here is the feature file:
Feature: file upload
Background:
* url baseUrl
* configure lowerCaseResponseHeaders = true
Scenario: upload file
Given path '/document'
And header Content-Type = 'multipart/form-data'
* def temp = karate.readAsString('people.csv')
* print temp
And multipart file file = { value: '#(temp)', filename: 'people.csv', contentType: 'text/csv' }
And multipart field metadata = { value: {name: 'joe', description: 'stuff'}, contentType: 'application/json' }
When method post
Then status 200
And here is the console output from running that test:
09:27:22.051 [main] INFO com.intuit.karate - found scenario at line: 7 - ^upload file$
09:27:22.156 [main] INFO com.intuit.karate - karate.env system property was: dev
09:27:22.190 [main] INFO o.s.mock.web.MockServletContext - Initializing Spring DispatcherServlet ''
09:27:22.190 [main] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet ''
09:27:23.084 [main] INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a4c7d08f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
09:27:23.327 [main] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.14.Final
09:27:23.896 [main] INFO o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
09:27:24.381 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
09:27:24.418 [main] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 2228 ms
09:27:24.435 [main] INFO com.intuit.karate - [print] Name,Address,City,State,Zipcode,Phone Number,Date of Birth
John Brown,123 Main St.,Scottsdale,AZ,85259,555-1212,1965-01-01
Jan Black,456 University Dr.,Atlanta,GA,30306,800-1111,1971-02-02
Mary White,789 Possum Rd.,Nashville,TN,37204,888-2222,1980-03-03
09:27:24.482 [main] INFO c.i.k.mock.servlet.MockHttpClient - making mock http client request: POST - http://localhost:8080/document
09:27:24.500 [main] DEBUG c.i.k.mock.servlet.MockHttpClient -
1 > POST http://localhost:8080/document
1 > Content-Type: multipart/form-data
09:27:24.510 [main] ERROR com.intuit.karate - http request failed: null
file-upload.feature:14 - null
HTML report: (paste into browser to view) | Karate version: 0.9.2
Note: people.csv file reads successfully and prints in console.
Refer to this part of the docs: https://github.com/intuit/karate#read-file-as-string
So make this change:
* def temp = karate.readAsString('people.csv')
And multipart file file = { value: '#(temp)', filename: 'people.csv', contentType: 'text/csv' }
EDIT: my bad, also refer: https://github.com/intuit/karate#multipart-file
Feature: upload csv
Background: And def admin = read('classpath:com/project/data/adminLogin.json')
Scenario:
Given url baseUrl
And header Authorization = admin.token
And multipart file residentDetails = { read:'classpath:com/project/data/ResidentApp_Details.csv', filename: 'ResidentApp_Details.csv' }
When method POST
Then status 200
Note: Add only one extra line i.e And multipart file residentDetails = { read:'classpath:com/project/data/ResidentApp_Details.csv', filename: 'ResidentApp_Details.csv' }
here is a similar code that im usein
Feature: Create a company instance
Background: Creating the company instance in background
* url baseUrl
* def login = call read('classpath:blackbook/common/getToken.feature')
* def newCI = call read('../endpoints/create_companyinstance.feature')
* def id = newCI.response.data.id
* configure afterScenario =
"""
function(){
var ciID = karate.get('id');
console.log(ciID);
}
"""
After that i will run it. and the login call and newCI call runs fine but then i will get the following error
[ERROR] Scenario: Doing a get call and then some verifications Time
elapsed: 0.005 s <<< ERROR!
java.lang.RuntimeException: unexpected 'configure' key:
'afterScenario'
Please forgive noobness.
Jawad - apologies as I am responsible for prematurely adding documentation for un-released features.
"After hooks" is available in 0.7.0.RC2 - it would be great if you can try that and confirm if it looks good. Even though it is a "release candidate" - as the dev of Karate, I can confirm it should be good for use - and you will not have any breaking changes when "final" arrives (soon).