I’m working on setting up automated testing with Azure DevOps by integrating our test automation framework with Azure Test Plans using pipeline tasks.
We’re following the documented approach to programmatically create a test run, but I’m stuck at the first step — trying to retrieve the testPlanId using a planName parameter. It seems like the value isn’t being returned, possibly because the accessToken isn’t passed correctly?
Here’s a snippet of what we’re doing:
parameters:
- name: planName
type: string
stages:
- stage: get_TestplanID
pool:
name: myspoke
jobs:
- job: Get_TestPlanID
steps:
-
script: |
echo ${AZURE_DEVOPS_CLI_PAT} | az devops login
env:
AZURE_DEVOPS_CLI_PAT: $(System.AccessToken)
displayName: ‘Login to Azure DevOps’
-
bash: |
TestPlan_ID=$(curl --location --request GET ‘Azure DevOps Services | Sign In’
–header “Authorization: Basic $(echo -n :${AZURE_DEVOPS_CLI_PAT} | base64)” | jq “.value[] | select(.name=="${{ parameters.planName }}") | .id”)
echo “##vso[task.setvariable variable=TestPlanID]$TestPlan_ID”
I need to:
Extract testPlanID using the plan name.
Pass that to the next job to fetch suiteID, testCaseID, testPointID, and create a test run.
Update test results programmatically and optionally create bugs.
Has anyone successfully implemented automated testing with Azure DevOps and Azure Test Plans like this?
Is there a better approach to passing and chaining these IDs between tasks?
Any examples of working curl/PowerShell-based workflows would be helpful.
Been knee-deep in automated testing with Azure DevOps for a while now…
Yeah, I’ve run into the same hiccup, turns out the System.AccessToken wasn’t being passed correctly. Azure DevOps doesn’t enable that token by default, which tripped me up. You’ve got to manually allow it under pipeline permissions. Go to your pipeline settings and check the option: Allow scripts to access OAuth token.
Once that’s set, using this helped smooth things out:
echo ":$(System.AccessToken)" | base64
This worked better than hardcoding tokens. Made my curl calls work instantly, super useful when you’re scripting API calls for testPlanID lookup.
Jumping in here, I’ve been working with automated testing with Azure DevOps for over a year now, and I totally get where Tom’s coming from.
We faced similar issues initially and ended up switching from the az devops
CLI to raw REST API calls via PowerShell’s Invoke-RestMethod
. It gave us more control and helped with debugging.
What really helped was chaining things dynamically:
- testPlanID → suiteID → testCaseID
Each ID got exported as a pipeline variable using:
Write-Host "##vso[task.setvariable variable=testPlanID]$planId"
This way, data flowed cleanly across tasks. If you’re deep into automated testing with Azure DevOps, I’d say consolidating your fetch logic into a single script helps a lot, avoids job-to-job context loss.
Adding on to what Tom and Toby shared, we’ve built a robust setup for automated testing with Azure DevOps in our org.
What worked best for us was leveraging YAML templates to manage our test orchestration. We set the testPlanID, suiteID, and testPointID as job-level output variables instead of task-level ones. That way, they persist across jobs, like this:
dependencies.jobName.outputs['stepName.variableName']
It’s a much cleaner solution, especially when you’re passing data between multiple stages. Also, we phased out jq
in favor of pure PowerShell for better cross-platform support and error handling, especially when running on Windows agents.
Keeping it modular and readable goes a long way when scaling automated testing with Azure DevOps across multiple projects.