Can I report my automation tool test results to Testuff?

Yep! It allows your automation to update test results in Testuff, using the API.

Which tools are currently supported?

Testuff API enable us to integrate any tool that supports HTTP requests from a script, so we can integrate with virtually any tool on the market.

We have already successfully integrated Testuff with the following leading automation tools:

How do I set it up?

The API url can be found in the Settings link at the top of the Testuff window. Just add to it run/ to report test results. To retrieve the Test IDs simply right click the relevant suite or tests that are automated, and select Show IDs.

Create your automation scripts. See examples below. Scripts need to send HTTP POSTs with the following parameters:

  • test_id – the relevant test ID for which the result is reported.
  • status – test execution status, should be passed, blocked, or failed.
  • steps_failed – (optional) list of failed steps. Example “1,3,5”. You can use step_id instead of the step position.
  • steps_passed – (optional) list of passed steps.
  • steps_blocked – (optional) list of blocked steps.
  • branch_name – (optional) the name of the branch where the test result should appear.
  • lab_name – (optional) the name of the lab where the test result should appear.
  • run_configuration – (optional) specifies the run configuration used for the test.
  • comment – (optional) add a free text comment to the execution.
  • version – (optional) specifies the version used for the test.

The result header should include a Location result, which is the URI for the newly created run.

Make sure you receive an HTTP 201 response when sending the POSTs. Otherwise something has gone wrong. If something has indeed gone wrong, there should be information in the HTTP response as to the trouble.

As usual, feel free to contact us if you have any issues or questions.

What happens to the tests when creating a new branch?

When copying a branch we keep the test IDs for automation. If you want to run the tests in the new branch, just change the branch_name parameter in the scripts.

How do I look up tests by their IDs?

Just enter the ID in the search box at the top right and press enter.

What about some code examples?

Make sure to use basic authentication, with your Testuff username and password.


curl -u username:password -k -H "Content-Type: application/json" -X POST
--data "{\"test_id\":\"AUTOMATION_ID\",\"status\":\"failed\"}"


import urllib2
import json
import base64

parameters = {"test_id": TEST_AUTOMATION_ID,
"status": "failed",
"comment": "ANY COMMENT"}

username = "TESTUFF_LOGIN"
password = "PASSWORD"
url = ""

opener = urllib2.build_opener()

request = urllib2.Request(url)
request.add_header("Content-Type", "application/json")
request.add_header("Accept", "application/json")
encoded = base64.encodestring("%s:%s" % (username, password))[:-1]
request.add_header("Authorization", "Basic %s" % encoded)

postData = json.dumps(parameters, ensure_ascii=False).encode('utf8')
response =, postData)
print response.headers


Please install the Crypt::SSLeay module beforehand.

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;

my $req = POST '',
lab_name=> 'sanity',
test_id=> 'abcdefghijklmnop',
status=> 'failed',
steps_failed=> '1,4',
comment=> 'comment text'

$ua = LWP::UserAgent->new;
print $ua->request($req)->as_string;


Make sure all parameters are URLEncoded, for example by using the URLEncode function.

call Main()

Sub Main()
Dim strXML 'XML request string
Dim strJSON 'JSON request string
Dim strUserName 'user name to connect to the Web API service
Dim strUserPassword 'password for the user to connect to the Web API service
Dim strWebAPIURL 'Web API service URL
Dim s_test_id, s_expected_status, s_steps_failed, s_comment

' set Web API connectivity parameters
' replace email, password and serviceX with your account details
strUserName = "your_testuff_login"
strUserPassword = "your_testuff_password"
strWebAPIURL = ""

' set test scenario parameters
s_test_id = "uhpermbpkq7gh75s3x4mwuc46janat2g"
s_status = "failed"
s_steps_passed = "3"
s_steps_failed = "2,4"
s_comment = "additional info"

' prepare Web API call data
strXML = "<!--?xml version='1.0' encoding='utf-8'?-->" &amp; _

strJSON = "{" &amp; _
EmbraceInQuotes("test_id") &amp; ":" &amp; EmbraceInQuotes(s_test_id) &amp; "," &amp; _
EmbraceInQuotes("status") &amp; ":" &amp; EmbraceInQuotes(s_status) &amp; "," &amp; _
EmbraceInQuotes("steps_failed") &amp; ":" &amp; EmbraceInQuotes(s_steps_failed) &amp; "," &amp; _
EmbraceInQuotes("steps_passed") &amp; ":" &amp; EmbraceInQuotes(s_steps_passed) &amp; "," &amp; _
EmbraceInQuotes("comment") &amp; ":" &amp; EmbraceInQuotes(s_comment) &amp; _

' Try XML Request
strResult = GetDataFromURL(strWebAPIURL, strUserName, strUserPassword, "POST", "application/xml", strXML)
MsgBox "XML input, " &amp; strResult

' Try JSON Request
strResult = GetDataFromURL(strWebAPIURL, strUserName, strUserPassword, "POST", "application/json", strJSON)
MsgBox "JSON input, " &amp; strResult
End Sub

Function EmbraceInQuotes(str)
Dim res
res = Chr(34) &amp; str &amp; Chr(34)
EmbraceInQuotes = res
End Function

Function GetDataFromURL(strURL, strLogin, strPassword, strMethod, strContentType, strPostData)
Dim lngTimeout
Dim intSslErrorIgnoreFlags
Dim blnEnableRedirects
Dim blnEnableHttpsToHttpRedirects
Dim strHostOverride
Dim strResponseText
Dim objWinHttp


lngTimeout = 59000
intSslErrorIgnoreFlags = 13056 ' 13056: ignore all err, 0: accept no err
blnEnableRedirects = True
blnEnableHttpsToHttpRedirects = True
strHostOverride = ""

Set objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
objWinHttp.SetTimeouts lngTimeout, lngTimeout, lngTimeout, lngTimeout
objWinHttp.Open strMethod, strURL
If strMethod = "POST" Then
objWinHttp.setRequestHeader "Content-type", strContentType
End If
If strHostOverride &lt;&gt; "" Then
objWinHttp.SetRequestHeader "Host", strHostOverride
End If
objWinHttp.Option(4) = intSslErrorIgnoreFlags
objWinHttp.Option(6) = blnEnableRedirects
objWinHttp.Option(12) = blnEnableHttpsToHttpRedirects
objWinHttp.SetCredentials strLogin, strPassword, CREDENTIALS_FOR_SERVER
On Error Resume Next
If Err.Number = 0 Then
If objWinHttp.Status = "201" Then
GetDataFromURL = "Created: " &amp; objWinHttp.GetResponseHeader("Location")
GetDataFromURL = "Error: " &amp; objWinHttp.ResponseText
End If
GetDataFromURL = "Error " &amp; Err.Number &amp; " " &amp; Err.Source &amp; " " &amp; Err.Description
End If
On Error GoTo 0
Set objWinHttp = Nothing
End Function


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Net;
using System.Collections.Specialized;

namespace WebAPIConsoleApp
class Program
static void Main(string[] args)
// set Web API connectivity parameters
// replace email, password and serviceX with your account details
string s_username = "your_testuff_login";
string s_password = "your_testuff_password";
string s_url = "";

// set test scenario parameters
string s_test_id = "TEST_ID";
string s_status = "failed";
string s_steps_failed = "1,2";
string s_comment = "my comment";
StringBuilder s_JSON_builder = new StringBuilder();
s_JSON_builder.Append("{ ");
s_JSON_builder.Append("\"" + "test_id" + "\": " + "\"" + s_test_id + "\"");
s_JSON_builder.Append(",\"" + "status" + "\": " + "\"" + s_status + "\"");
s_JSON_builder.Append(",\"" + "steps_failed" + "\": " + "\"" + s_steps_failed + "\"");
s_JSON_builder.Append(",\"" + "comment" + "\": " + "\"" + s_comment + "\"");

string s_JSON = s_JSON_builder.ToString();

string res = "";
// System.Net.HttpWebRequest adds the header 'HTTP header "Expect: 100-Continue"' to every request by default
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(s_url);
req.Credentials = new NetworkCredential(s_username, s_password); //This line ensures the request is processed through Basic Authentication

req.ContentType = "application/json";
req.Method = "POST";

req.KeepAlive = true;
req.Timeout = 50000;
req.AllowAutoRedirect = false;
req.ContentLength = s_JSON.Length;

Stream s = req.GetRequestStream();
s.Write(System.Text.Encoding.ASCII.GetBytes(s_JSON), 0, s_JSON.Length);

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
res = "Created: " + resp.Headers["Location"];
catch (Exception e)
res = "Error: " + e.Message + e.Data;




require 'net/http'
require 'net/https'

# Replace host name with values from Testuff API settings screen
http ='', 443)
http.use_ssl = true
path = '/api/v0/run/'
req =
# Replace email and password with your account details
req.basic_auth '', 'password'
# edit the parameters below to fit with your data and format
req.add_field 'Content-Type', 'application/json'
data = '{"test_id": "ea87af9928ebc981284", "status": "failed"}'
req.body = data
resp, data = http.request(req)
# Output response code to the screen (we should get 201)
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
puts 'resource uri = ' + resp['location']


// Sample of reporting test results to Testuff API. This sample includes:
// 1. postTestuff - interface for getting test results parameters and how to send them to Testuff API
// 2. main - allows you to test it from a cmd line

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Base64;

public class postTest {

// @param args the command line arguments
public static enum STATUS {
passed, blocked, failed

// Your Testuff login details
final static String login = "TESTUFF_LOGIN";
final static String pass = "TESTUFF_PASSWORD";
final static String url = ""; // Change serviceX to the correct data center

public static void main(String[] args) throws MalformedURLException, IOException {
// TODO code application logic here
try {
postTestuff(args[0].trim(),STATUS.valueOf(args[1].trim()), args[2].trim(), args[3].trim(), args[4].trim()
, args[5].trim(), args[6].trim(), args[7].trim(), args[8].trim(), args[9].trim());
} catch (Exception e) {
System.out.println("Usage: java Posttest test_id status steps_failed steps_passed steps_blocked lab_name version run_configuration comment branch_name");
System.out.println("All arguments are required and in order, use \"\" for null values.");


public static void postTestuff(String test_id, STATUS status, String steps_failed, String steps_passed, String steps_blocked,
String lab_name, String version, String run_configuration, String comment, String branch_name) throws MalformedURLException, IOException {

String strJSON = "{"
+"\"test_id\":\""+ test_id+ "\","
+"\"status\":\""+ status.toString()+"\","
+"\"steps_failed\":\""+ steps_failed+"\","
+"\"steps_passed\":\""+ steps_passed+"\","
+"\"steps_blocked\":\""+ steps_blocked+"\","
+"\"lab_name\":\""+ lab_name+"\","
+"\"version\":\""+ version+"\","
+"\"run_configuration\":\""+ run_configuration+"\","
+"\"branch_name\":\""+ branch_name+"\","
+"\"comment\":\""+ comment

// System.out.println(strJSON);

URL u = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) u.openConnection();

String encoding = Base64.getEncoder().encodeToString((login + ":" + pass).getBytes());

conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", "" + strJSON.length());
conn.addRequestProperty("Authorization", "Basic " + encoding);
conn.addRequestProperty("Accept", "application/xml");
OutputStream os = conn.getOutputStream();

// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {

// Dump response headers, new test url in "Location"
Map<String, List> headerFields = conn.getHeaderFields();
for (String s : headerFields.keySet()) {
System.out.println(s + ":" + headerFields.get(s));


var xhr = new XMLHttpRequest();
var url = ""; // Change serviceX to the correct data center
var username = "TESTUFF_LOGIN";
var password = "PASSWORD";
var test_id = "TEST_ID_TO_RUN";"POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Authorization", "Basic " + window.btoa(username + ":" + password));
xhr.onreadystatechange = function () {
if (xhr.readyState === 4){ //if complete
if(xhr.status === 201){ //check if "OK" (201)
var json = JSON.parse(xhr.responseText);
console.log("OK: id= " +;
} else {
var json = JSON.parse(xhr.responseText);
console.log("Error: " + json.error + "(" + xhr.status + ")");
var data = JSON.stringify({
"test_id": test_id,
"status": "failed",
// Additional parameters you can use
//"steps_failed" : steps_failed,
//"steps_passed" : steps_passed,
//"steps_blocked" : steps_blocked,
//"version" : version,
//"run_configuration" : run_configuration,
//"branch_name" : branch_name,
//"comment" : comment

Time Management Help Index Languages