I am new to TestNG and my task is to test a SportBetting apps API endpoints. To access the endpoints I also should authenticate the user, and somehow keep the session/ cookie to keep the user logged in if I want to test other api endpoints too.
My method looks like this right now:
#Test
public void returnPlayerById(){
RestAssured.baseURI ="http://localhost:8080/sportsbetting-web/players/1";
given().get("http://localhost:8080/sportsbetting-web/players/1").then().statusCode(200).body("player.id[0]", equalTo(1));
}
However it gives the following error:
java.lang.AssertionError: 1 expectation failed.
XML path player.id[0] doesn't match.
Expected: <1>
Actual: <>
I understand, that somehow my method finds nothing. But why? Is it because the code itself is bad, or is it because the authentication is missing? Im very new to this topic. How should I proceed?
Related
I have the following endpoint:
#PutMapping("/{projectIdentifiers}/analysts/{analystEmail}")
public void assignProjectsToAnalyst(#PathVariable List<String> projectIdentifiers, #PathVariable String analystEmail) {
projectService.assignProjectsToAnalyst(projectIdentifiers, analystEmail.toLowerCase());
}
I have a class annotated with #ControllerAdvice which takes care of handling exceptions.
#ExceptionHandler(BadRequestException.class)
#ResponseStatus(BAD_REQUEST)
public ExceptionDTO handleBadRequestException(BadRequestException exception) {
return new ExceptionDTO(exception.getMessage());
}
If I throw an exception, I should get a 400 with the following error message:
{
"errorMessage": "Some error"
}
While testing from Postman and Swagger page, it works as expected, while testing from the react application which calls this endpoint, the network tab in the developer tools in Chrome is showing the backend is responding with a 500.
This doesn't seems to make any sense.
Could it be the fact the the method does not return anything in the endpoint definition?
The class is annotated with #RestController
Since you do not posted your react code, and the error you're getting from your browser. I recommend a way to debug if there is any difference between your browser request and postman request.
In your chrome browser, right click on your request in network tab and then choose "Copy as cURL(bash)"
In your postman, choose the code tab in the right panel (the little "</>" icon), then select cURL in dropdown.
Now you can compare 2 cURL requests. As you said that it works in postman as expected, then there is likely an issue in your browser code :)
I'm using Karate with Gradle, and have 8 feature files that test read / GET functionality for my Spring Boot API.
I'm seeing these tests fail in a way that feels quite random.
The failures are related to Authorisation somehow, but I can't see anything that's wrong on the face of it.
Here's an example,
This fails
Feature: Get Objectives
Background:
* url baseUrl
* def objectiveEndpoint = '/objectives'
* header Authorization = token
Scenario: Get an Objective that exists
Given path objectiveEndpoint + '/37376564-3139-6232-2d66-6631392d3466'
When method GET
Then status 200
And match response contains { objectiveId: '37376564-3139-6232-2d66-6631392d3466' }
And this passes
Feature: Get Assessments
Background:
* url baseUrl
* def assessmentEndpoint = '/assessments'
* header Authorization = token
Scenario: Get an assessment that exists
Given path assessmentEndpoint + '/2900b695-d344-4bec-b25d-524f6b22a93a'
When method GET
Then status 200
And match response contains { odiAssessmentId: '2900b695-d344-4bec-b25d-524f6b22a93a' }
The objective test fails due to a 401 with the following message:
com.intuit.karate.exception.KarateException: objectives-read.feature:12 - status code was: 401, expected: 200, response time: 74, url: http://localhost:8080/objectives/37376564-3139-6232-2d66-6631392d3466, response: {"path":"/objectives/37376564-3139-6232-2d66-6631392d3466","error":"Unauthorized","message":"Unauthorized","timestamp":"2020-06-02T08:04:57.231+0000","status":401}
The assessments test passes.
I'm getting a token by running an Authorisation feature, and storing the result from that into the token variable.
The Auth feature is:
Feature: Log In
Background:
* url 'https://$URL/oauth/token'
* def localSecret = secret
* def localClientId = clientId
Scenario: Get token
Given url 'https://$URL/oauth/token'
And form field grant_type = 'client_credentials'
And form field client_id = localClientId
And form field client_secret = localSecret
And form field audience = 'http://localhost:8080'
When method post
Then status 200
And match response contains { access_token: '#string' }
And def access_token = $.access_token
I then add the token to config, and pass it into each test like this:
var result = karate.callSingle('classpath:login.feature', config);
config.token = 'Bearer ' + result.access_token;
I've confirmed that the token used in the above two features is valid. I've manually tested my API with the token printed in the output of the failed tests, and both of the above tests work fine when I recreate them in Postman. This doesn't feel like a problem with my API because if I rerun the test suite, the tests that fail differ, and on my CI I have a green build with these tests.
I'm experiencing the problem both when running test suites individually like this:
#Karate.Test
Karate testAssessments() {
return Karate.run().relativeTo(AssessmentsRunner.class);
}
and when running all of my tests in parallel like this:
public class SpecTestParallel {
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[]{"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "Test API");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
#Test
void testParallel() {
Results results = Runner.path("classpath:specTests").tags("~#ignore").parallel(5);
generateReport(results.getReportDir());
assertEquals(0, results.getFailCount(), results.getErrorMessages());
}
}
Has anyone had a similar issue before?
As it turns out, this was unexpected behaviour in IntelliJ.
So Karate appears to have a retry policy. If a test failes, it will retry a few times.
When I run tests using the test runner function in IntelliJ, each time a test fails, IntelliJ logs that in the test runner window as it should for a failed test, but Karate keeps running, retries and the test passes. I can see that in the reports now but the IntelliJ test runner doesn't update.
This leads to a confusing situation where tests pass, but appear to fail locally, but the tests pass on CI.
Here is an example of local tests:
and the same commit passing in CI:
I'm not really sure what the fix is here, if there is one. It would be nice if IntelliJ was aware of this behaviour, or maybe Karate could only report the result of a test after all retries have been processed - right now it looks like Karate reports as soon as the first test run is processed.
It's been a confusing few days.
fellow stackoverflowians :)
I've been for quit time to make a Post call using Gmail API.
Been trying to use createDraft and createLabel.
Now I guess I've found how to do this correctly (mostly) but I get this error:
java.lang.AssertionError: 1 expectation failed.
Expected status code <200> but was <400>.
I realise that this error occurs because I make incorrect request.
Could You, guys, help me with this?
Here's my code:
import io.restassured.RestAssured.*
import io.restassured.http.ContentType
import io.restassured.matcher.RestAssuredMatchers.*
import org.hamcrest.Matchers.*
import org.testng.annotations.Test
class RestAPIAutoTestPost {
#Test
fun createLabelInGoogleMail() {
RestAssured.baseURI = "https://www.googleapis.com/gmail/v1/users/me"
val accessToken = "ya29.Glw7BEv6***"
val jsonAsMap = HashMap<String, Any>()
jsonAsMap.put("id", "labelAPITestNameID")
jsonAsMap.put("labelListVisibility", "labelShow")
jsonAsMap.put("messageListVisibility", "show")
jsonAsMap.put("messagesTotal", "0")
jsonAsMap.put("messagesUnread", "0")
jsonAsMap.put("name", "labelAPITestName")
jsonAsMap.put("threadsTotal", "0")
jsonAsMap.put("threadsUnread", "0")
jsonAsMap.put("type", "user")
given().
contentType(ContentType.JSON).
body(jsonAsMap).
`when`()
post("/labels?access_token=$accessToken").
then().
statusCode(200)
}
}
I suppose I use HashMap incorrectly or I use some incorrect body fields.
I've only started to learn restAssured so I beg my pardons for newby question.
Thanks!
P.S. I'd really appreciate for any help with Post methods and puting data into body
I think your use of RestAssured and HashMap is correct. I think you are getting a 400 from this API because you are specifying the id property. By playing with this in Google's API Explorer, I was able to generate 400 errors by doing that. According to the documentation, the only things you need to specify for a POST/Create are: labelListVisibility, messageListVisibility, and name. The id is returned to you as part of the response.
A good feature in RestAssured is that you can have it log what it sends or receives when there is an error or all the time.
Log all requests:
given().log().all()
Log all responses:
`when`().log().all()
Or just when validations fail:
`when`().log().ifValidationFails()
Using that will give you a more precise reason why your interaction with the API is failing because it will show whatever Google is sending back. So we can see for sure if I'm right about the id.
And since you seem to be using Kotlin for this, you might want to take advantage of its great multiline string capabilities and just create the JSON payload manually:
val body = """
{
"labelListVisibility": "labelShow",
"messageListVisibility": "show",
"name": "ThisIsATest"
}
"""
I have two endpoints in my Java Jersey web service:
{host}/{accountNo}
{host}/{accountNo}/service
Due to some problem with other systems i need to add a regex to validate the accountNo, so i only to enter both endpoints if the accountNo is aplhanumeric.
This was my solution:
#Path("/{accNo : [a-zA-Z0-9]*$}") for the first endpoint
#Path("/{accNo : [a-zA-Z0-9]*$}/service") for the second enpoint
The first endpoint is working fine and it validates everything that i wanted
However , every time i try to call endpoint 2 it returns not found.
Can you help me?
The following should work:
#Path("/{accNo: [a-zA-Z0-9]*}/service")
Just remove $ that means end of line.
I have a problem with jmeter regular expressions extractor.
I'm using magento jmeter stress test. https://github.com/magento/magento-performance-toolkit/tree/master/1.14
Problem is in next part. When i put category url and key in settings, jmeter gives me next errors:
Assertion error: false
Assertion failure: true
Assertion failure message: Response was null
This is regular expression extractor:
<a href="http://${host}${base_path}(index.php/)?([a-z0-9-]+)${url_suffix}" class="level
This if from responce assertion:
^[a-z0-9-]+$
Example of url:
http://web.stresstest.com/index.php/my-class.html
The error you're getting is due to a Null response , meaning you didn't get a checkable response.
Could you show the Sampler details and in View Results Tree the request and response ?