Introduction to using SpecFlow tool for testing REST API. For beginners that are at least a bit familiar with test automation, and gives some details and hints.
4. Why not…
SoapUI
Free version issues
Tests less easy to read
Thought there was no CI
Fitnesse
Works poorly with .NET
Wiki markup and tables interface is tiring
Cucumber
Yes – SpecFlow is Cucumber for .NET!
6. BDD / Gherkin language
GIVEN book with ISBN “1-84356-028-3” is in the system
AND it’s available quantity is 9
WHEN I add a book with ISBN “1-84356-028-3”
THEN the book is successfully added to the list
AND available qty. for book with ISBN “1-84356-028-3” is 10
7. The environment
Same tool as
for GUI tests
(Visual Studio,
C#)
Same solution
as GUI tests
and even the
whole system
Convenient!
Developers are
integrated!
9. REST API
Web architectural style with a set of constraints
Web service APIs that adhere to the constraints - RESTful
Frontend
REST API
Backend
External
system(s)
External
system(s)
10. Rest API: typically used HTTP methods
Resource GET PUT POST DELETE
Collection URI,
such as
http://example.com/res
ources
List
collection's
members
Replace
collection with
another
collection
Create new
entry in the
collection
Delete the
entire
collection
Element URI,
such as
http://example.com/res
ources/item17
Retrieve
the member
of the
collection
Replace the
member of the
collection
Not generally
used
Delete the
member of the
collection
11. Example 1
Request
GET https://eshop.com/books/14765
Response
Status: 200 OK
{
"id": “14765",
“title": “Game of Thrones",
“author": “George R. R. Martin",
“isbn": "1-84356-028-3",
“availableQty": “4"
}
12. Example 2
Request
POST https://eshop.com/books
{
“title": “501 Spanish Verbs",
“author": “C. Kendris",
“isbn": "1-84750-018-7",
“availableQty": “10"
}
Response
Status: 200 OK
{
“id": “78953“
}
13. Example 3
Requests
DELETE
https://eshop.com/book/84523
GET https://eshop.com/admin
PUT https://eshop.com/book/24552
{ [some wrong data] }
Responses
Status: 200 OK
Status: 401 Unauthorized
Status: 500 Internal Server Error
14. Why test Rest API?
If used by external applications: this is your UI!
As your system layer:
Can help find / isolate problems:
Security
Performance
Robustness
Functionality
May be more simple to test / automate than GUI tests
18. Step 2: write your test scenarios
ListBooks.feature
Scenario: There are no books in the system
Given there are no books in the system
When I retrieve list of all books
Then I get empty list
Scenario: There are less books than fit into 1 page
Scenario: There are more books than fit into 1 page
Scenario: Sort books
Scenario: Search for a book
19. Step 3: generate scenario steps
[Given(@”there are no books in the list”)]
public void GivenThereAreNoBooksInTheList()
{
ScenarioContext.Current.Pending();
}
20. Step 4: implement scenario steps
Here‘s where the Rest API calls go!
Plain C# can be used or libraries // I use RestSharp
Structure your project
21. Project structure
Features: all features, can have subfolders
Steps: bindings of features to actions
Actions: where things happen
Helpers: among others, RestHelper.cs
Model: classes matching our API data format
App.config: holds base URI
22. A quick look into code: Steps & Actions
Steps
Actions
28. Hooks (event bindings)
Before / after test run static
Before / after feature static
Before / after scenario
Before / after scenario block (given / when / then)
Before / after step
29. Step scope and reusing
Steps are global!
Naming: “when I update it” “when I update the book”
Scoped bindings:
[Scope(Tag="my tag", Feature=“my feature", Scenario=“my scenario")]
Reusing step in other steps
[Given(@"(.*) is logged in")]
public void GivenIsLoggedIn(string name) {
Given(string.Format("the user {0} exists", name));
Given(string.Format("I log in as {0}", name));
}
33. Behaviour /
Business Driven Development
1. PO / QA writes scenarios
2. Developer writes unit/integration tests
3. Developer writes code until tests pass
34. Driving Selenium tests
Scenario: Successful login
Given I am at http://eshop.com/login
When I login with user “John” and password “Password1”
Then I am redirected to http://eshop.com/main
Scenario: Successful login
Given I am in login page
When I login with correct credentials
Then I am redirected to main page
35. SpecFlow & Selenium
using scoped bindings
[When(@"I perform a simple search on '(.*)'", Scope(Tag = “api"))]
public void WhenIPerformASimpleSearchOn(string searchTerm) {
var api = new CatalogApi();
actionResult = api.Search(searchTerm);
}
[When(@"I perform a simple search on '(.*)'"), Scope(Tag = "web")]
public void PerformSimpleSearch(string title) {
selenium.GoToThePage("Home"); selenium.Type("searchTerm", title);
selenium.Click("searchButton");
}
36. Test case management / Test reporting
One functional test suite?
Manual
Automated API
Automated GUI
One report with test list that can be read by
POs and manual QAs
management
customer
Client-server, stateless, cacheable, layered system, code on demand (client-side, optional), uniform interface: identification of resources, manipulation of resources, self-descriptive messages, hypermedia as the engine of the application state.
If I don’t see it in the UI but can access through API – it’s not secured good enough!
Unnecessary API calls made / too much info returned – performance
Misuse of the API finds bugs (insert duplicate record error retrieving list)
Fields you don’t see in UI may be wrong, or just looking from another point of view helps find bugs
In SpecFlow, test scenarios are grouped by features into dedicated feature files
Good example why API needs to be tested. It may be implemented the way that API returns and error if there are no books, but it should be an empty list based on RESTful constraints. GUI might simply display no books if there‘s an error, so you will think all is good. Then you might also wonder if it‘s OK that API returns an error but API doesn‘t show it.
Binding to feature is an anti-pattern, but there are other good uses to scoped bindings, like tags for differentiating between API and GUI tests
Reusing like in this example is for making our steps shorter. In test console we’ll see inner steps. So far I haven’t used this as I found moving out Rest API calls to separate classes is enough, but I can see where it would make sense to use it.
API testing is just one possible use of SpecFlow
And in Steps all Webdriver logic can be placed. PageObject pattern can still be used at it’s fullest. For example, just the way we have Model classes, we can have Page classes.
The slide shows the style that should not and should be used in scenarios.