Search code examples
c#azure-devopsazure-pipelinesvstesttestrunconfig

Pass Variables from one Visual Studio Test Task to Another in Azure Pipeline through multiple agents


I have couple of unit tests in the project which are dependent to one another. After one test runs, i will capture the output, wait for it to synchronize in another system and perform another test using the output of the first test. I am trying to achieve this using azure pipeline. I created 3 Agent Jobs -, in Job A, I am running Unit Test1 and creating a output variable which am passing to a variable in Job C, Job B is an agent less server to delay for 1 minute in between these 2 agents. I have used overrideTestrunParameters: '-sauce2 $(sauce5)' to override the parameters for second test but i got below error, while passing the parameters to the second agent task.

[warning]Unable to parse the override run parameters string: -sauce2 crushed tomatoes

[error]SetupPhase.Run : Exception occurred during the updation of run settings: System.FormatException: Error encountered while overriding test run parameters. Please check the test run parameteres provided.

at Microsoft.VisualStudio.TestService.SettingsManager.OverrideParamsSettingsProcessor.GetOverrideParameters(String overrdeParametersString) at Microsoft.VisualStudio.TestService.SettingsManager.OverrideParamsSettingsProcessor.UpdateSettingsWithParameters(XDocument settings) at Microsoft.VisualStudio.TestService.SettingsManager.CommonSettingsManager.UpdateCommonSettings(InputDataContract inputDataContract, SettingsModifier settingsModifier) at Microsoft.VisualStudio.TestService.SettingsManager.SettingsManager.UpdateSettingsAsRequired(InputDataContract inputDataContract) at MS.VS.TestService.VstestConsoleAdapter.SetupPhase.Run(VstestConsoleRunContext testRunContext, CancellationToken cancellationToken)

[error]Settings updation failed with error: Error encountered while overriding test run parameters. Please check the test run parameteres provided.

TestRunParameters:

 <RunSettings>
 <TestRunParameters>
    <Parameter name="sauce" value="chilly" />
    <Parameter name="sauce1" value="chilly1" />
    <Parameter name="sauce2" value="chilly2" />
</TestRunParameters>

UnitTests:

[Test]
    public void UnitTest1()
    {
        string sauce = TestContext.Parameters["sauce"];
        string sauce1 = TestContext.Parameters["sauce1"];
        TestContext.Progress.WriteLine(sauce);
        TestContext.Progress.WriteLine(sauce1);
        //creating outpute variable in azure
        TestContext.Progress.WriteLine("##vso[task.setvariable variable=sauce4;Secret=false;isOutput=true;]crushed tomatoes");
    }

    [Test]
    public void UnitTest2()
    {
        string sauce2 = TestContext.Parameters["sauce2"];
        TestContext.Progress.WriteLine($"sauce2: {sauce2}");
    }

Azure.yaml pipeline:

jobs:


- job: A
pool:
  name: New Agent Pool
  demands: 
  - msbuild
  - visualstudio
  - vstest

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Debug'
  sauce: 'tomato'
  sauce1: 'pepper'

steps:
- task: NuGetCommand@2
  displayName: 'NuGet restore'
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'      

- task: VSTest@2
  displayName: 'Unit Test1'
  inputs:
    testAssemblyVer2: |
      **\$(BuildConfiguration)\*Test*.dll
      !**\obj\**
    testFiltercriteria: 'Name=UnitTest1'
    runSettingsFile: SeleniumTest.ABC/Test.runsettings
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    overrideTestrunParameters: '-sauce $(sauce)'
  name: 'OutputVar'

  - job: B
dependsOn: 
  - A 
pool: server
steps:
- task: Delay@1
  inputs:
    delayForMinutes: '1'

  - job: C
dependsOn: 
  - A 
  - B
pool:
  name: New Agent Pool
  demands: 
  - msbuild
  - visualstudio
  - vstest

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Debug'
  sauce2: $[dependencies.A.outputs['outputVar.sauce4']]

steps:
- task: NuGetCommand@2
  displayName: 'NuGet restore'
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
  
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      # Write your PowerShell commands here.      
      Write-Host run time value
      Write-Host sauce2 = $(sauce2)

- task: VSTest@2
  displayName: 'Unit Test2'
  inputs:
    testAssemblyVer2: |
      **\$(BuildConfiguration)\*Test*.dll
      !**\obj\**
    testFiltercriteria: 'Name=UnitTest2'
    runSettingsFile: SeleniumTest.ABC/Test.runsettings
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    overrideTestrunParameters: '-sauce2 $(sauce2)'
  condition: succeededOrFailed()

Screenshots: enter image description here

I could see that in Powershell task new run time parameter is printed, but its failing in VS Test Task. Can some one advise me how to capture run time variables in VSTest Task and pass to another VSTest Task in Azure pipelines.


Solution

  • The output variable is successfully past from job A to job C, for the powershell task can print out the new variable $(source2).

    The problem came from the overrideTestrunParameters: '-sauce2 $(sauce2)' of the vstest task in job C. $(sauce2) is evaluate to crushed tomatoes without quotes "".

    Please try wrapping $(sauce2) in double quotes:

    overrideTestrunParameters: '-sauce2 "$(sauce2)"'