How to set up complex relationships? #GivenWhenThenWithStyle

The challenge for this week seems to be the #1 problem with Given-When-Then, according to many people who filled in our survey on this article series. I’ve combined the question from several similar responses:

How to set up complex relationships for the “Given” part (things with 1:n relations and conditions on the children), so that they are easy to follow.

This issue mostly appears with systems that have a big database, and strict data storage requirements. Sometimes it can also happen if there is no database, but the in-memory object model requires a complex network of collaborators to fully operate on something we need to test.

For example, consider an online retailer trying to test order refunds. The retailer buys items from multiple providers, and sells them to customers. To test an order refund, we must first have a valid order. An order must contain at least one (but usually many) order items, which can’t exist in a vacuum. For each order item, we must have a corresponding inventory item. Inventory items must have a name, quantity, and provider. In order to set up a provider, we first need to set up one or more purchase contracts, and for each contract we must set up a billing schedule, and several types of provider contacts (billing, technical, logistics). A valid order also must be created by an active customer. To create the customer we need a payment method, which must be validated first. For personal customers, we have just one contact email. For corporate customers, we might also need to add multiple types of contacts (billing, technical, logistics). Some of that set-up can take a long time, as corporate customer contacts need to be validated by an operator to avoid issues. By the time you’re reading this sentence, you probably forgot what we wanted to test at the start of the paragraph. With concrete data in several rows and columns under each of the sentences, there’s very little chance that anyone will understand what’s going on.

An easy way out of this situation would be to break the model – relax the constraints so the system becomes more easily testable (“Let’s allow orders without any items?”). Although in some cases you may be able to get away with this, to make the challenge more interesting, we’ll want to directly test the functionality involving end-points in that graph of relationships. Here are the rules to try to capture in a good way:

  1. If a customer is asking for a refund because the order was not delivered, we take the responsibility for it. The customer gets a refund (using the original payment method from the order), and a notification about the successful refund. For corporate customers, both the billing and the logistics contacts should receive the notification. The provider is not going to be involved at all in this.
  2. If a customer is asking for a refund because the order was delivered, but one of the items was defective, then the provider of that item takes the responsibility. The customer gets a refund (using the original payment method from the order), with contact notifications as in the previous option, but we also immediately contact the provider about it. The provider billing contact should get a notification about a refund so they can credit our account. The technical contact should get the information supplied by the customer in the refund request, along with the defective item information from the order, and customer’s technical contact information so they can follow up directly. If an order contains items from multiple providers, only the provider supplying the defective item should be contacted, the others should not.

Your challenge is to capture the two requirements in a Given-When-Then spec that’s easy to follow. If you avoid listing any of the information directly in the feature file, which you absolutely should try to do, then also explain briefly how the automation layer is supposed to fill in the missing pieces of the puzzle. (How should it connect the information from the feature file to database items? What’s being set up and how?).

Participate in the challenge

Submit your response by Monday 7th September using the link below. If you plan to post a longer idea, consider publishing it somewhere as a blog or article, and then just submit the published link to the form.

Stay up to date with all the tips and tricks and follow SpecFlow on Twitter or LinkedIn.

PS: … and don’t forget to share the challenge with your friends and team members by clicking on one of the social icons below 👇