Bitrise is one of the best solutions for mobile application development. It gives us many mobile app-related steps to create CI/CD (continuous integration / continuous deployment) pipelines (or workflows as in the Bitrise). Around the mobile application development ecosystem, we have many cloud solutions to make quick and reliable development processes. Browserstack is also one of them, it is widely used in web development and testing but also it also has nice features like 'App Live' and 'App Automate' for mobile app testing.
In this post, I want to share how we can integrate Browserstack to Bitrise to run XCUITest.
Run XCUITest on Browserstack via Bitrise
If you want to run XCUITest on a real device then you must build the for generic iOS devices. Building for generic iOS devices requires provisioning so you should ensure that you added the provisioning step to the workflow. Also to be able to run an iOS build on a real device, the device should be registered to the Apple console. This is required by Apple security concerns. However, device farms Firebase Test Lab and Browserstack handle this issue, so no need to be concerned about the limit of registered devices.
In this example, we are using a script to handle all the staff for us. So it does the followings:
- Create a .ipa file from the derived artifact
- ZIP the test file - UITests-Runner.app to UITests-Runner.zip
- Upload the app - .ipa created at Step-1
- Upload the test file - .zip file created at Step-2
- Trigger test with uploaded files and desired devices and test options
- Wait until tests to finish and evaluate the result
For the script, all the required files are created by the step "Xcode Build for testing for iOS" so this step be set up correctly. We are using file under "$BITRISE_TEST_DIR_PATH"
See the script to run XCUITest on Browserstack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Author: Mesut Güneş | |
set -e | |
cd $BITRISE_TEST_DIR_PATH | |
#-1 creating IPA | |
rm -rf Payload | |
mkdir Payload | |
cp -rf projectX.app Payload/ | |
zip -r Payload.zip Payload/ | |
mv Payload.zip projectX.ipa | |
#-2 zip tests | |
zip --symlinks -r projectXUITests-Runner.zip projectXUITests-Runner.app | |
#-3 upload app | |
upload_app=$(curl -u "$BROWSERSTACK_USER:$BROWSERSTACK_USER_TOKEN" -X POST "https://api-cloud.browserstack.com/app-automate/upload" -F "file=@projectX.ipa") | |
app_url=$(echo $upload_app | jq -r .app_url) | |
envman add --key BROWSERSTACK_APP_URL --value $app_url | |
echo -e "\napp_url: $app_url\n" | |
#-4 upload test | |
upload_test=$(curl -u "$BROWSERSTACK_USER:$BROWSERSTACK_USER_TOKEN" -X POST "https://api-cloud.browserstack.com/app-automate/xcuitest/test-suite" -F "file=@projectXUITests-Runner.zip") | |
test_url=$(echo $upload_test | jq -r .test_url) | |
envman add --key BROWSERSTACK_TEST_URL --value $test_url | |
echo -e "\ntest_url: $test_url\n" | |
#-5 upload test | |
# we can filter the test for different purposes | |
# test_name="\"ProductCampaignScreenTests\", \"LoginScreenTests\"" ==> \"only-testing\": [$test_name] | |
test_name="" | |
trigger_tests=$(curl -u "$BROWSERSTACK_USER:$BROWSERSTACK_USER_TOKEN" \ | |
-X POST "https://api-cloud.browserstack.com/app-automate/xcuitest/build" \ | |
-d "{\"devices\": [\"iPhone 11 Pro-13\"], \"app\": \"$app_url\", \"deviceLogs\" : \"true\", \"testSuite\": \"$test_url\", \"only-testing\": [$test_name]}" \ | |
-H "Content-Type: application/json") | |
build_id=$(echo $trigger_tests | jq -r .build_id) | |
envman add --key BROWSERSTACK_TEST_BUILD_ID --value $build_id | |
echo -e "\ntrigger_tests: $trigger_tests\n" | |
echo -e "\nbuild_id: $build_id\n" | |
#-6 wait tests until 30mins | |
end=$((SECONDS+1800)) | |
exit_code=1 | |
status="not run" | |
while true | |
do | |
if [ $SECONDS -gt $end ]; then | |
echo " - Timeout for Test RUN!" | |
break | |
fi | |
status=$( curl -u "$BROWSERSTACK_USER:$BROWSERSTACK_USER_TOKEN" -X GET "https://api-cloud.browserstack.com/app-automate/xcuitest/v2/builds/$build_id" | jq -r .status ) | |
if [ "$status" == "running" ]; then | |
echo -e " - Still running, waiting . . ." | |
sleep 5; | |
elif [ "$status" == "passed" ]; then | |
exit_code=0 | |
break | |
else | |
break | |
fi | |
done; | |
test_result_url="https://app-automate.browserstack.com/dashboard/v2/builds/$build_id" | |
envman add --key BROWSERSTACK_TEST_RESULT_URL --value $test_result_url | |
echo "status: $status" | |
echo -e "\nCheck the test result from Browserstack: \n - $test_result_url" | |
exit $exit_code |