0% found this document useful (0 votes)
48 views12 pages

Coding The Automation Steps: Module Overview

The document discusses how steps in SpecFlow scenarios are bound to C# code for automation. It covers installing required NuGet packages, generating step definitions, and different styles of binding steps to code like using regular expressions or method names. It also shows what happens when steps are added, changed, or deleted and how the default binding style can be set in the app.config file.

Uploaded by

Gkfb AC
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views12 pages

Coding The Automation Steps: Module Overview

The document discusses how steps in SpecFlow scenarios are bound to C# code for automation. It covers installing required NuGet packages, generating step definitions, and different styles of binding steps to code like using regular expressions or method names. It also shows what happens when steps are added, changed, or deleted and how the default binding style can be set in the app.config file.

Uploaded by

Gkfb AC
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Coding The Automation Steps

Module Overview

Hi welcome back to module 3. In this module we'll be learning how the steps in a scenario bind to the

C# methods where we can actually perform our automation. In this module we'll learn about the

relevant NuGet packages that we need to install to utilize NUnits in SpecFlow. We'll look at two different

styles of binding step definitions to scenario steps and we'll see how we can set a default step definition

style when we generate our step definition files. We'll see what happens when we add a new step and

when we delete an existing step. We'll see how we can execute scenarios and debug individual step

definitions. We'll see how we can share step definitions between scenarios and how we can use

parameterized step definitions to promote reusability and reduce maintenance overhead. We'll

learn how when using a data table in a step how the data is passed through to the step definition and

our code. And we'll look at how scenario outline steps map to step definitions. Finally we'll look at how

we share scenario context and data between the individual steps that make up a scenario.

Installing The Required NuGet Packages

So the first thing we need to do is install the relevant NuGet packages. So we've already got the

SpecFlow extension installed and enabled. And now we have to add in the NuGet packages that we

need. So if we just do a search for SpecFlow we can see that we get a number of results. So if we look

at this SpecFlow NUnit package we can see that this depends on the SpecFlow package and the NUnit

package. So by installing this one SpecFlow. NUnit package we'll get everything we need to start writing

our automation. If we look at our installed packages we can see now that we've got NUnit and this is

the testing framework we'll be using in our automation. We then have the SpecFlow NUnit and the

SpecFlow itself package. So all of these packages combined with the extension that we've already

installed give us everything we need to start creating our automation.

1
Step Definition Binding

Now we have our NuGet packages installed and we've written our first Feature file with our first

Scenario. We now need to create the automation for each of the steps within the Scenario. So notice

here that each of these steps is highlighted in purple and this indicates that there's currently no

automation set up for these steps. When we're working with SpecFlow and Gherkin we need a way to

translate these natural language expressions into automatable and executable code. In SpecFlow

there's a concept of binding. Binding is essentially the hooking up of individual steps to individual pieces

of automation code. And we can see in the Test Explorer here that we don't currently have any tests in

our solution. If we take a look at our Solution Explorer we can see we have our. feature file here and if

we expand this down we can see we have this generated C# file. If we have a look at this we can see

that it's designer generated code and ordinarily we wouldn't change any of this. This code

essentially hooks up our natural language sentences to the SpecFlow framework and the

underlying unit testing framework that we're using. So in this case it's NUnit. And we can see NUnit in

use in this generated code through these attributes, but we don't need to worry too much about

this generated code. So now we need to create a class that contains methods that map to each of

these scenario steps. To do this we right-click and we head down to Generate Step Definitions. When

we open this dialog we're given the choice to select which steps we want to generate step definitions

for. So we're just going to leave this as all of them ticked, we get to choose the class name that we

want to generate, and we have a number of options for the style of binding. So by default it's this

Regular expressions in attributes style. And we'll come back to this in just a moment. For now I'm

just going to click Generate and I'm just going to leave the file name the same. If we have a look in our

Solution Explorer now we can see we've got our new class file. If we have a look at this we can see

that it contains methods for each of our steps in our scenario. So the first

step GivenThereIsToothpasteOnTheBrush, Given there is toothpaste on the brush and the mouth is

open, The mouth is open and notice here that this is mapped to the conceptual Given phase. We don't

have a separate and attribute and the same is true for the but attribute. The braces aren't damaged

2
appears as a Then attribute and also notice now that in our Feature file the steps have changed from

purple to white. And this indicates that there's a binding between the natural language and some code.

If we were to go and delete one of these bindings, so let's delete

the GivenThereIsToothpasteOnTheBrush, just save that, and if we head back to our Feature file now

notice that this step has reverted back to purple. And that's because no binding is available for this step.

So let's go ahead and remove this step definitions file and everything goes back to purple and we'll

right-click again, choose Generate Step Definitions, but this time we'll choose from the style dropdown

the Method name underscores option. If we click Generate now just OK the file name head back to

Solution Explorer and to our step definitions and this time we can see a different style here. The

attributes are now simply Given, When, or Then and the method name has been generated using

underscores between each word. Let's go back to the original style, (Typing) so this is the default

Regular expressions in attributes style (Typing) and notice here that we've got our text specified in the

attribute itself as well as in the method name and again in the actual original scenario step. So say

we change one of these steps, let's change the When the back teeth are brushed step and we'll change

this to read When all the back teeth are brushed. And immediately this changes to purple to indicate

that there's no matching step definition that can be bound to. So to restore this binding we head back to

our step definitions file and we can just change the attribute value here When all the back teeth are

brushed, Save this. And head back to our Feature file. Notice now that this step has gone from purple

back to white. Because the binding between this scenario step and the step definition has been

restored. And in this case it's because we're using the regular expression style, but notice here the

method name we haven't changed. And that's because it's the text in here that creates the binding. We

could actually name this method anything. So when we're working with the regular expression style it's

possible for the actual method name to quickly become out of sync with the actual binding and original

step text. And of course we could change this manually, but this can create some maintenance

overhead. So let's see what happens in this scenario if we use the underscore style. So I'll just

close this and we'll go and delete it and we'll regenerate these step definitions and this time we'll choose

the underscore style as before and hit Generate. And hit Save. So this time we don't have any text in

3
our attributes and the method names include underscores. And if we go back to our Feature file

everything is white which means we have matching step definitions for each of these steps. So let's

change this back to just when the back teeth are brushed. Again we notice it goes purple and to fix this

we head back but rather than having to change a string into the attribute and also the method name.

We can just change the method name now. So here we can remove the all, we Save this, head back to

our Feature file. And now the mapping has been restored and the step has changed back to white. So

we'll be using the method name underscore style for the rest of this course.

Setting The Default step Definition Style

We can specify the default style of binding by changing the app config. So by default when we hit

Generate Step Definitions it defaults to the Regular expressions in attributes style. So to change this

default we can open the app. config and we can add an additional line in the SpecFlow section. So here

we've added this trace element and we've set the step definition skeleton style to use method name

underscores. And if you want to know more about this configuration head to this link here. And this will

take you to the SpecFlow documentation. So now we've specified our Method name underscore to be

the default format, if we hit Save and we just get a warning here and SpecFlow's offering to regenerate

our feature files if required, so let's just hit Yes for now. And let's head back to our Feature and now

when we choose Generate Step Definitions we can see that the style now defaults to Method

name underscores, as opposed to the default Regular expressions in attributes. And notice here there's

a third option to use Method name Pascal case instead of underscores, but again we're going to stick to

the Method name underscores format for this course.

Adding New Steps

Let's take a look at what happens now when we add a new step to our scenario. So here we've got our

scenario and we've got our step definitions. So let's go and change this and let's just add an extra And

to the Given section. So it goes purple, so it means we need a step definition for this scenario step. So if

4
we go and right-click and choose Generate Step Definitions as before we only get the choice of one

because this is the only one that's not bound to a step definition. If we click Generate and we'll keep this

as BrushingOfTeethSteps. cs we get a warning that we're overriding it and if we click Yes and just hit

Yes because this is open in Visual Studio. If we go and have a look at our steps file now we can see

that we've only got one step definition. And if we look in the Feature all of the other lines have turned

purple. And that's because we've overridden the previous step definitions file and now it only

contains this step. So how do we add a new step definition? Well let's reset this, we'll delete this file,

we'll comment out this extra line for a moment and we'll go and generate everything again. Hit Save.

And now we can see our original step definitions. So let's uncomment this line. So we need to create an

individual step definition for this line. And we'll add it to our existing step definitions. So to do this we

head back to our Scenario, go to Generate Step Definitions, again we only get a single choice, but this

time instead of choosing Generate we'll choose Copy methods to clipboard. Now if we go back to our

step definitions we can paste what we've just copied to the clipboard. So here we can see our x_y_z

line in our step definitions now. And if we head back we can see that once we save this step definitions

file our line goes back to white. So that's how we can add a new step definition when we add a new

step to our scenario.

Deleting Steps

If we want to completely remove a scenario step we simply delete it from the scenario, so we've just

removed the x_y_z step and we can just hit Save and that's all we really have to do. However,

there's also the matching step definition and if we leave this here it won't cause any problems, but we

have to be careful that we don't create a maintenance problem in the future. So assuming this

step definition isn't shared with multiple scenarios, and we'll have a look at this concept later in the

module, we can simply go ahead and delete the step definition. One small tip is that when we're

deleting or editing a scenario step if we're working with a lot of scenarios and features, we can use a

handy navigation shortcut before we delete or change something. So for example, say we wanted to

5
delete And the front teeth are brushed, we could first right-click and choose Go To Step Definition. This

will then open the step definition file in the right place. So we can just delete the step definition, head

back to our Feature, and delete the line.

Running and Debugging Scenarios and step Definitions

So once we've got our scenarios and our step definitions how do we actually execute our scenarios and

kickoff the test automation? The first thing to check is that if you haven't already got it installed in

Extensions and Updates you need to check that you've got the NUnit test adaptor for Visual Studio

installed. Because we're using NUnit as our underlying framework and we're using the Visual Studio

Test Explorer we need to install that extension in order for Visual Studios Test Explorer to understand

NUnit. So to run a scenario we can simply right-click on it and choose either Run SpecFlow Scenarios

or Debug SpecFlow Scenarios. Let's hit Run. If we have a look at our test output for the

successful brushing scenario we can see that we get a message telling us that one or more

step definitions are not implemented yet, but we have actually generated our step definitions here. The

reason we're getting this message is because when we generate the step definitions the generation

adds the ScenarioContext. Current. Pending line. And this instructs SpecFlow that although we've

generated our step definitions we haven't actually implemented any code in them just yet. If we needed

to debug one of these step definitions we simply place a breakpoint in the step definition and we

can right-click and choose Debug SpecFlow Scenarios instead of Run Scenarios. So let's click this and

we can see now that our breakpoint has been hit in our Given_there_is_toothpaste_on_the_brush step

definition. In addition to right-clicking on the scenario and running it from there we can also use the

Test Explorer to search for specific scenarios to execute. So here we've just got one scenario, but we

could run it by right-clicking and hitting Run or Debug Selected Tests. So that's how we can execute a

scenario by either right-clicking inside the Feature file or by using the Visual Studio Test Explorer to

initiate the test run.

6
Sharing step Definitions

Our step definitions can be shared between multiple scenarios. So here we've got our successful

brushing scenario and all of the steps have matching step definitions. So let's go and add another

scenario. So notice here that the When x and then z lines are showing as purple because they don't

have any matching step definitions, but this given line There is toothpaste on the brush is showing as

white. Even though for this new scenario we haven't generated any steps. And that's because

there's already a step definition for this Given step. So if we right-click and choose Go To Step

Definition we can see that there is in fact a step definition for this line. If we navigate to the Given in

the first scenario we can see that it goes to the same place. So this Given step definition currently will

execute for both this scenario step and this scenario step. This sharing of matching step

definitions means that we can make use of code reuse in our automation steps, but this does, however,

mean that when we're changing step definitions we just have to be aware that if they're shared they will

affect multiple scenarios.

Parameterization to Promote step Definition Reusability

Another way we can reduce maintenance overhead is to use parameterized step definitions. So let's

say we had this scenario here and we want to modify it to specify the amount of toothpaste on

the brush. So let's say here Given there is 1 gram of toothpaste on the brush, so we need to go and

update our step definition binding. So Given_there_is_1_gram_of_toothpaste_on_the_brush let's Save

this and just double-check that it's gone white. And let's say now that we also want another scenario

with 2 grams of toothpaste. So let's take a copy of this and let's just call it Successful brushing 2. And

we'll change this to 2 grams of toothpaste on the brush. So we can go and copy this step definition and

change this to 2 grams. Again we'll Save it and just double-check here that everything's okay, which it

is. So now we've got two scenarios where the only difference is in this Given line. So although all of

these step definitions will be reused, we've got two step definitions for these Givens that only differ in

the data, ie the number of grams of toothpaste that's on the brush. So here in our step definitions we've

7
got two steps that when we come to write the actual automation will be extremely similar. So we can

reduce this code duplication in our step definitions by making use of parameterization in our

step definitions. So let's go and delete these two Given step definitions. Hit Save and head back and

notice now that we've got our two Givens that are not bound. If we right-click and go to Generate

Step Definitions we can get a preview, but notice that in this preview it's only going to generate a single

Given for the two selected Givens that we've specified here. So let's just close this preview and Copy

the methods to the clipboard and head back to our step definitions and let's just paste this in. So we've

only pasted in one Given, if we Save it and head back to the Feature notice now that both of our Givens

have turned white. Also the number in these Givens has changed to an italicized grayed out color. So

why is this? Well if we have a look at the generated step definition we can see now that in place of the

actual number of grams we have this P0, we also have a parameter that's now been added to our step

definition, also called p0. So let's go and put a breakpoint here and let's debug our first successful

brushing scenario. And our breakpoint gets hit and if we have a look at the value of this parameter we

can see that it's a 1 representing the 1 gram from our scenario step. If we stop this and instead

debug successful brushing 2 once our breakpoint gets hit we can have a look at our parameter value

and this time we've got the number 2 to represent 2 grams from the second scenario. So in this way

we've created a parameterized step definition that we can share between multiple scenarios. If we want

to we can go and rename this parameter so let's call it grams of toothpaste, or just grams. If we debug

this now we can see that we get our value for grams of toothpaste and we can also improve the

readability of the step by replacing this P0 with something more meaningful. To do this we just

specify something in capital letters. So let's just call it GRAMS. Again if we debug this we can see that

we get our grams of toothpaste. If we go and change the values in the Feature, so let's say 11 and

22, and just choose one of these to debug notice now that we get our new value for grams. So that's

how we can use parameterized step definitions to reduce the code duplication in our step definitions

where we have the same basic step definition but it only varies by data values.

Multiple and String params in A Single step Definition


8
We can also pass multiple parameters in a single step definition and also specify both strings and

numbers. So let's change this Given and we'll add two parameters. So again we'll add so many grams

of toothpaste and we'll also add another parameter to specify the brand of toothpaste. So let's just make

up a brand called Brand X. So Given there is 2 grams of Brand X toothpaste on the brush. So we can

go and edit our step definition now. So Given_there_is, (Typing) and again we use upper case to

denote the parameters, so Given_there_is_GRAMS_grams_of_BRAND_toothpaste_on_the_brush we

now have to add the method parameters. So the first one is a number, so we'll say int grams to match

the uppercase grams here and also we'll add a string parameter called brand to match the brand

parameter here. And these parameters in the method definition have to be in the same order as they

appear in the method name. Hence we've got GRAMS and grams first and BRAND and brand second.

If we Save this and head back to our Feature we now see that our Given step has gone back to white

and now we've got two parameters signified by the italics and the gray 2 and Brand X. So let's debug

this and we'll see what parameters we get passed. So let's go across here to our parameters and

for grams we can see we've got 2 and for brand we've got Brand X. We can go here and change this to

say 22 and Brand Y, debug the test again check our parameters and we have 22 grams and Brand Y.

Creating A step Definition with A Data Table

We saw in the previous module how we can specify data tables in Gherkin. So here in this Given step

we've specified a data table containing two columns, ToolName and ToolQuality, and we have three

data rows within the table. So how do we access these data items in our step definition? If we look at

our step definition here we can see that we've got this parameter of type table and this is a SpecFlow

table class. And we can use this table object to get at the table data in our step definition here. So to get

the firstToolName here we're using indexes, so we're saying the first row and the first column in the first

row. And here we're saying again the first row, but the second column. As well as using indexes for

the columns we can also specify the name of the column. So here we're saying the secondToolName is

at row 1, these being 0 based indexes. And the column is called ToolName. The secondToolQuality

9
again we're on the second row in the table, and we're looking for the column called ToolQuality. There's

a couple of other methods on this table object to do things such as rename columns and there's

also the useful ContainsColumn method which we can use to test for the existence of a column with a

specified name. So here we're saying does the table contain a column called Color, which it doesn't.

So let's go ahead and debug this test and we'll have a look at this table structure. So we have access to

a collection of Headers, so if we expand this we can see we've got the headers or the columns

of ToolName and ToolQuality. And we also have this Rows property and we can drill down into this, see

each of the table row objects. Each table row object has a collection of keys and values and again

we can just expand this down and we can see we've got ToolName paste and ToolQuality medium. So

let's have a look at our variables here. The first ToolName we've got paste and Quality medium, so this

maps to paste and medium here. And the second ToolName of brush and the second ToolQuality of

high, so again this maps to brush and high. If we look at our IsToolColorColumnSpecified we can see

that we've got false as expected. So that's how we can specify a data table in Gherkin for a Given step

and how we can access the rows and columns by adding a table parameter to our step definition.

Scenario Outline step Definitions

So let's take a look at scenario outlines in use. So here we've got our scenario outline from module 2,

we have three parameters, brand, mins, and percent and these map to the columns here. So

notice we've got these quote marks around our string type and these other things are numbers. So let's

go ahead and generate our step definitions, but this time I'm going to start with the Regular

expression style and we'll see why in a just a moment. So let's generate this and let's go and have a

look at our step definitions. So notice that we're using the Regular expression style and for our Given

step for our string it's added our string parameter as expected. So we can put a breakpoint here and we

can debug one of these tests and if we look at our parameter 0 we can see that we get Brand X as

expected. So let's delete these step definitions and let's now generate them using the Method name

underscores style. Let's go and look at our step definitions now so we're not using the

10
Regular expression style this time. And let's do the same as before, add a breakpoint and then debug

the test. And let's have a look at our parameter value again, but notice this time we've got this additional

quote. We can see that we've got Brand X followed by this quote, which is clearly wrong. So we'll Close

this and stop debugging and let's go back to our Features. And we have a hint here that something is

not quite right. The opening quote is white but the closing quote is gray. When we're not choosing the

Regular expression style we need to remove these quotes. If we debug the test again and check our

string parameter now we can see that we've got Brand X without the additional quote. If we look at our

Feature file we can see that we don't have any gray items now, so this is a hint to us that everything is

as expected. And as with parameters before we can go and make this a bit more readable. We change

this to Brand and the corresponding parameter also to Brand and we could do the same things for these

When and Then parameters as well. So let's just double-check everything is working as expected. So

for this first example in the scenario outline we have our Brand X, if we debug the next one we have our

Brand Y, and if we debug the final one we get our Brand Z. So that's how we can map scenario outline

examples to individual step parameters.

Sharing and Maintaining State Between step Definitions

Because in SpecFlow each of the individual steps in a scenario map to a separate method in our step

definitions sometimes we need to be able to pass data between individual step definitions. One way

we can do this is to use the ScenarioContext. Current and we can use this as a dictionary to add keys

and values to the currently executing scenario context. So when each scenario executes we get a

new scenario context and we can add things to it. So here the key is brand name and the value that

we're storing is the brand that's passed through as a parameter. The next step that gets executed is this

When I brush for so many minutes step. And even though this is a separately executing step we can

retrieve the brand name from the scenario context by specifying as an indexer the key that we added

here. So let's see this in action. We'll debug this test and if we check our brandName variable we can

see that we got Brand X that we stored in the previous step. And we can see this for the other tests.

11
This time Brand Y was stored. If all our step definitions exist in the same class instead of using the

scenario context we can create private fields. So here we could simply create a field and rather than

use the scenario context we could simply say that we're setting the internal field to the value of this

parameter passed in in this step. And then we could simply use this underscore brand field in this step

here. So just to illustrate, if we run this now we can see that our brand field in the class is set to Brand

Y. So this private field approach is fine if all our steps are within the same class, but because matching

step definitions don't have to be all in the same class, so a scenario could have two steps. One

step could be bound to a step definition in one class and another to a step definition in a different class

we can't always use this approach. And that's when storing things in ScenarioContext. Current is more

flexible.

Module Summary

So that brings us to the end of module 3. In this module we learned how to install the relevant NuGet

packages to get NUnit and SpecFlow working together. We saw the regular expression style of binding

and the method underscore style of binding. We learned how to change the app config to change the

default step definition style. We saw what happens when we add and delete steps. And we saw how we

can execute scenarios and debug individual steps within those scenarios. We saw how a step definition

can be shared between multiple scenarios and how we can parameterize step definitions so we can

reuse them. We saw how to access the data items in a data table when we pass it to a step definition.

And we also saw how when we're using data driven scenario outlines how the data maps to our step

definition parameters. And finally we learned a couple of methods of sharing data between scenario

steps.

12

You might also like