1
votes

I had a series of scenarios that look like this:

Given these receipts:
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |
And delay is 15
When I calculate date of payment
Then Date of payment should be 20

Given these receipts:
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |
And delay is 30
When I calculate date of payment
Then Date of payment should be 15

Given these receipts:
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |
And delay is 45
When I calculate date of payment
Then Date of payment should be 10

So I learned about Scenario outline and I tried to make one for the above scenarios but had trouble putting in the receipts for obvious reasons:

Given these receipts: '<receipts>'
And delay is <delay>
When I calculate date of payment
Then Date of payment should be '<dateOfPayment>'

Examples:
| delay | dateOfPayment | receipts                               |
| 15    |    20         | | Amount | Date       | Company     |  |
                        | | 1000   | 2016/10/25 | one company |  |
                        | | ..............................    |  |

Given that I want the same collection of, in this case, receipts for all scenarios in my Feature how can I declare a table that will be passed at the place of '<receipts>' in the scenario outline

Maybe, should I proceed with a different approach?

---------------------------------- EDITED --------------------------------

Maybe something like this could work (but It is not implemented in Gherkin):

Given these receipts: '<receipts>'
And delay is <delay>
When I calculate date of payment
Then Date of payment should be '<dateOfPayment>'

Examples:
| delay | dateOfPayment | 
| 15    |    20         | 

Placeholder: '<receipts>'
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |
3
If the 'receipts' datatable data is constant across scenarios, you should keep it where you have in your original scenarios. And just put the 'delay' and 'dateOfPayment' in the scenario outline examples. But if the receipts data changes across scenarios this would not work. What is the dependency of the three companies in the datatable? - Grasshopper
company is only an information in this example, it could be another date (issue date, due date). - sabotero
@Grasshopper so I have to repeat the table for every scenario? It seems like that could be factorized somehow, maybe creating another scenario with only a given that pass the table as parameter. Maybe something like this (without using the feturecontext that is mentioned in that link)? - sabotero
@Grasshopper I edited my question to show a possible solution, but I know it does not work yet (not implemented in Gherkin) - sabotero
Can you use each line of the 'receipts' across all scenarios into single examples in a scenario outline? - Grasshopper

3 Answers

3
votes

I had this silly idea: Given that the receipts does not change I could maybe provide to the Scenario Outline a Given with the actual table rather than a placeholder

And it worked:

Scenario Outline: payment
Given these receipts:
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |
And delay is '<delay>'
When I calculate date of payment
Then Date of payment should be '<dateOfPayment>'

Examples: 
| delay | dateOfPayment |
| 15    | 20            |
| 30    | 10            |
| 45    | 5             |

If you are, as I am, working in .Net with Specflow and c# specflow will generate this method for the Givenwith the table:

[Given(@"these receipts:")]
public void GivenTheseReceipts()
{            
    ScenarioContext.Current.Pending();
}

Don't worry, just add the table parameter, and the table will be passed as parameter as it does with a normal scenario:

[Given(@"these receipts:")]
public void GivenTheseReceipts(Table table)
{
    var receipts = table.CreateSet<Receipt>(); // you can even create a set given you have defined the Receipt class
}

public class Receipt
{
    public decimal Amount { get; set; }
    public DateTime Date { get; set; }
    public string Company { get; set; }
}

------------------------- EDITED -------------------------------------

It seems as it would have also worked with Background:

Background: 
Given these receipts:
| Amount | Date       | Company         |
| 1000   | 2016/10/25 | One Company     |
| 1200   | 2016/10/20 | Another Company |
| 1500   | 2016/10/13 | My Company      |

Scenario Outline: payment
And delay is '<delay>'
When I calculate date of payment
Then Date of payment should be '<dateOfPayment>'

Examples: 
| delay | dateOfPayment |
| 15    | 20            |
| 30    | 10            |
| 45    | 5             |

Now, it's only a matter of style.

Notice also that Background will be called before all other scenarios you may have in your Feature file.

1
votes

Scenario Outline does not support table substitution.

You could, however, use:

| delay | dateOfPayment | rcpt1Amnt | rcpt1Date | rcpt1Cmpny | rcpt2Amnt | recpt2Date | ... | 15 | 20 | 1000 | 2016/10/25| One Company| 1200 | 2016/10/20 | ...

0
votes

In answer to @Monnie_tester you can use the Table directly. Here is an example:

[Then(@"I do something")]
    public void ThenIDoSomething(Table table)
    {
        string outName;

        for (int i = 0; i < table.Rows.Count; i++)
        {
            var r = table.Rows[i];
            r.TryGetValue("Name", out outName);
        }


    }