1

I'm attempting to make use of the SpecFlow+ targets functionality as described here, and although I've managed to get the additional scenarios to show in the test explorer window for my different tags, when running in parallel I'm not able to get the correct 'Target' value from the transformed App.config for that particular thread/scenario.

E.g.

Scenario looks like the following...

@Browser_Chrome
@Browser_Edge
Scenario:[Apprentice Management] Navigate to add new apprentice
    Given The user is logged into the Smart End Point Assessment website
    When The user is on the Apprentice -> Add Apprentice page
    Then The user will be on the Apprentice Details page

Targets section in .srprofile file looks like the following...

<Targets>
    <Target name="Edge">
      <Filter>Browser_Edge</Filter>
      <DeploymentTransformationSteps>
        <EnvironmentVariable variable="Test_Browser" value="Edge" />
      </DeploymentTransformationSteps>
    </Target>
    <Target name="Chrome">
      <Filter>Browser_Chrome</Filter>
      <DeploymentTransformationSteps>
        <EnvironmentVariable variable="Test_Browser" value="Chrome" />
      </DeploymentTransformationSteps>
    </Target>
  </Targets>

Transformation that tweaks the value in the relocated configuration file...

<add key="browser" value="{Target}" 
xdt:Locator="Match(key)" 
xdt:Transform="SetAttributes(value)" /> 

Scenario showing up for each target in the test explorer window. All fine so far...

enter image description here

The problem is, if I try to run those 2 scenarios together, in code I'm not able to access the correct browser app.config value for each running thread.

Here are 2 options for trying to retrieve that value in code...

string testBrowserOne = ConfigurationManager.AppSettings["browser"];
string testBrowserTwo = Environment.GetEnvironmentVariable("Test_Browser");

Debug.WriteLine($"Test Thread {Thread.CurrentThread.ManagedThreadId}. testBrowserOne = {testBrowserOne}");
Debug.WriteLine($"Test Thread {Thread.CurrentThread.ManagedThreadId}. testBrowserTwo = {testBrowserTwo}");

The output from running these 2 threads/scenarios is as follows....

Test Thread 21. testBrowserOne = Edge   
Test Thread 21. testBrowserTwo = Chrome
Test Thread 20. testBrowserOne = Edge
Test Thread 20. testBrowserTwo = Chrome

I've no idea why these 2 different methods for retrieving the value are returning different values but it's largely irrelevant. The issue is that both threads are returning the same values, which means I can't have one scenario run a chrome test, and one scenario run an edge test at the same time. They would either both run as Chrome or both run as Edge.

What could be the issue here?

Other relevant .srprofile settings are below

  <Execution stopAfterFailures="0"
             testThreadCount="3"
             testSchedulingMode="Random"
             retryFor="Failing"
             retryCount="1"
             apartmentState="MTA"  />
  <VSTest testRetryResults="Unified"
          passRateAbsolute="1" />
  <Environment testThreadIsolation="SharedAppDomain" platform="x86"/>

I'm worried this is a symptom of using SharedAppDomain and there is no solution.

Konzy262
  • 2,747
  • 6
  • 42
  • 71

1 Answers1

1

You are right. The problem is the SharedAppDomain testThreadIsolation. The EnvironmentVariable Deploymentstep only works with the Process testThreadIsolation mode.

You can only set environment variables on a process level. In the same process, they will be overwritten all the time.

Change the testThreadIsolation mode to Process and it should work as expected.


Full disclosure: I am one of the developers on SpecFlow and SpecFlow+

Andreas Willich
  • 5,665
  • 3
  • 15
  • 22
  • Thanks for this. Sadly I make use of the `[BeforeTestRun]` and `[AfterTestRun]` hooks to setup and teardown some shared state that is referenced during the running of my scenarios (e.g. setting up a logger once then using it in every scenario). I don't believe I can do this with the execution mode set to `Process`. I am aware 'global' before and after test run actions can be performed with deployment transformation steps but again, I don't think any state referenced their can also be accessed during scenario execution. – Konzy262 Jan 29 '20 at 10:22
  • I assume I can run all tests in parallel of a particular target type (specified using filters) during a test run still with `SharedAppDomain`. I just can't mix and match targets in the same test run. – Konzy262 Jan 29 '20 at 10:25