SpecFlowOSS / SpecFlow

#1 .NET BDD Framework. SpecFlow automates your testing & works with your existing code. Find Bugs before they happen. Behavior Driven Development helps developers, testers, and business representatives to get a better understanding of their collaboration
https://www.specflow.org/
Other
2.23k stars 752 forks source link

Question: Sets and Instances with Specflow + Excel #2586

Open adamfriedland opened 2 years ago

adamfriedland commented 2 years ago

Product:

Quick question as I don't see any documentation related to it and a search turned up nothing either. Is it possible to use the CreateSet or CreateInstance functions and their various other derivatives using Specflow+Excel? Specflow doesn't recognise the @source attribute when trying to leverage these implementations in the feature file.

SabotageAndi commented 2 years ago

SpecFlow+ Excel is generating normal tables as if you write your feature files manually. And so, you can use the CreateSet methods. Why are you asking? What issue do you have?

Be aware that we don't maintain SpecFlow+ Excel anymore and it is totally outdated.

adamfriedland commented 2 years ago

Would you be able to provide an example of this?

Here's an example of a step image

And me attempting to hit the step in the feature file which usually requires an example table within the feature file. image

adamfriedland commented 2 years ago

Also regarding your comment to deprecation. Is there a new tool which you'd better advise me using?

SabotageAndi commented 2 years ago

The issue is, that you put the tag on the step. These tags have to be put on the scenario. See https://docs.specflow.org/projects/specflow-excel/en/latest/Excel/Excel-Examples.html#prepare-feature-files-for-external-examples

The success of SpecFlow+ Excel is SpecFlow.ExternalData. You find docs for it here: https://docs.specflow.org/projects/specflow/en/latest/Guides/externaldata.html

adamfriedland commented 2 years ago

Correct and I've already done this. However this is what transpires if you follow your suggestion or you fallback onto this syntax. I see that I'm actually already using the ExternalData plugin.

image

adamfriedland commented 2 years ago

Any feedback on this?

SabotageAndi commented 2 years ago

Ah now I got it. You can only provide examples via SpecFlow.ExternalData. You can't provide table parameters.

clrudolphi commented 2 years ago

Would there be an interest in adding that as a feature? I will draft a prototype if there is interest.

clrudolphi commented 2 years ago

I have looked into this and have an approach that "works" - kind of.

As mentioned in this thread above, Tags are not allowed on individual Steps. That makes more difficult the process of externalizing tables for run-time values. I am attempting to take into account the likely need for multiple such external tables per scenario/feature.

What I have come up with is the use of a StepArgumentTransformation that accepts as input the syntax that is used by the ExternalDataSource generator's tag and uses that to read in excel and build a Table.

[Binding]
public class TransformToTable
{
    [StepArgumentTransformation(@"@@External: @DataSource: (.*) @DataSet: (.*)")]
    public Table ExternalSourcetoTable(string filename, string setname)
    {
        ...
    }

The body of the method uses the ExcelDataLoader class from the ExternalData plugin to load the file.

This transformer is then used in a Given step, such as: Background: data set Given a person table @@External: @DataSource: Features\People.xlsx @DataSet: People And expected results table @@External: @DataSource: Features\People.xlsx @DataSet: ExpectedResults

The first Given loads the excel file and uses the 'People' worksheet to build a Set of Person objects. The second uses the 'ExpectedResults' worksheet to load in a set of strings to be used as expected results for the test validations that follow in the scenario.

The binding for the first Given is: [Given(@"a person table (.*)")] public void GivenAPersonTable(Table mytable) { _people = mytable.CreateSet().ToArray(); }

How well does this approach work for your needs and the objectives of the SpecFlow project? To really make this approach viable, the ExternalData plugin would need to be refactored to externalize the DataLoaders and DataSources to make them into their own NuGet package.

A different approach would be to create a run-time plugin that uses a similar, but not identical Tag syntax as the ExternalData plugin and identify each loaded Excel sheet by name (which would then be retrieved from Context at run time).

What do you think?

JosphineMonica commented 1 year ago

I would like try similar concept by placing Gherkin feature steps (And/Then) in an external file instead of examples: Test data and call it inside a scenario. Can you please advise.

clrudolphi commented 1 year ago

I would like try similar concept by placing Gherkin feature steps (And/Then) in an external file instead of examples: Test data and call it inside a scenario. Can you please advise.

Would you mind providing more detail on why you would want this capability? What would the workflow be like?

It appears to me that you would like the ability to reuse Steps like a library. From my understanding, that type of approach is losing favor in lieu of the driver pattern (https://docs.specflow.org/projects/specflow/en/latest/Guides/DriverPattern.html )

JosphineMonica commented 1 year ago

Yes. We have scenarios as bellow:

Actual:

Scenario1: Navigates to Module A Step 1A Step 2A Step 3A Navigates to Module B Step 1B Step 2B Step 3B Navigates to Module A Step 1A Step 2A Step 3A

Scenario 2: Navigates to Module B Step 1B Step 2B Step 3B Navigates to Module C Step 1C Step 2C Step 3C

Scenario 3: Navigates to Module A Step 1A Step 2A Step 3A Navigates to Module C Step 1C Step 2C Step 3C

And I need a functionality that supports repetitive feature steps in any external file such as .txt or .feature. So my feature file might look like below:

Expected:

Scenario1: Naviages to Module A from "ModuleA.txt" Naviages to Module B from "ModuleB.txt" Naviages to Module A from "ModuleA.txt"

Hope I made it clear:) Can you please suggest any options for the same.

Thanks, Monica

On Sat, May 6, 2023 at 1:32 AM Chris Rudolphi @.***> wrote:

I would like try similar concept by placing Gherkin feature steps (And/Then) in an external file instead of examples: Test data and call it inside a scenario. Can you please advise.

Would you mind providing more detail on why you would want this capability? What would the workflow be like?

It appears to me that you would like the ability to reuse Steps like a library. From my understanding, that type of approach is losing favor in lieu of the driver pattern ( https://docs.specflow.org/projects/specflow/en/latest/Guides/DriverPattern.html )

— Reply to this email directly, view it on GitHub https://github.com/SpecFlowOSS/SpecFlow/issues/2586#issuecomment-1536939434, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWBL7Z7L7VD7GAURLWJPF5TXEWLZDANCNFSM5T37FDJA . You are receiving this because you commented.Message ID: @.***>

-- Thanks,

Monica.

clrudolphi commented 1 year ago

SpecFlow v3 has the ability for a step to call/invoke another. See the documentation here:

This feature is deprecated however and removed from v4 (the documentation explains why).

If you're willing to stay on v3 for some time this approach may fit your needs.

JosphineMonica commented 1 year ago

Thank you @clrudolphi

JosphineMonica commented 1 year ago

I am trying to keep all my testdata in csv file and access it via External data Plugin.

Expected: Each scenario should run based on the Testcase ID supplied in FeatureFile.

@DataSource:products.csv Scenario: Valid product prices are calculated Given the customer has put 1 piece of in the basket When the basket price is calculated Then the basket price should be greater than zero

If I mention only chocolate to the above scenario, it should run only chocolate instead of the list present in the products.csv.

I would like to know this feature as I moved my test data into csv file and trying to execute specific list of testcases for each scenario. So I will be supplying the 2 or 3 Testcases name from feature file for each scenario in Tables and the respective Test Data for each testcases should be picked and executed.

Is it possible.

clrudolphi commented 1 year ago

Yes, this is possible, but you will have to do some of the work. As described in the docs here: ScenarioContext use context injection to obtain the ScenarioContext object in your step binding method. This will give you the name of the Scenario.

The @Datasource attribute will provide the contents of a worksheet from a excel/csv file. One of the columns of that sheet should contain your scenario name, the contents of which should match your Scenario name. The external data source attribute will provide you a table with all of the rows in that sheet. You'll have to filter it down to just those rows with a matching Scenario name.

JosphineMonica commented 1 year ago

@clrudolphi That's excellent. Thank you for the quick reply. I did exactly the same. However, I still require some information. I have one external file which has list of testcases (This will act as the Key which I am going to send it from Feature File). When I do the above steps, it lists all my testcases (let's say 20 Testcases of Claim Creation in the excel). Now, for Scenario 1 (Create Client), I need to run only 5 Testcases instead of 20 (E2E Test cases of Claim from Client to Bank record creation) and I am passing the list of Testcases names from Feature File. Every iteration, scenario context record matches with my feature list of inputs and then continue to execute if matched else it needs to exit the current execution and continue with the second testcases in the feature list. Is it possible here. I am afraid that this might create confusion where the plugin provides the list of Test cases in the Test Explorer for every scenario in my feature file. I have 5 Scenario from client to bank record creation. Each 5 with 20 Test cases being listed.

clrudolphi commented 1 year ago

Yes, your concern there is valid. The ExternalDataSource plugin will provide "examples" to the Scenario which end up being generated as individual test cases in the Test Explorer. At least, that is the default behavior. You might try turning off the row tests in the configuration file. See this section of the documentation. I haven't tried it myself, but turning allowRowTests to false might result in the behavior you are looking for.

JosphineMonica commented 1 year ago

@clrudolphi Thanks for the reply. I tried setting up the flag to false for allowrowtests and it still displays the list of testcases. Looks like, I couldn't use external data plug in my case. Anyway, thank you for the support.