We saw how to use Selenium WebDriver with Cucumber-JVM for BDD/ATDD. Now let's try using a similar combination in .NET using SpecFlow.NET. We can implement BDD in .NET using the SpecFlow.NET and Selenium WebDriver .NET bindings.
SpecFlow.NET is inspired by Cucumber and uses the same Gherkin language to write specs. In this recipe, we will implement tests for the Fund
Transfer
feature using SpecFlow.NET. We will also use the Page
objects for FundTransferPage
in this recipe.
This recipe is created with SpecFlow.NET Version 1.9.0 and Microsoft Visual Studio Professional 2013; follow these steps:
This will install the project template and other support files for SpecFlow.NET in Visual Studio 20132.
Let's test the fund transfer feature using SpecFlow.NET by performing the following steps:
FundTransfer.specs
, as shown in the following screenshot:FundTransfer.specs
solution in Solution Explorer and select Manage NuGet Packages…, as shown in the following screenshot:The steps to create a spec file are as follows:
FundTransfer.specs
solution in Solution Explorer. Select Add | New Item.FundTransfer.feature
in the Name: textbox. Click on the Add button, as shown in the following screenshot:FundTransfer.feature
tab.SpecFlow
will add a dummy feature in the feature file. Replace the content of this file with the following feature and scenarios:Feature: Customer Transfer's Fund As a customer, I want to transfer funds so that I can send money to my friends and family Scenario: Valid Payee Given the user is on Fund Transfer Page When he enters "Jim" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure the fund transfer is complete with "$100 transferred successfully to Jim!!" message Scenario: Invalid Payee Given the user is on Fund Transfer Page When he enters "Jack" as payee name And he enters "100" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! 'Jack' is not registered in your List of Payees" is displayed Scenario: Account is overdrawn past the overdraft limit Given the user is on Fund Transfer Page When he enters "Tim" as payee name And he enters "1000000" as amount And he Submits request for Fund Transfer Then ensure a transaction failure message "Transfer failed!! account cannot be overdrawn" is displayed
The steps to create a step definition file are as follows:
FundTransfer.sepcs
solution in Solution Explorer. Select Add | New Item.FundTransferStepDefs.cs
in the Name: textbox.using System; using System.Collections.Generic; using System.Linq; using System.Text; using TechTalk.SpecFlow; using NUnit.Framework; using OpenQA.Selenium; namespace FundTransfer.specs { [Binding] public class FundTransferStepDefs { FundsTransferPage _ftPage = new FundsTransferPage(Environment.Driver); [Given(@"the user is on Fund Transfer Page")] public void GivenUserIsOnFundTransferPage() { Environment.Driver.Navigate().GoToUrl("http://cookbook.seleniumacademy.com/fundTransfer.html"); } [When(@"he enters ""(.*)"" as payee name")] public void WhenUserEneteredIntoThePayeeNameField(string payeeName) { _ftPage.payeeNameField.SendKeys(payeeName); } [When(@"he enters ""(.*)"" as amount")] public void WhenUserEneteredIntoTheAmountField(string amount) { _ftPage.amountField.SendKeys(amount); } [When(@"he enters ""(.*)"" as amount above his limit")] public void WhenUserEneteredIntoTheAmountFieldAboveLimit(string amount) { _ftPage.amountField.SendKeys(amount); } [When(@"he Submits request for Fund Transfer")] public void WhenUserPressTransferButton() { _ftPage.transferButton.Click(); } [Then(@"ensure the fund transfer is complete with ""(.*)"" message")] public void ThenFundTransferIsComplete(string message) { Assert.AreEqual(message, _ftPage.messageLabel.Text); } [Then(@"ensure a transaction failure message ""(.*)"" is displayed")] public void ThenFundTransferIsFailed(string message) { Assert.AreEqual(message, _ftPage.messageLabel.Text); } } }
The steps to define a Page
object and a helper class are as follows:
Page
object for the Fund Transfer Page by adding a new C# class file. Name this class FundTransferPage
. Copy the following code to this class:using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenQA.Selenium; using OpenQA.Selenium.Support.PageObjects; namespace FundTransfer.specs { class FundTransferPage { public FundTransferPage(IWebDriver driver) { PageFactory.InitElements(driver, this); } [FindsBy(How = How.Id, Using = "payee")] public IWebElement payeeNameField { get; set; } [FindsBy(How = How.Id, Using = "amount")] public IWebElement amountField { get; set; } [FindsBy(How = How.Id, Using = "transfer")] public IWebElement transferButton { get; set; } [FindsBy(How = How.Id, Using = "message")] public IWebElement messageLabel { get; set; } } }
Environment
and copy the following code to this class:using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using TechTalk.SpecFlow; namespace FundTransfer.specs { [Binding] public class Environment { private static ChromeDriver driver; public static IWebDriver Driver { get { return driver ?? (driver = new ChromeDriver(@"C:ChromeDriver")); } } [AfterTestRun] public static void AfterTestRun() { Driver.Close(); Driver.Quit(); driver = null; } } }
The steps to run the tests are as follows:
SpecFlow.NET first needs the feature files for the features we will be testing. SpecFlow.NET supports the Gherkin language for writing features.
In the step definition file, we must create a method for each step written in a feature file using the Given
, When
, and Then
attributes. These methods can also take the parameter values specified in the steps using the arguments. Following is an example of entering the name of the payee:
[When(@"he enters ""(.*)"" as payee name")] public void WhenUserEneteredIntoThePayeeNameField(string payeeName) { _ftPage.payeeNameField.SendKeys(payeeName); }
In this example, we are automating the "When he enters "Jim" as payee name"
step. We used the When
attribute and created a method: WhenUserEneteredIntoThePayeeNameField
. This method will need the value of the payee name embedded in the step, which is extracted using the regular expression by the SpecFlow.NET. Inside the method, we are using an instance of the FundTransferPage
class and calling its payeeNameField
member's SendKeys()
method, passing the name of the payee extracted from the step. Using the Page
object helps in abstracting locator and page details from the step definition files, making it more manageable and easy to maintain.
SpecFlow.NET automatically generates the NUnit test code when the project is built. Using the Visual Studio Test Explorer and NUnit Test Adaptor for Visual Studio, these tests are executed and the features are validated.
18.216.96.94