I’m a big fan of API libraries like REST Assured for Java and requests for Python, as they both make it really straightforward to write API tests.
Looking at the docs, Pactum seems to be able to do quite a few things. Integration testing, API mocking, contract testing, … It’s all in there. In this blog post, I’ll focus on the API testing (integration testing) capabilities of the library, but I might very well explore some of the other Pactum features in future blog posts and make a series out of it.
The examples you’ll see in this blog post are written using Jest as the testing framework.
Let’s start with the ‘Hello, world!’ of API testing: performing a GET request to an endpoint of choice and checking the HTTP status code of the response. In Pactum, that can be done like this:
pactum.spec() exposes all methods offered by Pactum to construct a request. Since we don’t need to specify anything in terms of headers, cookies or a request body, we can directly invoke an HTTP GET using the
get() method, passing in the endpoint of our choice, and then specify our expectations around the response. In this case, our only expectation is that the HTTP status code equals 200, which we can verify using the
Running the test (using
npm run test which in turns invokes Jest) shows that our test passes:
As a next step, let’s see if we can check the value of a response header, in this case the Content-Type header:
expectHeaderContains() method does exactly what it says on the tin: it looks for a response header and checks that its value contains a predefined expected value, in this case
application/json. One thing to beware of is that for some reason you need to specify the header name in lowercase characters. I initially used
Content-Type, but that made the test fail because it couldn’t find a header by that name.
Oh, and if you want a method that performs an exact match, use
Next, let’s look at the response body. Pactum supports JSON response bodies really well, for other response bodies (plain text, XML, …) support seems to be limited to string-based comparison, which means you’ll have to do a little more work yourself. Our API under test returns data in JSON format, so that’s not a problem here.
Say we want to check that the top level element
name has a value equal to
Leanne Graham in our JSON response. Using the
expectJsonMatch() method in Pactum makes this a straightforward thing to do:
The first argument to
expectJsonMatch() is actually a json-query expression, so it can be used to retrieve nested objects, too, for example:
So, what about POSTing some data to an endpoint instead of retrieving and checking data from an endpoint? It turns out that, too, is really straightforward using Pactum:
Creating a JSON payload is as easy as specifying (creating) it and using the
withJson() method to add it to your request.
As a final example, I often look at how easy it is to create data-driven tests with an API library. Since APIs often expose business logic, and you’ll often need more than one combination of input and corresponding expected output values to properly verify that logic, data-driven tests are a fairly common thing when writing tests for APIs.
Now, Jest does a lot of the heavy lifting for us (like JUnit would in Java, or pytest would in Python) by providing a mechanism for data-driven tests using
All we need to add when writing our Pactum-based test is specify a path parameter using the
withPathParams() method and using that to populate the
Running this test yields the following output:
All code and examples shown in this blog post can be found here."