Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Update existing manual test cases in XRay using python

Dileep Krishnan
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
June 12, 2025

I am trying to update existing manual test cases in XRay in an automated manner using python. Below is the function I use. I have only 1 test step.

def update_manual_test_case_rest(test_case_key, summary=None, description=None, steps=None, labels=None,attachments=None):
"""
Updates a manual test case in XRay for Jira using the REST API.

Args:
test_case_key (str): The key of the test case to update (e.g., "TP-123").
summary (str, optional): The new summary/title of the test case. Defaults to None.
description (str, optional): The new description of the test case. Supports image inclusion (as Markdown). Defaults to None.
steps (list of dict, optional): A list of dictionaries representing the test steps.
Each dictionary should have 'action', 'data', and 'result' keys. Defaults to None.
labels (list of str, optional): A list of labels to add or replace on the test case. Defaults to None.
attachments (list of tuple, optional): A list of tuples, where each tuple contains:
- file_path (str): The path to the image file.
- filename (str, optional): The desired filename for the attachment in Jira.
If None, the original filename will be used. Defaults to None.
"""
update_url = f"{jira_url}/rest/api/2/issue/{test_case_key}"
payload = {"fields": {}}
if summary:
payload["fields"]["summary"] = summary

if description:
payload["fields"]["description"] = description

if steps is not None:
step_objects = []
for step in steps:
step_objects = [{
"index": 1,
"action": step.get("action", ""),
"data": step.get("data", ""),
"expected result": step.get("result", "")
}]
payload["fields"]["customfield_123456"] = {"steps": step_objects}

if labels is not None:
payload["fields"]["labels"] = labels

if payload["fields"]:
try:
response = requests.put(update_url, headers=headers, auth=auth, data=json.dumps(payload))
response.raise_for_status() # Raise an exception for bad status codes
print(f"Successfully updated test case: {test_case_key}")
except requests.exceptions.RequestException as e:
print(f"Error updating test case {test_case_key}: {e}")
if response is not None:
print(f"Response status code: {response.status_code}\n")
try:
print(f"Response body: {response.json()}")
except json.JSONDecodeError:
print(f"Response body: {response.text}")
else:
print(f"No updates provided for test case: {test_case_key}")

When executing, I am getting the below error.

Error updating test case {issue_id}: 400 Client Error: Bad Request for url: {jira_url}//rest/api/2/issue/{issue_id}Response status code: 400

Response body: {'errorMessages': ['Exception occurred: java.lang.NullPointerException'], 'errors': {}}

How can I rectify this?

1 answer

Suggest an answer

Log in or Sign up to answer
0 votes
David Nickell
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 13, 2025

I don't read python but if your code tuly produces 2 slashes between your base URL and the word REST, that is my guess.  

Francisco Fonseca _Xray_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 20, 2025

Hi @Dileep Krishnan,

Welcome to the community!

Thanks for sharing your script. Based on the error message and reviewing your payload structure, there are a few likely causes:

  • Make sure the base URL in jira_url ends without a trailing slash, to avoid //rest/... when building update_url.
  • In your steps payload, make sure to use the correct JSON field names. For Xray, the expected key is:
{
"index": 1,
"action": "...",
"data": "...",
"expectedResult": "..."
}
  • Also, ensure that customfield_123456 is replaced with your actual custom field ID for the Manual Test Steps field.

If you’re still facing issues, we recommend reaching out to our support team directly so they can take a deeper look at your configuration and setup: https://jira.getxray.app/servicedesk/customer/portal/2

@David Nickell  – great catch on the double slash. 

Best,
Francisco

TAGS
AUG Leaders

Atlassian Community Events