API testing, be it REST, SOAP, JSON, XML or GraphQL, can be tricky – both from perspectives of the testing code itself and from maintaining it up to date as it evolves over time. However, by using Karate Framework you can overcome these struggles! Karate Framework helps get rid of the boilerplate code which is involved in performing the requests and asserting the response contents. In addition, it provides a descriptive language based on Cucumber that allows tests to be easily written and understood even by non-programmers.
In order to demonstrate a bit of the framework, we need first an accessible API. Let’s use a playground project from Best Buy. The setup is fairly easy to have it up and running in a few minutes. After the playground API is running, it is time to get started with the API testing.
Let’s use a Maven archetype to boost the project quickly.
Our development environment will be Intellij Idea CE with Cucumber Plugin, Java 8 and Maven 3.
Create a folder to host the test project and run the command below:
mvn archetype:generate \ -DarchetypeGroupId=com.intuit.karate \ -DarchetypeArtifactId=karate-archetype \ -DarchetypeVersion=0.5.0 \ -DgroupId=io.testproject \ -DartifactId=api-testing
At this point, you have the project structure ready to start writing the tests. The archetype comes with some testing samples, but we will write our own. Let’s create one package folder and name it features under src/test/java. This is where all the feature files will reside.
In order to run tests on feature files, you will need one class at the root of our features folder like the one below:
APITest.java package features; import com.intuit.karate.junit4.Karate; import org.junit.runner.RunWith; @RunWith(Karate.class) public class APITest { }
This class is needed so the Maven test phase picks up the test files and runs all the tests recursively on the sub-folders. Now we can proceed and create our first feature file. Let’s create a file called products.feature under src/test/java/features/products.
This is how your project structure should look like:
We can add the first test as below:
products.feature Feature: Verify that products are properly returned by the API Background: * url 'http://localhost:3030' Scenario: Products are returned on GET Given path 'products' When method get Then status 200
This is a very basic test: it just verifies that after we perform a GET on the /products endpoint, we should receive an HTTP code 200 that implies a successful call. After we are finished we can call mvn test and see the test output. The feature file will be executed, with all the scenarios and steps on it.
Let’s add another scenario to check more advanced tests:
products.feature #existing content of products.feature Scenario: Specific product has minimum required data to be displayed Given path 'products/9132294' When method get Then status 200 And match $ == { price: #notnull, description: #notnull, image: #notnull }
Now we are navigating to a specific product and verifying it contains the minimum information to be displayed in the website. We need to check whether it has price, description and image. Let’s run the mvn test again.
We can see our first test failure. The == operator tells the framework to expect exactly the 3 fields in question, but as the response has several others, it fails. In order to verify the response has at least the 3 fields we expect, we need to correct it by using the contains operator:
products.feature #existing content of products.feature Scenario: Specific product has minimum required data to be displayed Given path 'products/9132294' When method get Then status 200 And match $ contains { price: #notnull, description: #notnull, image: #notnull }
And now the test works as expected. Karate implements JsonPath expressions to traverse on the response fields, which makes it easier to interact. We can add one small example to our last feature:
products.feature #existing content of products.feature Scenario: Specific product has minimum required data to be displayed Given path 'products/9132294' When method get Then status 200 And match $ contains { price: #notnull, description: #notnull, image: #notnull } And match $.categories contains { id: #notnull, name: #notnull, createdAt: #notnull, updatedAt: #notnull }
That’s it, we are now able to navigate to the categories array and evaluate its content without writing complicated matchers or delicate string manipulations.
This tutorial highlights some of the core features of Karate Framework that will allow you to create a bullet-proof API Testing with very little setup, a learning curve and deliver robust and easy-to-maintain tests. For a more comprehensive feature list, please check Karate project in Github. The code found on this sample project can be found at my Github.
What do you think of API testing with Karate Framework? You are welcome to leave your thoughts and questions in the comment section below. Happy Testing! 😎
Hi Neil,
Great Tool and very well explained.
I am trying to configure the project using Karate API in my eclipse JAVA EE for Developer and IntelliJ Community edition. But there in feature file steps are looking for glue code. Could you please help me resolve the issue.
Thanks,
Sangamesh
Hi Sam,
Thanks, glad you liked it!
Personally, I use Visual Studio Code with a couple of plugins to aid development, such as this one: https://marketplace.visualstudio.com/items?itemName=alexkrechik.cucumberautocomplete. I think it is lighter in terms of configuration than Eclipse and IDEA for this use case.
Best,
Neill
Hi Neill,
I want help for validating API response using karate framework.
I have API’s which are “independent” on each other.
I have POST method along with request parameters. when I hit that particular API got the response with different parameters (no single match from request parameter and response parameter).
Now I want to validate response parameter value. how to do it.
I tried using reponse.contains but it always “Pass” the result.
example : request: “method” post
school name: “abcd”
register date : “1:10:2010″
Response:
Principle name : ” pqrs”
Principle Email id “[email protected]
now I want to validate that “principle name ” should not be null
I have implemented like this but it it doesn’t work
Feature: School info
Background:
* url baseUrl
Scenario: check Principles info
Given path ‘School info’
And request {school name: “abcd” ,register date : “1:10:2010”}
When method post
Then status 200
And match response.response contains {“type”: “Success”,”code”:20000}
And match response.principle list[*] { “Principle name”: “#notnull”}
Hi Jo,
I think the best way would be to use: https://github.com/intuit/karate#referring-to-self. If that doesn’t solve the problem, I am not sure I followed it correctly.
Best,
Neill
Hi Neill,
{Sorry for long post}
if possible share your comment on my below query.
I am executing the Karate Suite through Jenkins job which is maven based. While execution the job ends it with comment like
[INFO] — maven-surefire-plugin:2.12.4:test (default-test) @ Karate_Digital —
[INFO] Skipping execution of surefire because it has already been run for this configuration
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
I am clueless as not able to execute my suite through Maven in my IDE too with the similar message.
My POM looks like below
4.0.0
Karate_Digital
Karate_Digital
0.0.1-SNAPSHOT
jar
UTF-8
1.8
3.6.0
0.9.1
com.intuit.karate
karate-jersey
${karate.version}
test
com.intuit.karate
karate-junit4
${karate.version}
test
net.masterthought
cucumber-reporting
4.5.1
<!– src/test/java
**/*.java
–>
org.apache.maven.plugins
maven-compiler-plugin
${maven.compiler.version}
Problem Statement
true
report-only
UTF-8
${java.version}
${java.version}
-Werror
digital_statement_automation_team/src/test/java/com/barclaycard/qe/runner
**/*Runner_API.java
Hi Neill,
I have an existing automation framework with Java Junit appium and gradle to test mobile app.
There are some user scenarios where I need to make few changes in customer profiles. I want to reset the test data after making that change, so I am thinking of using Karate to make those api calls instead of automating the UI part which is time consuming.
Can you please assist how I can integrate it with my existing Appium automation framework?
Cheers
Udit Choudhary
Anyone has tried NTLM authentication ?? if someone can help
Great tool and well explained