I have a pipeline that runs integration tests, and I need to associate the test results with test cases in a test plan. To achieve this, I use scripts to:
- Update test cases within the test plan.
- Associate test results with the corresponding test cases.
While the process works and the results appear correctly in Azure, I noticed that an additional manual test run is created for each test case result association.
Is there a way to prevent these multiple test runs from being generated? Or is there an alternative approach to automatically associate test cases with test results after a test run without triggering new test runs?
Below are the scripts used for this process:
Script to automatically update test cases in Azure:
// Create a new test case
const createTestCase = async (testCase) => {
const url = `${config.orgUrl}/${config.project}/_apis/wit/workitems/$Test Case?api-version=6.0`;
const data = [
{ op: 'add', path: '/fields/System.Title', value: testCase.name },
{ op: 'add', path: '/fields/Microsoft.VSTS.TCM.AutomatedTestName', value: testCase.name },
{ op: 'add', path: '/fields/Microsoft.VSTS.TCM.AutomatedTestId', value: generateAutomatedTestId(testCase) }
];
try {
const response = await axios.post(url, data, { headers });
console.log(`Test case created: ${response.data.id}`);
return response.data.id;
} catch (error) {
console.error('Error creating test case:', error.response?.data || error.message);
throw error;
}
};
// Update an existing test case
const updateTestCase = async (testCaseId, testCase) => {
const url = `${config.orgUrl}/${config.project}/_apis/wit/workitems/${testCaseId}?api-version=6.0`;
const data = [
{ op: 'add', path: '/fields/System.Title', value: testCase.name },
{ op: 'add', path: '/fields/Microsoft.VSTS.TCM.AutomatedTestName', value: testCase.name }
];
try {
const response = await axios.patch(url, data, { headers });
console.log(`Test case updated: ${testCaseId}`);
return response.data.id;
} catch (error) {
console.error('Error updating test case:', error.response?.data || error.message);
throw error;
}
};
Script to associate Test cases with test results:
const associateTestResults = async (runId, testCaseId) => {
const url = `${config.orgUrl}/${config.project}/_apis/test/runs/${runId}/results?api-version=6.0`;
const body = [{
testCase: { id: testCaseId },
outcome: "Passed"
}];
try {
const response = await axios.post(url, body, { headers });
console.log(`Test result associated with test case ${testCaseId}`);
} catch (error) {
console.error('Error associating test result:', error.response?.data || error.message);
throw error;
}
};
YAML Tasks to execute these steps:
- script: |
npm run test || exit 0
displayName: 'Run tests'
env:
TEST_USER_PASSWORD: $(TEST_USER_PASSWORD)
SERVICE_BUS_CONNECTION_STRING: $(SERVICE_BUS_CONNECTION_STRING)
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/results/testResults.xml'
testRunTitle: 'IntegrationTests-TEST'
publishRunAttachments: true
displayName: 'Publish Test Results'
name: PublishTestResults
- task: PowerShell@2
displayName: 'Get Latest Test Run ID'
inputs:
targetType: 'inline'
script: |
$url = "https://org/project/_apis/test/runs?api-version=7.1-preview.3"
$headers = @{
"Authorization" = "Bearer $(AZURE_DEVOPS_API_TOKEN)"
"Content-Type" = "application/json"
}
$maxRetries = 10
$retryDelay = 5
$testRunId = $null
for ($i = 1; $i -le $maxRetries; $i++) {
Write-Host "Attempt $($i): Fetching test run..."
try {
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
Write-Host "Response: $($response | ConvertTo-Json)"
$matchingRun = $response.value | Where-Object { $_.name -eq "IntegrationTests-TEST" } | Sort-Object -Property id -Descending | Select-Object -First 1
if ($matchingRun) {
$testRunId = $matchingRun.id
Write-Host "Found Test Run ID: $testRunId"
break
}
} catch {
Write-Host "Error: $($_.Exception.Message)"
}
Write-Host "Test Run ID not found yet. Retrying in $retryDelay seconds..."
Start-Sleep -Seconds $retryDelay
}
if (-not $testRunId) {
Write-Host "##[error]Failed to retrieve Test Run ID after $maxRetries attempts."
exit 1
}
Write-Host "##vso[task.setvariable variable=TEST_RUN_ID]$testRunId"
env:
AZURE_DEVOPS_API_TOKEN: $(AZURE_DEVOPS_API_TOKEN)
- script: |
node $(System.DefaultWorkingDirectory)/results/testResults.js
displayName: 'Process Test Results'
env:
TEST_RUN_ID: $(TEST_RUN_ID)
AZURE_DEVOPS_API_TOKEN: $(AZURE_DEVOPS_API_TOKEN)