Test Runs
The runs endpoints allow you to create and manage test executions in your project. You can create new runs, list existing runs, manage test cases within runs, and track their results.
Types of Runs
QA Sphere supports three types of test runs:
1. User Selection (Static Structure)
- Specified by
type: "static_struct"
- Test cases can be selected by their IDs or using filters (folders, tags, priorities)
- Test cases in the run are fixed after creation unless manually updated
- Updates to versioned test case properties, such as title and steps, are reflected for test cases with open statuses
2. Static Runs
- Specified by
type: "static"
- Test cases can be selected directly by IDs or using filters (folders, tags, priorities)
- Similar to Static Structure in that test cases are fixed after creation
- Updates to versioned test case properties, such as title and steps, are not reflected in the run, even for test cases with open statuses
3. Live Runs
- Specified by
type: "live"
- Only dynamic selection based on folder, tag, and priority filters
- Test cases are automatically added/removed when they match or do not match filter criteria
- Supports multiple query plans for flexible test case selection
- Updates to versioned test case properties, such as title and steps, are reflected for test cases with open statuses
note
- Updates to test cases are never propagated to closed runs
- For live and user selection runs, test case versions are fixed once the status is non-open. As a result, updates to versioned test case properties, such as title and steps, are not reflected in the run
- Changes to the folder and position of test cases are always propagated to all run types, except closed runs, because these changes are not versioned. This means that such updates do not create a new test case version and are applied to all existing versions of the test case
Test Case Selection
Test cases can be selected in two ways:
- Direct Selection: Use
tcaseIds
to directly specify the test cases - Using filters:
folderIds
: Select test cases from specific folders, including those within subfolderstagIds
: Select test cases with specific tagspriorities
: Select test cases with specific priority levels- If any of these filters is not specified or is left empty, all test cases are selected without filtering based on that criterion
- The resulting list of test cases is obtained by applying a logical AND to these conditions
This selection method is referred to as a Query Plan.
- For static and user selection runs, only single query plan can be specified. When using filters, the system automatically resolves them to a fixed set of test cases at the time of creation
- For live runs, only filter-based selection is allowed, and multiple query plans can be specified. The results of all query plans are combined using a union to create the final list of test cases. Additionally, as test case properties change, test cases are automatically added to or removed from the run according to the query plans
List Project Runs
GET/api/public/v0/project/{project_id}/run
Returns all runs in a project with their current status.
Query Parameters
Parameter | Description | Example |
---|---|---|
closed | Filter by run status | closed=true or closed=false |
milestoneIds | Filter by milestone | milestoneIds=1&milestoneIds=2 |
limit | Maximum number of runs to return | limit=10 |
Example Request
curl \
-H "Authorization: ApiKey your.api.key.here" \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run
Response Fields
{
runs: Array<{
id: number // Unique identifier of the test run
type: string // Type of the run 'static' | 'static_struct' | 'live'
projectId: string // ID of the project this run belongs to
project: { // Project details
id: string // Project unique identifier
code: string // Project code
title: string // Project title
}
milestoneId: number | null // ID of associated milestone if any
milestone: object | null // Milestone details if associated
assignmentId: number // ID of the assigned user
assignment: { // Assignment details
id: number // User ID
email: string // User email
name: string // User display name
avatar: string // URL to user's avatar
role: string // User role in the project
}
title: string // Title of the test run
description: string // Description of the test run
statusCounts: { // Count of test cases by status
all: number // Total test cases
blocked: number // Blocked test cases
failed: number // Failed test cases
open: number // Open test cases
passed: number // Passed test cases
skipped: number // Skipped test cases
}
timeSpent: number | null // Time spent on the run
createdAt: string // Creation timestamp
closedAt: string | null // Closure timestamp
closedByUserId: number | null // ID of user who closed the run
}>
}
Create New Run
POST/api/public/v0/project/{project_id}/run
Creates a new test run in the project.
- For
static
/static_struct
run types:- Only a single query plan should be specified, and either of the two selection methods (direct or filters) can be used
- When using filters, the system automatically resolves them to a fixed set of test cases at the time of creation
- For
live
run types, only filter-based selection is permitted, and multiple query plans can be specified - Within a given query plan, the filter conditions are combined using a logical AND
- The test case lists obtained from different query plans are combined using a union
Request Body
{
title: string // Required: Run title
description?: string // Optional: Run description
type: "static" | "static_struct" | "live" // Required: Run type
milestoneId?: number // Optional: Associated milestone
assignmentId?: number // Optional: Assigned user
queryPlans: Array<{ // Required: Test case selection criteria
// Direct Selection:
tcaseIds?: Array<string> // Directly specify test cases
// Using Filters:
folderIds?: Array<number> // Select test cases from folders (including subfolders)
tagIds?: Array<number> // Select test cases with tags
priorities?: Array<"low" | "medium" | "high"> // Select by priority
}>
}
Field Constraints
title
: Must be 1-255 characters long and unique within the projectdescription
: Maximum 512 charactersqueryPlans
:- For non-live runs: Only one query plan is allowed
- For live runs: Only filter based selection is allowed
assignmentId
: Must be an active user with permissions above Viewer role
Example Request - Live Run With Filtered Test Cases
curl \
-H "Authorization: ApiKey your.api.key.here" \
-H "Content-Type: application/json" \
-d '{
"title": "Sprint 23 Regression",
"description": "Regression test suite for Sprint 23 release",
"type": "live",
"milestoneId": 5,
"queryPlans": [{
"folderIds": [1, 2],
"tagIds": [1],
"priorities": ["high"]
}, {
"folderIds": [4, 6],
"tagIds": [],
"priorities": ["medium", "high"]
}]
}' \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run
Example Request - Live Run With All Test Cases
curl \
-H "Authorization: ApiKey your.api.key.here" \
-H "Content-Type: application/json" \
-d '{
"title": "Complete Test Suite",
"description": "Run with all test cases from the project",
"type": "live",
"milestoneId": 5,
"queryPlans": [{
"folderIds": [],
"tagIds": [],
"priorities": []
}]
}' \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run
Example Request - Static Run With Specific Test Cases
curl \
-H "Authorization: ApiKey your.api.key.here" \
-H "Content-Type: application/json" \
-d '{
"title": "Specific Test Cases Run",
"type": "static",
"queryPlans": [{
"tcaseIds": ["1CEPaUhgH_Tvt2LZygwVRQa", "1CAPaUhgH_Tvt2LZygwVRTb", "1EEPaUhgH_Tvt2LZygwVRLm"]
}]
}' \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run
Response
Status: 201 Created
{
"id": 2
}
Best Practices
- Use live runs for ongoing test suites that should automatically update
- Use static runs for fixed test sets like release certifications
- Always provide descriptive titles and link runs to milestones when applicable
- Assign runs to specific users for better accountability
Clone Existing Run
POST/api/public/v0/project/{project_id}/run/clone
Creates a new run by cloning an existing one. For live runs, the new run will reflect current test case states.
Request Body
{
runId: number // Required: Source run ID to clone
title: string // Required: New run title
description?: string // Optional: New description
milestoneId?: number // Optional: New milestone
assignmentId?: number // Optional: New assignee
}
Field Constraints
title
: Must be 1-255 characters long and unique within the projectdescription
: Maximum 512 charactersrunId
: Must be a valid run ID in the projectmilestoneId
: Must be a valid milestone ID if providedassignmentId
: Must be an active user with permissions above Viewer role
Example Request
curl \
-H "Authorization: ApiKey your.api.key.here" \
-H "Content-Type: application/json" \
-d '{
"runId": 1,
"title": "Sprint 24 Regression - Clone",
"description": "Cloned regression suite for Sprint 24",
"milestoneId": 5,
"assignmentId": 1
}' \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run/clone
Example Response
{
"id": 2
}
note
When cloning a live run, the new run will:
- Maintain the same query plans as the original run
- Reflect the current state of test cases (may differ from the original run)
- Start with all test cases in 'open' status regardless of the original run's results
Close Run
POST/api/public/v0/project/{project_id}/run/{run_id}/close
Close an open test run.
Example Request
curl \
-H "Authorization: ApiKey your.api.key.here" \
-H "Content-Type: application/json" \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run/1/close
List Run Test Cases
GET/api/public/v0/project/{project_id}/run/{run_id}/tcase
Returns all test cases in a run with their current status.
Query Parameters
Parameter | Description |
---|---|
include=folder | Include folder information for each test case |
Example Request
curl \
-H "Authorization: ApiKey your.api.key.here" \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run/1/tcase?include=folder
Response Fields
{
"tcases": Array<{
id: string // Unique identifier of the test case
version: number // Version number of the test case
legacyId: string // Legacy identifier (if any)
folderId: number // ID of the folder containing the test case
pos: number // Position within the folder
seq: number // Sequence number
title: string // Title/description of the test case
priority: string // Priority level (high, medium, etc.)
status: string // Current status of the test case
isAutomated: boolean // Whether the test case is automated
folder?: { // Folder information if include query parameter is passed
id: number // Unique identifier for the folder
parentId: number // Unique identifier of the parent of the folder (0 if it is the root folder)
title: string // Title of the folder
comment: string // Added comment for the folder
pos: number // Position of the folder with respect to its sibling (starts with 0)
}
}>
}
Sample Response
{
"tcases": [
{
"id": "1CGeNaNVt_Axa7TcMjUm6Zh",
"version": 1,
"legacyId": "",
"folderId": 11848,
"pos": 3,
"seq": 8,
"title": "The \"Checkout\" page with products from the cart should be shown after clicking the \"Checkout\" button",
"priority": "high",
"status": "open",
"isAutomated": false
},
{
"id": "1CGeNaNWP_Eiq5mjzPsKSX9",
"version": 1,
"legacyId": "",
"folderId": 11848,
"pos": 4,
"seq": 9,
"title": "The cart is still filled after going back from the \"Checkout\" page without submitting it",
"priority": "medium",
"status": "open",
"isAutomated": false
}
]
}
Get Run Test Case
GET/api/public/v0/project/{project_id}/run/{run_id}/tcase/{tcase_or_legacy_id}
Get details of a single run test case using its ID, sequence or legacy ID.
Example Request
curl \
-H "Authorization: ApiKey your.api.key.here" \
https://your-company.your-region-code.qasphere.com/api/public/v0/project/BD/run/1/tcase/1
Response Fields
{
id: string // Unique identifier of the test case
version: number // Version number of the test case
legacyId: string // Legacy identifier (if any)
title: string // Title of the test case
seq: number // Sequence number of the test case
folderId: number // Identifier of the folder where the test case is placed
pos: number // Ordered position (0 based) of the test case in its folder
priority: string // Priority of the test case (`high` | `medium` | `low`)
comment: string // Test description/precondition
steps: Array<{ // List of test case steps
description: string // Details of steps
expected: string // Expected result from the step
}>
tags: Array<{ // List of test case tags
id: number // Unique identifier of the tag
title: string // Title of the tag
}>
files: Array<{ // List of files attached to the test case
id: string // Unique identifier of the file
fileName: string // Name of the file
mimeType: string // Mime type of the file
size: number // Size of the file
url: string // URL of the file
}>
requirements: Array<{ // Test case requirement (currently only single requirement is supported on UI)
id: string // Unique identifier of the requirement
text: string // Title of the requirement
url: string // URL of the requirement
}>
links: Array<{ // Additional links relevant to the test case
text: string // Title of the link
url: string // URL of the link
}>
authorId: number // Unique identifier of the user who created the test case
createdAt: string // Test case creation timestamp (ISO 8601 format)
status: string // Status of the latest result added for the run test case (open if no results are added)
isAutomated: boolean // Whether latest result was added using APIs
isLatestVersion: boolean // Whether this is the latest version of the test case
results: Array<{ // Results created for this test case in the run
id: number // Unique identifier of the test case result
tcaseId: string // Unique identifier of the test case
tcaseVersion: string // Version number of the test case
authorId: number // Unique identifier of the user who added the result
author: { // Details of the user who added the result
id: number // Unique identifier of the user
email: string // Email of the user
name: string // Name of the user
avatar: string | null // Avatar of the user
role: "owner" | "admin" | "user" | "test-runner" | "viewer" // Role of the user
}
status: string // Result status ("passed" | "failed" | "blocked" | "skipped" | "open" | "custom1" | "custom2" | "custom3" | "custom4")
comment: string // Comments/observations while executing the test case
links: Array<{ // Details of issues created in external integrations
id: number // Unique identifier of the issue
resultId: number // Unique identifier of the result for which the issue is created
integrationId: string // Unique identifier of the external integration on which the issue is created
integration: { // Details of the external integration
id: string // Unique identifier of the integration
name: string // Name of the integration
type: "jira" | "github" | "custom" // Integration type
config: object // Configuration for the integration (eg. url/email)
}
url: string // URL of the created issue
text: string // Title of the created issue
meta: object // Additional information related to the issue
}>
timeTaken: number | null // Time taken for executing the test case
apiKeyId: string | null // Unique identifier of the API key, if this result was added via public APIs
internal: boolean // Whether the result was added by system (eg. when test run is modified)
createdAt: string // Result creation time (ISO 8601 format)
}>
}
Sample Response
{
"id": "1CEPaUhgH_Tvt2LZygwVRQa",
"version": 1,
"legacyId": "",
"title": "Changing to corresponding cursor after hovering the element",
"seq": 1,
"folderId": 2,
"pos": 0,
"priority": "low",
"comment": "<p>The \"About Us\" page is opened</p>",
"steps": [
{
"description": "<p>Test the display across various screen sizes (desktop, tablet, mobile) to ensure that blocks and buttons adjust appropriately to different viewport widths</p>",
"expected": ""
}
],
"tags": [
{
"id": 1,
"title": "About Us"
},
{
"id": 2,
"title": "Checklist"
}
],
"files": [],
"requirements": [],
"links": [],
"authorId": 1,
"createdAt": "2024-01-01T00:00:00.000Z",
"status": "open",
"isAutomated": false,
"isLatestVersion": true,
"results": [
{
"id": 20293,
"tcaseId": "1CEPaUhgH_Tvt2LZygwVRQa",
"tcaseVersion": 1,
"authorId": 1,
"author": {
"id": 1,
"email": "[email protected]",
"name": "System Owner",
"avatar": null,
"role": "owner"
},
"status": "blocked",
"comment": "",
"links": null,
"timeTaken": null,
"apiKeyId": null,
"internal": false,
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}