Skip to content

Instantly share code, notes, and snippets.

@testableapple
Last active December 1, 2024 13:01
Show Gist options
  • Save testableapple/98e3306eaa9742bf8b4dcba6cd7b05e1 to your computer and use it in GitHub Desktop.
Save testableapple/98e3306eaa9742bf8b4dcba6cd7b05e1 to your computer and use it in GitHub Desktop.
Optimizing Android Test Runs: Parsing Test Names and Implementing Parallelization
default_platform :android
skip_docs
lane :build do
gradle(tasks: ['assembleDebugAndroidTest', 'assembleDebug'])
end
lane :test do
install_test_services
install_test_parser
apk_path = "path/to/app.apk"
test_apk_path = "path/to/test.apk"
sh("adb install -r #{apk_path}")
sh("adb install -r #{test_apk_path}")
current_test_batch = batch_tests(
batch_number: options[:batch_number],
batch_count: options[:batch_count],
test_apk_path: test_apk_path
)
app_package_name = 'com.example'
test_package_name = "#{app_package_name}.test"
test_runner_package_name = 'androidx.test.runner.AndroidJUnitRunner'
test_orchestrator_package_name = 'androidx.test.orchestrator/.AndroidTestOrchestrator'
androidx_test_services_path = sh('adb shell pm path androidx.test.services').strip
result = sh(
"adb shell 'CLASSPATH=#{androidx_test_services_path}' " \
'app_process / androidx.test.services.shellexecutor.ShellMain am instrument -w '\
'-e clearPackageData true ' \
"-e targetInstrumentation #{test_package_name}/#{test_runner_package_name} " \
"-e class #{current_test_batch.join(',')} #{test_orchestrator_package_name}"
)
UI.user_error!('Tests have failed!') if result.include?('Failures')
end
lane :batch_tests do |options|
current_batch = []
if options[:batch_number] && options[:batch_count]
sh("java -jar test-parser.jar #{options[:test_apk_path]} ./")
test_names = File.read('AllTests.txt').split
current_batch = test_names.each_slice((test_names.size.to_f / options[:batch_count].to_i).ceil).to_a[options[:batch_number].to_i]
end
UI.success("Contents of the current batch: #{current_batch}")
current_batch
end
lane :install_test_services do
device_api_level = sh('adb shell getprop ro.build.version.sdk').strip.to_i
force_queryable = device_api_level >= 30 ? '--force-queryable' : ''
version = '1.5.0'
output = 'test-services.apk'
url = "https://dl.google.com/dl/android/maven2/androidx/test/services/test-services/#{version}/test-services-#{version}.apk"
sh("wget -O #{output} '#{url}' 2>/dev/null") unless File.exist?(output)
sh("adb install #{force_queryable} -r #{output}")
output = 'orchestrator.apk'
url = "https://dl.google.com/dl/android/maven2/androidx/test/services/orchestrator/#{version}/orchestrator-#{version}.apk"
sh("wget -O #{output} '#{url}' 2>/dev/null") unless File.exist?(output)
sh("adb install #{force_queryable} -r #{output}")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment