Question

I've got a handful of specflow tests that look something like this:

Scenario: Person is new and needs an email
Given a person
And the person does not exist in the repository
When I run the new user batch job
Then the person should be sent an email

Scenario: Person is not new and needs an email
Given a person
And the person does exist in the repository
When I run the new user batch job
Then the person should not be sent an email

Except instead of just 2 scenarios, I've got 10 very similar scenarios, all with the type of steps so I want to use a "Scenario Outline". Unfortunately, I'm having a really hard time coming up with a readable way to re-write my steps.

Currently, I've come up with this but looks clunky:

Scenario: Email batch job is run
Given a person
And the person '<personDoes/NotExist>' exist in the repository
When I run the new user batch job
Then the person '<personShould/NotGetEmail>' be sent an email

Examples:
| !notes   | personDoes/NotExist | personShould/NotGetEmail |
| Exists   | does not            | should                   |
| No Exist | does                | should not               |

I also considered this, and while it is cleaner it doesn't convey meaning nearly as well

Scenario: Email batch job is run
Given a person
And the person does exist in the repository (is '<personExist>')
When I run the new user batch job
Then the person should be sent an email (is '<sendEmail>')

Examples:
| !notes   | personExist | sendEmail |
| Exists   | false       | true      |
| No Exist | does        | false     |

Does anybody have a better way of parameterizing concepts like "does", "does not", "should", "should not", "has", "has not"? At this point, I'm thinking about leaving the everything as a different scenario because it is more readable.

Was it helpful?

Solution

Here is what I've done in the past:

Given these people exist in the external system
| Id | First Name | Last Name | Email |
| 1  | John       | Galt      | x     |
| 2  | Howard     | Roark     | y     |
And the following people exist in the account repository
| Id | External Id | First Name | Last Name |
| 45 | 1           | John       | Galt      |
When I run the new user batch job
Then the following people should exist in the account repository
| External Id | First Name | Last Name | Email |
| 1           | John       | Galt      | x     |
| 2           | Howard     | Roark     | y     |
And the following accounts should have been sent an email
| External Id | Email |
| 2           | y     |

You can use the table.CreateSet() and table.CreateSet() helper methods in SpecFlow to quickly turn the tables into data for your fake external system repository and your account table in the database.

Then you can use table.CompareToSet(accountRepository.GetAccounts() to compare the table in your "Then" clause to the records in your database.

The neat thing is, all of the steps you wrote are reusable for multiple situations. All you do is change the data in the tables, and SpecFlow writes the tests for you.

Hope that helps!

OTHER TIPS

Maybe you should split them into two scenarios

Scenario Outline: User exists in the repository
Given a person
| Field | Value   |
| First | <first> |
| Last  | <last>  |
And the person exists in the repository
When the user attempts to register
Then the person should be sent an email

Examples:
| first   | last   |
| Bob     | Smith  |
| Sarah   | Jane   |

And then another scenario for the opposite. This keeps the scenario meaning very clear. If your common steps are worded genericly you can reuse them. I also try to come from the approach of the user

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top