How to build an automated API test framework - Part 3
We conclude out series on building API tests in ruby by extending our framework further and adding more tests in
So here we are. The final post on building an automated API framework. We've covered a lot of ground already so if you if you haven't already I would recommend reading the first post on creating a framework with basic checks followed by the second post on extending the framework to handle POST requests. If you are all caught up then let's continue...
Before we start let's take a look at what we have so far:
- spec stores our automated checks
- api a library of API endpoints we use in spec to communication with restful-booker
- payloads a suite of builders to create payloads for POST requests
- gemfile / Rakefile manages the running of our framework and it's dependencies
In the previous posts we've focused on creating basic checks around GET and POST endpoints, but what if we need to create something more complex?
Extending the framework further
For our next check, we want to turn our attention to the DELETE endpoint of restful-booker. The DELETE action itself is simple but there are a few actions we need to cover before executing the DELETE such as:
- Create a booking for deletion and store the ID for later use
- Send a request to the /auth endpoint to get a token to use in the DELETE request
Before we create the check itself lets extend our API library. First, We need to add an additional method in api/booking.rb
def delete_booking(id, token)
begin
return RestClient.delete 'http://localhost:3001/booking/' + id.to_s, :cookie => 'token=' + token
rescue => e
return e.response
end
end
Next, we need to create a new file in api/ named authorise.rb and add the following:
require 'rest-client'
module Authorise
def post_credentials(payload)
begin
return RestClient.post 'http://localhost:3001/auth', payload, :content_type => :json
rescue => e
return e.to_s
end
end
end
Next, /auth
requires a payload with our username and password so let's create a new builder in payloads
class AuthorisePayload
attr_accessor :username, :password
def initialize(&block)
instance_eval &block if block_given?
end
def toJson
return "{
\"username\": \"#{username}\",
\"password\": \"#{password}\"
}"
end
end
Also don't forget to add require './api/authorise'
and require './payloads/authorise_payload'
to spechelper.rb
Creating the DELETE check
With the api and payloads files added let's create our check first include the Authorise
module from api in integration_spec.rb by adding the following under the Booking
include
include Authorise
Then create the check itself
it('DELETE /booking/{id} should return a 200') do
payload = BookingPayload.new do
self.firstname = 'Sally'
self.lastname = 'Jenkins'
self.totalprice = 111
self.depositpaid = true
self.checkin = '11-11-2010'
self.checkout = '12-11-2010'
self.additionalneeds = 'Breakfast'
end
created_response = Booking.create_booking(payload.toJson, :json)
auth_payload = AuthorisePayload.new do
self.username = "admin"
self.password = "password123"
end
auth_response = Authorise.post_credentials(auth_payload.toJson)
delete_response = Booking.delete_booking(JSON.parse(created_response.body)["bookingid"].to_i, JSON.parse(auth_response.body)["token"])
expect(delete_response.code).to be(201)
end
So let's talk through what's going on in this check:
- First, we create a booking payload and use
create_booking
to create the booking we plan to delete. We also store the response increated_response
for later use. - Next are the payload and request to authenticate with restful-booker. Again, we store the response in
auth_response
for use in the delete request - Finally, we take the booking ID for
created_response
to determine which booking to delete and we take the token value fromauth_response
to use in our Cookie header to allow us to make the request. We then assert on the response code.
Conclusion
So what we have created is a check that depends on multiple requests to be called that share various bits of information to be used to build further requests. Using this process we can create user workflows through the application that are much more sophisticated than a simple check on a single API call.
Going forward
And that's it! A copy of the framework can be found here on GitHub for you to compare against. Before I finished I challenge you to take your copy of the framework and extend it. Why not try:
- Creating a check for the PUT endpoint in restful-booker
- Extend the API library to work on different environments
- Use the framework structure to create a series of checks against a different application