Your path to black belt begins here: Java, MongoDB and Karate DSL
When I first heard of Karate DSL I was thinking “what do martial arts have to do with coding?” After a few silly jokes that I’ll spare you, in Clarity AI we realised it’s a great tool for implementing functional tests.
Why? You may ask. Because it has big variety of functionalities such as gherkin-style tests, powerful DSL to access and validate json responses and is easily extensible and customizable to our needs.
After learning more about Karate and following our culture of embracing new technology in Clarity AI, we decided to give Karate a try. How to manage MongoDB basic functions in Karate? How to mix Java implementation and Karate functionalities? These and other questions popped up in my mind in the beginning of the Karate development in our system that was using MongoDB. After resolving those questions I fell like sharing my experience for those who can benefit from it. Hope it helps!
BASIC KARATE CONCEPTS
Karate has three basic concepts: Feature, Background and Scenario.
- Feature is an extension of the files that contain tests. Feature can contain one or more scenarios.
- Scenario is a test case in the Karate feature.
- Background is used for preparing tests execution like defining variables, reading external files, executing other features. It is executed for each scenario.
There are also other functionalities like afterScenario and afterFeature that we will mention in the article. AfterScenario contains functions that are executed after a scenario is executed. AfterFeature contains functions that are executed after a feature is done executing all scenarios. Both functionalities are useful if you want to delete data or reset values after scenario or feature is done running.
JAVA IMPLEMENTATION
KARATE CONFIGURATION
In order to connect to a Mongo database, it is necessary to add these dependencies to the project:
implementation("com.fasterxml.jackson.core:jackson-databind:2.8.8")
implementation("org.slf4j:slf4j-api:1.7.25")
implementation("org.mongodb:mongo-java-driver:3.6.3")
Note that we also added dependencies for the json and logs so it’s easier to track errors and to manage the json files used in the application. They are optional but we recommend them.
MANAGING DATABASE CONNECTION
First of all, we will need a connection to the database. As the connection is not the objective of this article we’re not going to dedicate time to showing different examples of how to implement it. In our case, we opted for a simple connection with only the host and the port as necessary data.
INSERTING DATA INTO THE DATABASE
Once the connection is established, we have to insert data into the database. We recommend implementing a generic method to insert the data so it could be applied in different databases and collections with different objects. In this case, it is necessary to convert our list of objects to MongoDB documents to be able to insert them into the database.
READING DATA FROM THE DATABASE
In the next snippet, you can see an example of reading data from the database. We are going to obtain _id from MongoDB and return the value of it into the Karate test. In order to get the necessary id, we need to find the document by searching with unique field (for example _id) as shown in the Example 3. Once the data is available, it is going to be used as a parameter in the endpoint that you can see in Example 11.
DELETING DATA FROM THE DATABASE
After the test is finished, we remove the data from the database. If the collection only contains the data that was inserted for the test, the whole collection should be removed. Otherwise, be sure to provide unique IDs to delete only test data.
In the next example, you can see a method that deletes various documents. It checks if the field name (passed in the method’s argument) of the document contains ids and if it does, the documents that contain them will be deleted.
DISCONNECTING FROM THE DATABASE
Since we connected to the database with the method, we will need another one to disconnect from it. That method already exists in MongoDB and we are going to encapsulate it in a method as shown in the next example.
Here you can see how the full example of the class.
IMPLEMENTING THE TEST IN KARATE FEATURE
CONNECTING AND DISCONNECTING TO THE DATABASE IN KARATE FEATURE
It is inefficient to connect and disconnect to a database for each individual scenario. Instead, we establish a connection with the database in the background section, then disconnect from the database after all scenarios have run in the afterFeature functionality that Karate offers.
INSERTING DATA INTO THE DATABASE IN A KARATE FEATURE
In each scenario, all necessary data is inserted into the database before calling the endpoint. In this case, the data that we are going to insert is in json format and we have stored it in the application’s resources.
In order to get the data from the json shown previously, you should invoke the method to read en external file. The method’s name is read and it is already implemented in Karate for this purpose. It is only necessary to pass the path of the file you want to upload to the test into the method. After the data from the json is recovered, it can be easily inserted into the database by calling the java method implemented in the Example 2.
GETTING DATA FROM THE DATABASE IN A KARATE FEATURE
You can see how to get data from MongoDB by passing it the database name, collection, field name and field value you want search for in the Example 10 at the line 4.
DELETING DATA FROM THE DATABASE IN A KARATE FEATURE
As mentioned before, after the endpoint call, we delete the data. Note that we are deleting data in the afterScenario functionality that Karate provides. Data will be deleted after the scenario is finished because we do not want the data from this scenario to affect other scenarios that might be run afterwards.
The full example of Karate feature is below.
CONCLUSION
This article explains how to create a test using Karate, Java and MongoDB. Karate has a mechanism that allows you to implement almost any functionality that you want simply by adding the right dependencies to the project and creating Java classes that Karate features can use.
In Clarity AI, Karate helped us make our testing better and we have grown to use it for every new feature we are making. Hopefully this article helps you to implement your tests and to see the range of functionalities that Karate can provide as it did for us.