We've received a lot of requests where users wanted an example on how to Upload their App Package, Test Binaries and queue UI Tests using our API.
We've decided to create a highly detailed one. We hope you find this useful and informative!
Steps:
1) Create a new test run using the POST Method, Once the request is sent successfully, you will receive a test run id in the Response Headers.
Please note that down, we will use it later.
Sample Request
https://api.appcenter.ms/v0.1/apps/MSKASANI/DroidAppSampleXamarin/test_runs
2) Create file hashes for each file you want to upload to AppCenter Test.
You can get the file hashes by running the command sha256sum. This utility is available in Mac/Linux machines by default. (For Windows, consider installing Git Bash and use it)
Example:
ankasani@AK--PC MINGW64 ~/source/repos/AppXamarin/sampleapp-xamarin-master/UITest/bin/Debug/testdlls (master)
$ sha256sum nunit.framework.dll
39a9d50b6fecd1dec6f12dbf26023a6544e0ba018cfdc01b5625db6ae1f2f1f9 *nunit.framework.dll
$ sha256sum Xamarin.UITest.dll
453d6e03e8caf1aa541ce1f5c8592e35ae24a0669d0585ecbfa0e66edb1120e3 *Xamarin.UITest.dll
$ sha256sum UITest.dll
0ee8ef93661bfac8d446d99a6e5c7f5fc966883f5214e2b523fd546871646934 *UITest.dll
$ sha256sum com.mobilecenter.sampleappxamarin.apk
13b981e208ce45a7975b7a9b3d09d6108fdd12da490cb3ac54e1a82cf6b74a90 *com.mobilecenter.sampleappxamarin.apk
3) Create a store for the files using POST and hashes value calculated from the previous step.
Sample Request: https://api.appcenter.ms/v0.1/apps/MSKASANI/DroidAppSampleXamarin/test_runs/fb0cc373-aa4a-455f-b083-4fc1afa87f2e/hashes/batch
*file_type: app-file for apk\ipa and test-file for test assemblies/test related files.
*checksum: hash values from step 2
*relative_path: you can just define File Name with Extension, no need to specify the complete path.
JSON Body looks like,
[
{
"file_type": "app-file",
"checksum": "13b981e208ce45a7975b7a9b3d09d6108fdd12da490cb3ac54e1a82cf6b74a90",
"relative_path": "com.mobilecenter.sampleappxamarin.apk"
},
{
"file_type": "test-file",
"checksum": "39a9d50b6fecd1dec6f12dbf26023a6544e0ba018cfdc01b5625db6ae1f2f1f9",
"relative_path": "nunit.framework.dll"
},
{
"file_type": "test-file",
"checksum": "453d6e03e8caf1aa541ce1f5c8592e35ae24a0669d0585ecbfa0e66edb1120e3",
"relative_path": "Xamarin.UITest.dll"
},
{
"file_type": "test-file",
"checksum": "0ee8ef93661bfac8d446d99a6e5c7f5fc966883f5214e2b523fd546871646934 ",
"relative_path": "UITest.dll"
}
]
The corresponding response looks like,
[
{
"fileType": "app-file",
"checksum": "13b981e208ce45a7975b7a9b3d09d6108fdd12da490cb3ac54e1a82cf6b74a90",
"relativePath": "com.mobilecenter.sampleappxamarin.apk",
"uploadStatus":{
"statusCode": 412,
"location": "https://testcloud.xamarin.com/v0.1/direct_uploads?token=ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SjBaWE4w%0AWDNKMWJsOXBaQ0k2SWpjNU5EVmpNbUZtTFRFeFpXTXROR1ptWVMwNU1XSTBM%0AVFExTUdJd09EVTNNbU5sT1NJc0ltVjRjQ0k2TVRVek16Z3dOVFEzTUgwLlJO%0AaTQ3VTNPYTB5YWswMVRVdTV6Q0dfWFhwV25QUWJDdkJaNmVCRWRmOENuQ19U%0AbmdpRGI4MU0yYk1lTlZNY1VCVmRWLXlkRjh4dElLaU1yNFdtQUFhOFdoay02%0AOVVjb29rYkNTYUU2eUlzamowZlZPZVJhR2lFdGpvLWJHTFJLcXNGY0ZTeUdR%0ARTQzQUZ1TFlyTWlCRnowMElpd3ZudjYzZk9wQnRGaXhNa2lNNjhUTWxxVnNa%0AOFl3TFlTeU5KSWFvYVJCM0ZZTUkwajNYOWdVb3VJclVjNnpqcGNkYkxCcWJ0%0AVUpyN0ZFaTdJeWY4UG9rMXZxTzRlUExiaEszTmItTmd0Q2JuckZzS2x6Z3Za%0AaktUWHZZb2oya0FGWXZHaVZ4LVhfNVhUcGdiVnE1Z2dxVEtIdjRaUGFuaGR4%0AdnFvZ2YxRVYwWUJYaG40YUJLM3BnUVBodw%3D%3D%0A"
}
},
{
"fileType": "test-file",
"checksum": "39a9d50b6fecd1dec6f12dbf26023a6544e0ba018cfdc01b5625db6ae1f2f1f9",
"relativePath": "nunit.framework.dll",
"uploadStatus":{
"statusCode": 412,
"location": "https://testcloud.xamarin.com/v0.1/direct_uploads?token=ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SjBaWE4w%0AWDNKMWJsOXBaQ0k2SWpjNU5EVmpNbUZtTFRFeFpXTXROR1ptWVMwNU1XSTBM%0AVFExTUdJd09EVTNNbU5sT1NJc0ltVjRjQ0k2TVRVek16Z3dOVFEzTUgwLlJO%0AaTQ3VTNPYTB5YWswMVRVdTV6Q0dfWFhwV25QUWJDdkJaNmVCRWRmOENuQ19U%0AbmdpRGI4MU0yYk1lTlZNY1VCVmRWLXlkRjh4dElLaU1yNFdtQUFhOFdoay02%0AOVVjb29rYkNTYUU2eUlzamowZlZPZVJhR2lFdGpvLWJHTFJLcXNGY0ZTeUdR%0ARTQzQUZ1TFlyTWlCRnowMElpd3ZudjYzZk9wQnRGaXhNa2lNNjhUTWxxVnNa%0AOFl3TFlTeU5KSWFvYVJCM0ZZTUkwajNYOWdVb3VJclVjNnpqcGNkYkxCcWJ0%0AVUpyN0ZFaTdJeWY4UG9rMXZxTzRlUExiaEszTmItTmd0Q2JuckZzS2x6Z3Za%0AaktUWHZZb2oya0FGWXZHaVZ4LVhfNVhUcGdiVnE1Z2dxVEtIdjRaUGFuaGR4%0AdnFvZ2YxRVYwWUJYaG40YUJLM3BnUVBodw%3D%3D%0A"
}
},
{
"fileType": "test-file",
"checksum": "453d6e03e8caf1aa541ce1f5c8592e35ae24a0669d0585ecbfa0e66edb1120e3",
"relativePath": "Xamarin.UITest.dll",
"uploadStatus":{
"statusCode": 412,
"location": "https://testcloud.xamarin.com/v0.1/direct_uploads?token=ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SjBaWE4w%0AWDNKMWJsOXBaQ0k2SWpjNU5EVmpNbUZtTFRFeFpXTXROR1ptWVMwNU1XSTBM%0AVFExTUdJd09EVTNNbU5sT1NJc0ltVjRjQ0k2TVRVek16Z3dOVFEzTUgwLlJO%0AaTQ3VTNPYTB5YWswMVRVdTV6Q0dfWFhwV25QUWJDdkJaNmVCRWRmOENuQ19U%0AbmdpRGI4MU0yYk1lTlZNY1VCVmRWLXlkRjh4dElLaU1yNFdtQUFhOFdoay02%0AOVVjb29rYkNTYUU2eUlzamowZlZPZVJhR2lFdGpvLWJHTFJLcXNGY0ZTeUdR%0ARTQzQUZ1TFlyTWlCRnowMElpd3ZudjYzZk9wQnRGaXhNa2lNNjhUTWxxVnNa%0AOFl3TFlTeU5KSWFvYVJCM0ZZTUkwajNYOWdVb3VJclVjNnpqcGNkYkxCcWJ0%0AVUpyN0ZFaTdJeWY4UG9rMXZxTzRlUExiaEszTmItTmd0Q2JuckZzS2x6Z3Za%0AaktUWHZZb2oya0FGWXZHaVZ4LVhfNVhUcGdiVnE1Z2dxVEtIdjRaUGFuaGR4%0AdnFvZ2YxRVYwWUJYaG40YUJLM3BnUVBodw%3D%3D%0A"
}
},
{
"fileType": "test-file",
"checksum": "0ee8ef93661bfac8d446d99a6e5c7f5fc966883f5214e2b523fd546871646934 ",
"relativePath": "UITest.dll",
"uploadStatus":{
"statusCode": 412,
"location": "https://testcloud.xamarin.com/v0.1/direct_uploads?token=ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SjBaWE4w%0AWDNKMWJsOXBaQ0k2SWpjNU5EVmpNbUZtTFRFeFpXTXROR1ptWVMwNU1XSTBM%0AVFExTUdJd09EVTNNbU5sT1NJc0ltVjRjQ0k2TVRVek16Z3dOVFEzTUgwLlJO%0AaTQ3VTNPYTB5YWswMVRVdTV6Q0dfWFhwV25QUWJDdkJaNmVCRWRmOENuQ19U%0AbmdpRGI4MU0yYk1lTlZNY1VCVmRWLXlkRjh4dElLaU1yNFdtQUFhOFdoay02%0AOVVjb29rYkNTYUU2eUlzamowZlZPZVJhR2lFdGpvLWJHTFJLcXNGY0ZTeUdR%0ARTQzQUZ1TFlyTWlCRnowMElpd3ZudjYzZk9wQnRGaXhNa2lNNjhUTWxxVnNa%0AOFl3TFlTeU5KSWFvYVJCM0ZZTUkwajNYOWdVb3VJclVjNnpqcGNkYkxCcWJ0%0AVUpyN0ZFaTdJeWY4UG9rMXZxTzRlUExiaEszTmItTmd0Q2JuckZzS2x6Z3Za%0AaktUWHZZb2oya0FGWXZHaVZ4LVhfNVhUcGdiVnE1Z2dxVEtIdjRaUGFuaGR4%0AdnFvZ2YxRVYwWUJYaG40YUJLM3BnUVBodw%3D%3D%0A"
}
}
]
4) Now we need to upload the actual files.
From the previous response body, identify the "location" : that contains the URL of the files you are uploading.
In the Headers, you need to pass Content-Type:multipart/form-data
In the Body, you need to use the type Body_Form with the values below,
*relative_path and file_type: from the previous Response Body
*file : Path to the actual file
You're on the right track if you get '201 Created' as the response like below.
(We're halfway there)
5) Repeat the previous step for the rest of the files you want to upload.
6) We are ready to Execute the test now. For this, we need a device_slug.
Note: You should first create "Device Sets" in your Org or you can use the REST API to create a device sets.
Then, you can use the GET Method to get the list of devices sets.
Sample Request: https://api.appcenter.ms/v0.1/apps/MSKASANI/DroidAppSampleXamarin/owner/device_sets
Corresponding Response Body:
{
"id": "00917fb6-f30f-4d36-bd53-f900a94efe9f",
"name": "UI Test",
"slug": "ui-test",
"osVersionCount": 1,
"manufacturerCount": 1,
"owner":{
"type": "organization",
"id": "5dd75115-3832-4f10-9cfe-5ac8cc8a51a5",
"displayName": "MSKASANI",
"name": "MSKASANI"
},
"deviceConfigurations":[
{
"id": "717cfc38-4817-41fc-8a8e-06beef4f73b2",
"image":{
"thumb": "https://testcloud-prod-system-files.s3-eu-west-1.amazonaws.com/system_files/0dee6ee7-6839-4e4e-ad0b-333e3952f75c?response-cache-control=max-age%3D157788000&AWSAccessKeyId=AKIAI4UZT4FCOF2OTJYQ&Signature=r9EEm/x0YAA4NhRJ%2BhVSQwGtBbI%3D&Expires=1691079085"
},
"os": "8.1.0",
"osName": "Android 8.1.0",
"model":{"name": "Google Pixel 2 XL", "manufacturer": "Google", "releaseDate": "October 2017", "formFactor": "phone"…}
}
]
7) We're now ready to use the Test start API to trigger the test!
The Request body below is created for Xamarin.UITest Framework. If you're using other frameworks, don't worry, refer to the end of the doc for more details!
Sample JSON Request Body:
{
"test_framework":"ui_test",
"device_selection":"MSKASANI/ui-test",
"locale":"en_US",
"test_series":"apimaster",
"test_parameters":{
"tests":{
"method":{
"UITest.dll":[
"UITest.Tests(Android).AppLaunches",
"UITest.Tests(iOS).AppLaunches"
]
},
"fixture":{
"UITest.dll":[
"UITest.Tests(Android)",
"UITest.Tests(iOS)"
]
}
}
}
}
Corresponding Response Body:
{
"accepted_devices":[
"Google Pixel 2 XL (8.1.0)"
],
"rejected_devices":[]
}
If you now go to the Test page of your App, you will see...
Congratulations! :)
PS : For other Test Frameworks, if you want to know how the JSON looks like (for instance, Appium test)
Run the Test command manually with --debug switch
appcenter test run appium --app "MSKASANI/Appium" --devices "MSKASANI/my" --app-path C:\VSAC\AllTest\AppCenter-Test-Samples-master\Appium\Android\swiftnote.apk--test-series "master" --locale "en_US" --build-dir C:\VSAC\AllTest\AppCenter-Test-Samples-master\Appium\Android\Mavenex\target\upload –debug
Once the test is complete, you can check out the Command output to see how the Request Body looks like,