TestProject Forum

How to run mobile test job with Rest API

Hi, i want to use TestProject Rest API to integrate the test on my company mobile applications.

  1. First i get the available job with the request:
    curl -X GET “https://api.testproject.io/v2/projects/{PROJECT_ID}/jobs?_start=0&_limit=10” -H “accept: application/json” -H “Authorization: {AUTH_KEY}”

  2. then i want to enqueue the job execution with the request
    curl --location --request POST ‘https://api.testproject.io/v2/projects/{PROJECT_ID}/jobs/{JOB_ID}/run
    –header ‘accept: application/json’
    –header ‘Authorization: {AUTH_KEY}’
    –header ‘Content-Type: application/json’
    –data-raw ‘{
    “queue”: true

but i get an empty response from the “run” request…the response code is: 412 Precondition Failed

But if i run the jobs from the browser they works perfectly.

Any ideas? Do the https:// api.testproject .io/docs/v2/#/Jobs/Jobs_RunJobAsync works with mobile test?


Hello @luca.biasotto_testpr,
So let me see if I understood you correctly, are you trying to run the same job with two different methods? Because if you will just paste the same curl twice the jobs will be executed one after the other.

1 Like

Hi @itamar.klein,
no, i don’t try to run the same job with two different methods.
With the first URL I retrieve the list of jobs, then I want to run a job of those extracted.

  1. https://api.testproject.io/v2/projects/{PROJECT_ID}/jobs
  2. https://api.testproject.io/v2/projects/{PROJECT_ID}/jobs/{JOB_ID}/run

but the second request always get: 412 Precondition Failed

I see, I can suggest you to use this python script if you want to enqueue several jobs, and just replace the parameters to the one that are relevant for you

import requests
from threading import Timer
import time
import datetime

project_id = “PROJECT_ID”
base = “https://api.testproject.io
header = {“Authorization”: “YOUR_API_KEY”}
jobs_ids = [“JOB1_ID”, “JOB2_ID”]
jobs_names = {}
executions_id = {}
interval = 120 # Interval in seconds, set it to your liking.
job_states = [“Failed”, “Passed”, “Skipped”, “Suspended”, “Error”, “Aborted”]
summary = {}
starting_times = {}
body = {“queue”: “true”}
counter = 0

def execute_job():
for job_id in jobs_ids:
url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/run"
response = requests.post(url, headers=header, data=body)
job_name = jobs_names[job_id]
data = response.json()
if ‘id’ in data:
print(f"Starting ‘{job_name}’ …")
executions_id[job_id] = data[‘id’]
print(f"Job ‘{job_name}’ can not execute, status code is {response.status_code}.")

def reset_starting_times():
for job_name in jobs_names.values():
starting_times[job_name] = None

def get_state_with_timer(job_id, execution_id):
global counter
url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/executions/{execution_id}/state"
state = requests.get(url, headers=header)
job_name = get_job_name(job_id)
t = Timer(interval, get_state_with_timer, [job_id, execution_id])
data = state.json()
state_result = data[‘state’]
if state_result == “Executing” and starting_times[job_name] == None:
starting_times[job_name] = datetime.datetime.now()
print(f"Job: {job_name}, State: {state_result}")
# Checking interval countdown –
counter += 1
if counter == len(jobs_ids):
counter = 0
# Checking interval countdown –
if state_result in job_states:
summary[job_name] = state_result
if len(summary) == len(executions_id):

def get_jobs_names():
for job_id in jobs_ids:
jobs_names[job_id] = get_job_name(job_id)

def get_state(job_id, execution_id):
url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/executions/{execution_id}/state"
state = requests.get(url, headers=header)
return state.json()[‘state’]
print(f"Can not retrieve status, status code is {state.status_code}.")

def start_interval():
for job_id, execution_id in executions_id.items():
get_state_with_timer(job_id, execution_id)

def get_job_name(job_id):
url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/"
response = requests.get(url, headers=header)
return response.json()[‘name’]
print(f"Could not retrieve Job name, status code is {response.status_code}.")

def show_summary():
for job_name, final_state in summary.items():
print(f"Job ‘{job_name}’ has finished with the result of: {final_state}")
f"Executed on {starting_times[job_name]} {time.tzname}, with the execution time of: {datetime.datetime.now() - starting_times[job_name]}\n")

execute_job() # Start executing jobs

1 Like

ok, it’s works!!
Thanks @itamar.klein !!! :grinning:

1 Like

Happy to hear!
You’re welcome

Hey @itamar.klein,

Sorry to bring up this old request from a couple of months back, but I was wondering if you could help me.

I have followed and updated the script that you mentioned above with my info and it appears to run the jobs fine, however I get the following KeyError:

Traceback (most recent call last):
File “C:\Users\Dan\Desktop\job.py”, line 96, in
execute_job() # Start executing jobs
File “C:\Users\Dan\Desktop\job.py”, line 21, in execute_job
job_name = jobs_names[job_id]
KeyError: ‘whIfW_-X1EeEy203l94Xlg’

I was wondering if you have any ideas what I might be missing?



Hello @daniel1
Can you please share the script over at support@testproject.io

It seems you typed your information somewhere incorrectly.

Thanks, @ran.tzur! I have sent it through now.

Hi @daniel1
In the script you sent, you are missing those two method calls in the end of the script before execute_jobs:


They are there in the script, perhaps you deleted them by mistake.

It seems that way and is now working perfectly! Thanks for your patience!

From where do I run this python script? Do we have to create and new job and place this script there?
When I select New Job I have to select either Web or Mobile.