Extending my solution with API testing capabilities, and troubles with open source projects

This post was published on April 5, 2017

In last week’s blog post, I introduced how I would approach creating a solution for creating and executing automated user interface-driven tests. In this blog post, I’m going to extend the capabilities of my solution by adding automated tests that exercise a RESTful API.

Returning readers might know that I’m a big fan of REST Assured. However, since that’s a Java-based DSL, and my solution is written in C#, I can’t use REST Assured. I’ve spent some time looking at alternatives and decided upon using RestSharp for this example. Why RestSharp? Because it has a clean and fairly readable API, which makes it easy to use, even for non-wizardlike programmers, such as yours truly. This is a big plus for me when creating test automation solutions, because, as a consultant, there will always come a moment where you need to hand over your solution to somebody else. And that somebody might be just as inexperienced when it comes to programming as myself, so I think it’s important to use tools that are straightforward and easy to use while still powerful enough to perform the required tasks. RestSharp ticks those boxes fairly well.

A sample feature and scenario for a RESTful API
Again, we start with the top level of our test implementation: the feature and scenario(s) that describe the required behaviour. Here goes:

Feature: CircuitsApi
	In order to impress my friends
	As a Formula 1 fan
	I want to know the number of races for a given Formula 1 season

@api
Scenario Outline: Check the number of races in a season
	Given I want to know the number of Formula One races in <season>
	When I retrieve the circuit list for that season
	Then there should be <numberOfCircuits> circuits in the list returned
	Examples:
	| season | numberOfCircuits |
	| 2017   | 20               |
	| 2016   | 21               |
	| 1966   | 9                |
	| 1950   | 8                |

Note that I’ve added a tag @api to the scenario. This is so I can prevent my solution from starting a browser for these API tests as well (which would just slow down test execution) by writing dedicated setup and teardown methods that execute only for scenarios with a certain tag. This can be done real easy with SpecFlow. See the GitHub page for the solution for more details.

The step definitions
So, how are the above scenario steps implemented? In the Given step, I handle creating the RestClient that is used to send the HTTP request and intercept the response, as well as setting the path parameter specifying the specific year for which I want to check the number of races:

private RestClient restClient;
private RestRequest restRequest;
private IRestResponse restResponse;

[Given(@"I want to know the number of Formula One races in (.*)")]
public void GivenIWantToKnowTheNumberOfFormulaOneRacesIn(string season)
{
    restClient = new RestClient(Constants.ApiBaseUrl); //http://ergast.com/api/f1

    restRequest = new RestRequest("{season}/circuits.json", Method.GET);

    restRequest.AddUrlSegment("season", season);
}

The When step is even more straightforward: all is done here is executing the RestClient and storing the response in the IRestResponse:

[When(@"I retrieve the circuit list for that season")]
public void WhenIRetrieveTheCircuitListForThatSeason()
{
    restResponse = restClient.Execute(restRequest);
}

Finally, in the Then step, we parse the response to get the JSON field value we’re interested in and check whether it matches the expected value. In this case, we’re not interested in a field value, though, but rather in the number of times a field appears in the response (in this case, the length of the array of circuits). And, obviously, we want to report the result of our check to the ExtentReports report we’re creating during test execution:

[Then(@"there should be (.*) circuits in the list returned")]
public void ThenThereShouldBeCircuitsInTheListReturned(int numberOfSeasons)
{
    dynamic jsonResponse = JsonConvert.DeserializeObject(restResponse.Content);

    JArray circuitsArray = jsonResponse.MRData.CircuitTable.Circuits;

    OTAAssert.AssertEquals(null, test, circuitsArray.Count, numberOfSeasons, "The actual number of circuits in the list is equal to the expected value " + numberOfSeasons.ToString());
}

Basically, what we’re doing here is deserializing the JSON response and storing it into a dynamic object. I wasn’t familiar with the dynamic concept before, but it turns out to be very useful here. The dynamic type can be used for objects of which you don’t know the structure until runtime, which holds true here (we don’t know what the JSON response looks like). Then, we can simply traverse the dynamic jsonResponse until we get to the field we need for our check. It may not be the best or most reusable solution, but it definitely shows the power of the C# language here.

The trouble with RestSharp
As you can see, with RestSharp, it’s really easy to write tests for RESTful APIs and add them to our solution. There’s one problem though, and that’s that RestSharp no longer seems to be actively maintained. The most recent version of RestSharp was released on August 26 of 2015, more than a year and a half ago. There’s no response to the issues posted on GitHub, either, which also doesn’t bode very well for the liveliness of the project. For me, when deciding whether or not to use an open source project, this is a big red flag.

One alternative to RestSharp I found was RestAssured.Net. This project looks like an effort to port the original REST Assured to C#. It looks useful enough, however, it suffers from the same problem that RestSharp does: no activity. For me, that’s enough reason to discard it.

Just before writing this post, I was made aware of yet another possible solution, called Flurl. This does look like a promising alternative, but unfortunately I didn’t have the time to try it out for myself before the due date of this blog post. I’ll check it out during the week and if it lives up to its promising appearance, Flurl stands a good chance of being the topic for next week’s blog post. Until then, you can find my RestSharp implementation of the RESTful API tests on the GitHub page of my solution.

"