Search code examples
c#specflow

How to make a variable global within the step definition file so the other steps can access them


I am trying to make special keys global so that they can be used in other steps within the step definition file for C# Automation. So my file looks like this:


    [Binding]
    public class GenerateAPIKey

        
    {
        public var = specialKeyId; ===>this doesn't work (does not exist in its current context)

        [Given(@"the user has the specialKeyId and extraSpecialAccessKey")]
        public void GivenTheUserHasThespecialKeyIdAndextraSpecialAccessKey()
        {
            var specialKeyId (assigned but never used) = "2591d7c7617fffggrrg90a19bedb9d42493";
            var extraSpecialAccessKey = "vXBx0PINNV2Tffefgwrg7WgfsQM0e6Epjc+1UJ0Y=";
        }

I tried making it public but the specialKeyId says its unused even though it is being called in another step. I have even tried modifying the feature file but it gets awfully complicated as below:

Scenario: Creates a very special Key
    Given the user has the <specialKeyId> and extraSpecialAccessKey
    And the content is pass through the request successfully with a change to the API Key Name
    When the POST generateVerySpecialKey Request is initiated
    Then the status code of the response should be <ExpectedResult>
    Examples:
    | Expected Result | specialKeyId                      |
    | 200             | 2591d7c7617fffggrrg90a19bedb9d42493 |

When I generate the step definition file I get

        [Given(@"the user has the (.*)c(.*)bb(.*)bedb(.*) and extraSpecialAccessKey")]
        public void GivenTheUserHasTheCbbbedbAndSecretAccessKey(Decimal p0, Decimal p1, Decimal p2, Decimal p3)
        {
            throw new PendingStepException();
        }

NB What does all these parameters mean in the method brackets p0, p1 etc it just doesn't make sense.

All wording and numbers have been made up for confidentiality reasons


Solution

  • Have you tried using FeatureContext or ScenarioContext keys?

    You can create Context keys using the ScenarioContext or FeatureContext Bindings (check out this URL to see how to set this up in your StepDefinitions file: https://docs.specflow.org/projects/specflow/en/latest/Bindings/ScenarioContext.html). This way you can store keys or variables through your entire scenario or even entire feature.

    This way you can set an ApiKey in either Contexts and retrieve the ApiKey in another Step:

    1 Set API Key in Context

    _featureContext["API_KEY"] = specialKeyId;
    

    2 Retrieve API Key from Context

    var api_key = _featureContext["API_KEY"];
    

    I have an example I'm using:

    [Binding]
    public partial class StepDefinitions
    
    private readonly FeatureContext _featureContext;
    
    public StepDefinitions(FeatureContext featureContext)
    {
        _featureContext = featureContext;
    }
    
    [When(@"gebruiker nieuw account")]
    public void WhenGebruikerNieuwAccount(Table table)
    {
        var nieuw_account = DataGenerator.CreateNewAccount();
        output.WriteLine($"Nieuwe Account aangemaakt: {nieuw_account}");
        _featureContext["NIEUW_ACCOUNT"] = nieuw_account;
    }
    
    [When(@"gebruiker voert iets uit")]
    public void WhenGebruikeVoertIetsUit()
    {
        var nieuw_account = (Account)_featureContext["NIEUW_ACCOUNT"];
        selenium.WaitUntilElementThinkTimeClick(State.Visible, By.XPath($"//span[@title='{nieuw_account.Naam}']"));
        output.WriteLine("Accountnaam is " + nieuw_account.Naam);
    }
    

    1 Try defining configuration or settings first via an appsettings.json file in your project (make sure the properties of appsettings.json contains Copy If Newer to carry the file to the build folder):

    {
      "Keys": {
        "ApiKey1": "vXBx0PINNV2Tffefgwrg7WgfsQM0e6Epjc+1UJ0Y=",
        "ApiKey2": "ANOTHERKEY"
      }
    }
    

    2 Then get the key from the Configuration through Context (NuGet Microsoft.Extensions.Configuration & Microsoft.Extensions.Configuration.Json):

    private readonly IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
    

    3 Then get the API key inside the Step:

    var api_key1 = configuration["Keys:ApiKey1"]