简体   繁体   中英

How to test non idempotent Web Api endpoints with Specflow

I'm developing a Web API, which features some CRUD operations I want to test.

When running the following scenario the test is expected to pass always given the same parameters.

Scenario: Check each employee's info
Given an Employee's Id is <Id>
When getting the Employee's info
Then the First Name should be <FirstName> and the Last Name should be <LastName>

Examples:
  | Id | FirstName | LastName    |
  | 1  | George    | Georglou    |
  | 2  | John      | Johnopoulos |
  | 3  | Mike      | Mikou       |

On the other hand, when running the following scenario,

Scenario: Create a new Employee
Given an Employee's Fist Name is <FirstName> and Last name is <LastName>
When creating the Employee
Then the status code should be 201

Examples:
  | FirstName | LastName    |
  | Jack      | Jackglou    |

the test is passed only the first time because after that the employee is already created which is logical.

How do I test non idempotent endpoints? Do I need to change the example data each time I'm running the test? What is the best practice?

The general solution is to delete the test data after the test is completed. Unfortunately, there is no general code you can write to accomplish this.

The general process is:

  1. Track the people that get created using the ScenarioContext .

     [Binding] public class EmployeeSteps { private readonly ScenarioContext scenario; private List<Guid> TestEmployees => (List<Guid>)scenario["TestEmployees"]; public EmployeeSteps(ScenarioContext scenario) { this.scenario = scenario; } [Given(@"Given an Employee's First Name is ([^ ]+) and Last name is ([^ ]+)")] public void CreateEmployee(string firstName, string lastName) { var api = new YourAPI(); // <-- however you init your web API service var employeeId = api.CreateEmployee(/* pass whatever you need to here */); TestEmployees.Add(employeeId); } }
  2. In an AfterScenario hook , call API endpoints to delete the people that were created. Initialize this collection of "test employees" in a BeforeScenario hook:

     [Binding] public class Hooks { private readonly ScenarioContext scenario; public Hooks(ScenarioContext scenario) { this.scenario = scenario; } [BeforeScenario] public void CreateTestEmployeeCollection() { // Create list of employee Ids. Use whatever type for List<T> // that your API returns. This example uses a Guid. Could be // and int. Check your API documentation. scenario["TestEmployees"] = new List<Guid>(); } [AfterScenario] public void DeleteTestEmployees() { var api = new YourAPI(); // <-- however you init your web API service var employeesToDelete = (List<Guid>)scenario["TestEmployees"]; foreach (var employeeId in employeesToDelete) { api.DeleteEmployee(employeeId); } } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM