Wednesday, May 20, 2020

How to Integrate Ranorex with SpecFlow BDD and NUnit with SpecFlow HTML report


Tool Stack: 
The diagram below shows a sample tool stack to create a BDD-based testing framework. Ranorex Studio provides the development environment, while the Ranorex test automation framework provides the automation API. To parse the feature files from natural language to written code, we are using SpecFlow as the BDD interpreter. Finally, NUnit is the unit test provider, which manages and executes the tests. 




Process Overview: 
When following the BDD approach in an agile environment, the entire development process of a user story is divided into a business side and a technology side. 


On the business side, we create user stories, which are taken and broken down into features stored in feature files. These features are broken down into scenarios. The features are written down in a natural language following the Gherkin syntax. A basic feature written in Gherkin might look something like this: 

Feature: Serve coffee 

In order to earn money 

Customers should be able to 

buy coffee at all times 

 

Scenario: Buy last coffee 

Given there are 1 coffees left in the machine 

And I have deposited 1 dollar 

When I press the coffee button 

Then I should be served a coffee 


On the technology side, we need an interpreter to parse the feature files written in natural language (Gherkin syntax) and call test automation code. These Ranorex API calls or Ranorex recordings do the following: 
  • Automate the system under test 
  • Verify the expected output 
  • Returning a corresponding result 
Prepare Ranorex Studio for BDD: 

1. The SpecFlow Add-in for Ranorex Studio: 
The SpecFlow add-in provides file templates for feature files, step definition files and event definition files. It also translates the features from Gherkin syntax to C# code. To install the SpecFlow add-in to Ranorex Studio, follow the instructions below: 
  • Download or clone the SpecFlow_repo and open the project “TechTalk.SpecFlow.RanorexIntegration.csproj 
  •  Accept the option for all the projects 
  • You then need to ensure that the project is targeting the .NETFramework version 4.6.2 
  •  Select project from Solution Explorer view and click on “Manage NuGet Packages” 
  • Use the context menu and select Manage NuGet Packages, then click restore. Add the NuGet package for NUnit.Runners.2.7.1, it is important that you use version 2.7.1 
  •  A .sdaddin file will then be built in the IdeIntegrations folder. Use an extraction tool such as 7-Zip to extract the file and save it to a new folder named “TechTalk.SpecFlow.RanorexIntegration”. 
  • Copy the extracted folder and paste in the <Ranorex Installation folder>Bin\Addins\Misc.  
2. Make your Ranorex Solution BDD ready: 
  • In your Ranorex solution open the “Package management console” (View->Tools->Package management console) and run the following commands:
    • Install-Package SpecFlow.NUnit -Version 2.4.0 
    • Install-Package NUnit.Runners -Version 2.7.1 
    • Install-Package NUnit.Extension.NUnitV2ResultWriter 
  • You will notice that the references are added to the projects view. To ensure that your BDD solution integrates seamlessly with SpecFlow and NUnit you will need to amend the AssemblyInfo.cs and app.config. Simply double click on each in the projects view. 
    • For the AssemblyInfo.cs add below command: 
      •   [assembly:NUnit.Framework.Apartment(System.Threading.ApartmentState.STA)]
      • #region Using directives 

         

        using System; 

        using System.Reflection; 

        using System.Runtime.InteropServices; 

         

        #endregion 

         

        // General Information about an assembly is controlled through the following  

        // set of attributes. Change these attribute values to modify the information 

        // associated with an assembly. 

        [assembly: AssemblyTitle("BDDCalc")] 

        [assembly: AssemblyDescription("")] 

        [assembly: AssemblyConfiguration("")] 

        [assembly: AssemblyCompany("")] 

        [assembly: AssemblyProduct("BDDCalc")] 

        [assembly: AssemblyCopyright("Copyright 2019")] 

        [assembly: AssemblyTrademark("")] 

        [assembly: AssemblyCulture("")] 

        [assembly: NUnit.Framework.Apartment(System.Threading.ApartmentState.STA)]  

         

        // This sets the default COM visibility of types in the assembly to invisible. 

        // If you need to expose a type to COM, use [ComVisible(true)] on that type. 

        [assembly: ComVisible(false)] 

         

        // The assembly version has following format : 

        // 

        // Major.Minor.Build.Revision 

        // 

        // You can specify all the values or you can use the default the Revision and  

        // Build Numbers by using the '*' as shown below: 

        [assembly: AssemblyVersion("1.0.*")] 

    • For the app.config you will need to add <probing privatePath=”Runtime”/> in ‘assemblyBinding’ 
      • <?xml version="1.0" encoding="utf-8"?> 

        <configuration> 

          <configSections> 

            <section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" ></section> 

          </configSections> 

          <startup useLegacyV2RuntimeActivationPolicy="true"> 

            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" ></supportedRuntime> 

            <supportedRuntime version="v2.0.50727" ></supportedRuntime> 

          </startup> 

          <runtime> 

            <enforceFIPSPolicy enabled="false" ></enforceFIPSPolicy> 

        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 

              <dependentAssembly> 

                <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" ></assemblyIdentity> 

                <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" ></bindingRedirect> 

              </dependentAssembly> 

              <probing privatePath="Runtime"></probing> 

           </assemblyBinding> 

          </runtime> 

        <specFlow> 

             For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config  

           For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config <unitTestProvider name="NUnit" ></unitTestProvider></specFlow></configuration> 

3. Get started with BDD:
Now that your Ranorex Solution is BDD-ready, you can begin defining features in SpecFlow and creating automated tests for them in Ranorex.
  • Define a feature from the business side 
    • In SpecFlow, create a new feature file. To do so, right-click on the project, then choose Add > New Item > Category: SpecFlow > SpecFlow Feature. 
    • Now, create methods for all “Given,” “When,” and “Then” actions described in the scenario description. Add “Given”, “When” and “Then” attributes with values matching the scenario steps defined in the feature file. To do so, follow the samples provided by the template from which the new step definition file has been generated. 
      • Feature: Calculator 

         In order to avoid silly mistakes 

         As a math idiot 

         I want to be told the square root of a number 

         

        Scenario: Square root of a Number 

         Given I click 9 on calculator 

         When I press sqrt 

         Then the result should be 3 on the screen 

    • Save the file. Ranorex Studio will create a <name>.feature.cs file containing the automatically-generated code that will execute the test scenarios using the configured test provider.
    • If the code/C# file is not created please refer to the troubleshooting section at the end of this blog.
  • Create step and event definitions for the technology side  
    • Create a new step definition file. To do so, right click on the project and choose Add > New Item > Category: SpecFlow > SpecFlow Step Definition. 
    • Now, create methods for all “Given,” “When,” and “Then” actions described in the scenario description. Add “Given”, “When” and “Then” attributes with values matching the scenario steps defined in the feature file. To do so, follow the samples provided by the template from which the new step definition file has been generated. 
      • [Binding] 

             public class sqrt 

             { 

                 [Given("I have entered (.*) into the calculator")] 

                 public void GivenIHaveEnteredSomethingIntoTheCalculator(int number) 

                 { 

                     ClickNumButton.repo.numButton = number.ToString(); 

                     ClickNumButton.Start(); 

                 } 

         

                 [When("I press the square root button")] 

                 public void WhenIPressSqrt() 

                 { 

                     PressSqrt.Start(); 

                 } 

         

                 [Then("the result should be (.*) on the screen")] 

                 public void ThenTheResultShouldBe(int result) 

                 { 

                     ValidateResult.Instance.result = result.ToString(); 

                     ValidateResult.Start(); 

                 } 

             } 

    • SpecFlow searches for the step definition text in the step definition files that matches the text in the scenario step. 
    • Now you can implement the automated step, either by creating recording modules or by manually implementing the steps using the Ranorex automation API. 
  • Create Before all and after all: 
    • You can create additional steps to be executed before and after a scenario, such as performing setup and tear down tasks, including starting and closing the system under test. 
    • These steps can be defined in an event definition file and might look something like this: 
      •    [BeforeScenario] 

                public void BeforeScenario() 

                { 

                OpenBrowser.Start(); 

                } 

         

                [AfterScenario] 

                public void AfterScenario() 

                { 

                CloseBrowser.Start(); 

  • Using Recordings and code in the step definition files: 
    • You can trigger recording module from the step definition files by using command: 
      • FolderName.SubFolderName.Scripts.Start() 
    • You can also use Ranorex API to write code, just like in code module/user code 
    • Can drag and drop repository items in the step definition file and write code to perform desired output.
    •  
4. Change Project settings to run solution from command prompt: 
  • Change Project Output type: 
    • You will need to build your project as a library. To do so, open the project properties and set the output type of the project to “class library”. In addition, copy all Ranorex runtime DLLs to the output folder. 
    • Add command to copy run time dll in the bin folder to build events 
      • start  xcopy "C:\Program Files (x86)\Ranorex\Studio\Bin\Runtime" "$(ProjectDir)bin\Debug" /Y 
5. Execute code and generate reports: 
  • Open command prompt, and navigate to the project folder 
  • Run the below command to execute the suite: 
    • .\packages\NUnit.ConsoleRunner.3.11.1\tools\nunit3-console.exe --out=".\Reports\TestResult.txt" "--result=.\Reports\TestResult.xml;format=nunit2" ".\<project folder name>\bin\Debug\<projectName>.dll"
  • Run below command to create html report: 
    • .\packages\SpecFlow.2.4.0\tools\specflow.exe nunitexecutionreport --ProjectFile ".\<ProjectFolder>\<ProjectName>.csproj" --xmlTestResult ".\Reports\TestResult.xml" --testOutput ".\Reports\TestResult.txt" --OutputFile ".\Reports\CustomSpecflowTestReport.html"  
Trouble Shooting for .Net version 3.5: 
  • If you are not able to install .net 3.5 from windows/server features, try the below solution :
    • set the HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU folder. 
    • DoubleClick on UseWUServer(UseWindowsUpdateServer) and change the value to 0.
    • If the value is already 0 this fix may not work for you.  RESTART afterwards.