This section explains how to automate Ptero test execution → status polling → result retrieval → JUnit publishing in a Jenkins pipeline.
Script Inputs #
Key | Type | Description |
---|---|---|
userName | string | Apptest.ai Ptero website login ID. |
accessKey | string | Access Key issued in Ptero › Top-right icon › Edit Profile › Access Key (not your password). |
pid | int | Project ID to run tests against. |
testSuiteId | int | Test Suite ID (in Project › Test Suites). |
os | string | Device OS platform: “ANDROID” or “iOS” (case sensitive). |
device | string | Device key from Project › Device; use “random_device” to auto-select. |
sourceType | string | App source: “app_id” or “file”. |
appFilePath | string | App file path. Allowed extensions: .apk, .apks, .xapk, .ipa. |
appDownloadUrl | string | App download URL. Must start with http:// or https://. |
appId | string | App ID — Android: package name, iOS: bundle ID. |
Warning
Only one of app_id, app_file, app_download_url, or source_type can be provided.
If two or more are included, a Value Error occurs.To learn more, see [API Docs › Test Creation (Open API)].
Default Configuration Values (No Modification Required) #
Key | Type | Description |
---|---|---|
apiHost | string | API host address. |
runTestUrl | string | API URL for starting a test execution. |
testStatusCheckUrl | string | API URL for checking test execution status. |
testSuiteRunId | int | test_suite_run_id. Automatically assigned within the script after the test completes. |
Pipeline Script Example #
import groovy.json.*
node {
def apiHost = "https://api.apptest.ai"
def runTestUrl
def testStatusCheckUrl
def testSuiteRunId
def userName
def accessKey
def pid
def testSuiteId
def os
def device
def sourceType
def appFile
def appDownloadUrl
def appId
// Add to your Preparation Stage
stage('Preparation') {
echo "[ apptest.ai ] Current workspace : ${workspace}"
userName = 'your_user_id'
accessKey = 'your_access_key'
pid = 9876
os = 'iOS' // ANDROID | iOS
testSuiteId = 112233
device = 'random_device' // random_device or device key
// select one of the sourceType, appFile, appDownloadUrl, appId and change your form data
sourceType = "file" // file | app_id
// appDownloadUrl = "https://app.download.domain/download/path"
// appFilePath = "/home/com.android.chrome.apk"
// appFile = "@\"${appFilePath}\""
// appId = "com.android.chrome" // ANDROID: package name, iOS: bundle name
runTestUrl = "${apiHost}/openapi/v3/projects/${pid}/test-suite-runs"
echo "[ apptest.ai ] Preparation successfully."
}
// apptest.ai Test run Stage
stage('apptest.ai Test Run') {
// Call apptest.ai's Test run API.
runTestSuite = sh(returnStdout: true, script: "curl -X POST -u '${userName}:${accessKey}' -F 'source_type=${sourceType}' -F 'test_suite_id=${testSuiteId}' -F 'device=${device}' -F 'os=${os}' ${runTestUrl}").toString().trim()
runTestSuiteResponse = new JsonSlurperClassic().parseText(runTestSuite)
// Test run fail case
if (runTestSuiteResponse.result != "success") {
echo "[ apptest.ai ] Failed to run the test. ${runTestSuite}"
runTestSuite = null
runTestSuiteResponse = null
error "FAIL"
}
testSuiteRunId = runTestSuiteResponse['data']['test_suite_run_id']
runTestSuite = null
runTestSuiteResponse = null
echo "[ apptest.ai ] Test run successfully. (TestSuiteRun ID : ${testSuiteRunId})"
}
// Apptest.ai Test status check Stage
stage('apptestai Test Status Check') {
completeAll = false
testResultXml = ''
// Repeat until all tests are complete
while(!completeAll) {
sleep (time: 60, unit: "SECONDS")
testStatusCheckUrl = "${apiHost}/openapi/v3/test-suite-runs/${testSuiteRunId}"
getTestStatusCheck = sh(returnStdout: true, script: "curl -X GET -u '${userName}:${accessKey}' ${testStatusCheckUrl}").toString().trim()
getTestStatusCheckResponse = new JsonSlurperClassic().parseText(getTestStatusCheck)
if (getTestStatusCheckResponse.result != "success") {
echo "[ apptest.ai ] Failed to get test status. ${getTestStatusCheck}"
getTestStatusCheck = null
getTestStatusCheckResponse = null
error "FAIL"
}
testStatus = getTestStatusCheckResponse.data.status.toLowerCase()
echo "[ apptest.ai ] test-suite-run ${testSuiteRunId} complete result : ${testStatus}"
if (testStatus == 'complete') {
testResultUrl = "${apiHost}/openapi/v3/test-suite-runs/${testSuiteRunId}/result?data_type=xml"
getTestResult = sh(returnStdout: true, script: "curl -X GET -u '${userName}:${accessKey}' '${testResultUrl}'").toString().trim()
getTestResultResponse = new JsonSlurperClassic().parseText(getTestResult)
passCount = getTestStatusCheckResponse.data.status_detail.passed
totalCount = getTestStatusCheckResponse.data.total_test_count
testResultXml = getTestResultResponse.data.result_xml
if (passCount != totalCount) {
echo "[ apptest.ai ] status_detail ${getTestStatusCheckResponse.data.status_detail}"
echo "[ apptest.ai ] Failed to get test result data. ${testResultXml}"
getTestResult = null
getTestResultResponse = null
error "FAIL"
}
echo "[ apptest.ai ] Test completed. test-suite-run id : ${testSuiteRunId}"
getTestResult = null
getTestResultResponse = null
completeAll = true
}
getTestStatusCheck = null
getTestStatusCheckResponse = null
}
echo "[ apptest.ai ] All tests are completed."
echo "[ apptest.ai ] Test result data : ${testResultXml}"
}
// Write apptest.ai test result data to file Stage
stage('Write Apptestai Test Result') {
sh "mkdir -p tmp/"
sh "echo -n '${testResultXml}' > tmp/TESTS-Apptestai.xml"
}
// JUnit Test Stage
stage('jUnit Test') {
junit 'tmp/TESTS-*.xml'
}
}