Before exploring what Karate has to offer, we'll need to add a few dependencies to our project (assuming you already have your Cucumber dependencies):
We'll also integrate Karate with JUnit using @CucumberOptions and a simple java class in our test directory:
Now let's say our project is given the following application.yaml file:
Using Karate, we can access elements of the above YAML within our Cucumber feature files using the read() function:
Now let's say we have the following JSON file in our test resources that we would like to re-use in multiple tests:
We can in turn access this JSON using the same read() function:
We can even change elements of this JSON at will:
Pretty cool! Now, what if we wanted to create a database connection in the Cucumber file? First, we'll need to add some more dependencies to our project. In our case, we'll be needing a PostgreSQL connection:
Now we'll need some kind of java utilities class to handle the database connection work:
This should be enough to read from the database by instantiating an instance of DbUtils, using Java.type() as a means of telling Karate that we'd like to use this class:
Now, what if our feature file was for whatever reason dependent upon another feature file to run prior to executing our upcoming tests? Perhaps another set of tests that do some database insertion or authorization setup. We can use the call() function to execute an entirely separate feature file:
Neat! Let's take a look at our Cucumber file so far:
We've got full access to our application.yaml, a connection to our local database, and assurance that myOtherTests.feature will be executed prior to running any of our upcoming acceptance tests. Speaking of which, let's write one of those now:
Thanks to Karate's simplicity, much of the above is probably pretty self-explanatory, but we'll go through this line by line just in case. First, notice the "configure headers" line. This tells Karate that we're about to test one of our endpoints, and that test is going to require some headers. We're able to define those headers in pure JSON form. Then, Karate recognizes "url" as a keyword within our Given statement, and understands that the following string is the endpoint we'll want to be calling in our test. We can also explicitly define headers one by one, which is what the "And header Authorization-Header..." line is doing. Now, when we reach "When method GET", Karate makes the GET call to the given url, with our defined headers, all without any additional java test classes or dependencies. Pretty neat!
Lastly, you'll notice the "Then status 200" line. This is to assert that the response to our GET call was indeed a 200. Let's add some more assertions to make sure our endpoint is working exactly as expected:
As you can see, not only can we assert the status code of the response, but we can assert types (check out Karate's documentation for other type assertions), the JSON response itself, and any elements within it that we choose.
What if we wanted to also send a request body along with our endpoint call, say, for a POST?
All we have to do is change our GET to a POST, then add the content of our request body to our Given. That's it! Now we'll try to add an assertion to double-check that our POST properly inserted data into our database:
Because we have our myDatabase object thanks to DbUtils, we're able to simply pass SQL statements straight into our DbUtils methods, returned in JSON form (Note: because our DbUtils readRow() method returns a Map<String, Object>, Karate converts this into a JSON for easy access). No Spring bean @Autowiring or additional Java test classes needed!
You probably noticed that Karate ends up making your feature file a bit less readable to the average business-level non-developer. That is something you'll want to consider when determining whether it's the right tool for your project. But for developers, its magic has the potential to speed up the creation of your acceptance-tests. Karate is also open source, and we encourage you to check out its GitHub (linked below) and documentation to see all it has to offer. Thanks for reading!