Public/Api/TestPlan/Add-TestCaseToTestSuite.ps1
function Add-TestCaseToTestSuite { <# .SYNOPSIS Adds test cases to a test suite. .DESCRIPTION Adds one or more test cases to a test suite using Azure DevOps Test Plans API. .PARAMETER CollectionUri Url for project collection on Azure DevOps server instance. If not specified, $global:AzureDevOpsApi_CollectionUri (set by Set-AzureDevopsVariables) is used. .PARAMETER Project Project name, identifier, full project URI, or object with any one these properties. If not specified, $global:AzureDevOpsApi_Project (set by Set-AzureDevopsVariables) is used. .PARAMETER Plan Test plan object (with id and project properties) or test plan ID. When providing an object, the Project and CollectionUri are extracted from it. When providing an ID, relies on Project and CollectionUri parameters or global defaults. .PARAMETER Suite Test suite object or test suite ID. Can be piped from Get-TestSuitesList. .PARAMETER TestCaseId Array of test case IDs to add to the suite. .NOTES https://learn.microsoft.com/en-us/rest/api/azure/devops/testplan/test-suite-test-case/add-test-cases-to-suite?view=azure-devops-rest-7.1 #> [CmdletBinding(DefaultParameterSetName = 'FromId')] param( [Parameter(ParameterSetName = 'FromPipeline', Mandatory, ValueFromPipeline)] [AllowNull()] $InputObject, [Parameter(ParameterSetName = 'FromId', Position = 0)] [AllowNull()] [AllowEmptyString()] $Project, [Parameter(ParameterSetName = 'FromId')] [AllowNull()] [AllowEmptyString()] $CollectionUri, [Parameter(ParameterSetName = 'FromId', Position = 1)] [Alias('PlanId', 'Id')] $Plan, [Parameter(ParameterSetName = 'FromId', Mandatory, Position = 2)] [Alias('SuiteId')] $Suite, [Parameter(Mandatory, Position = 3)] [Alias('TestCaseIds', 'WorkItemId', 'WorkItemIds')] [int[]] $TestCaseId ) process { # Handle pipeline input if ($null -ne $InputObject) { # Check if InputObject has plan property (indicates it's a suite object) if ($InputObject -and $InputObject.plan.id) { # This is a suite object with plan property $Suite = $InputObject $Plan = $InputObject.plan.id # If suite has project property, use it if ($InputObject.project) { $Project = $InputObject.project } } elseif ($InputObject -and $InputObject.id) { # Check if it has typical plan properties (project and id without plan property) if ($InputObject.project -and -not $InputObject.plan) { # Treat as plan object $Plan = $InputObject } else { # Treat as suite object $Suite = $InputObject } } else { # Otherwise treat as plan object $Plan = $InputObject } } # If Suite is provided and has plan property but Plan is not set, extract it if ($null -eq $Plan -and $Suite -and $Suite.plan.id) { $Plan = $Suite.plan.id } # Extract plan ID and project information from plan object if needed $planId = $null if ($null -eq $Plan) { throw "Plan must be specified either directly or via a Suite object with TestPlanId property." } if ($Plan -and $Plan.project -and $Plan.id) { # Use project from plan object if available $Project = $Plan.project # It's a plan object with an id property $planId = $Plan.id } elseif ($Plan -match '^\d+$') { # It's a plan ID $planId = [int]$Plan } else { throw "Plan must be a test plan object with an 'id' property or a numeric plan ID." } # Extract suite ID from suite object if needed $suiteId = $null if ($Suite -and $Suite.id) { # It's a suite object with an id property $suiteId = $Suite.id } elseif ($Suite -match '^\d+$') { # It's a suite ID $suiteId = [int]$Suite } else { throw "Suite must be a test suite object with an 'id' property or a numeric suite ID." } # Get connection to project $connection = Get-ApiProjectConnection ` -CollectionUri $CollectionUri ` -Project $Project # POST https://dev.azure.com/{organization}/{project}/_apis/testplan/Plans/{planId}/Suites/{suiteId}/TestCase?api-version=7.1 $uri = Join-Uri ` -Base $connection.ProjectBaseUri ` -Relative "_apis/testplan/Plans/$($planId)/Suites/$($suiteId)/testcase" ` -NoTrailingSlash # Ensure we use at least API version 5.1 for this endpoint if ($connection.ApiVersion -lt [Version]'5.1') { $connection.ApiVersion = [Version]'5.1' } $body = @( $TestCaseId | ForEach-Object { [PSCustomObject] @{ workItem = [PSCustomObject] @{ id = $_ } } } ) $bodyString = ConvertTo-Json -Depth 3 -InputObject $body # Make the call Invoke-ApiListPaged ` -ApiCredential:$connection.ApiCredential ` -ApiVersion:$connection.ApiVersion ` -Uri:$uri ` -Method:POST ` -Body $bodyString } } |