[Appium][Ruby]Run tests in parallel

[Update]
Refer [Appium]Run tests in parallel with parallel_tests gem if you’re finding a way to run tests in parallel with existing gem.


When we run Appium in parallel on one Machine and one Appium server with Ruby, we have two ways to implement it. (For Android, we don’t need to configure this kind of environment. We must cover this for iOS because of the platform’s limitations.)

One is thread programming and another is process-fork programming. I’ll put examples to run tests with each method in the below.

  • rake run_parallel_t
    • Run tests with thread programming. In this case, each thread shares their data on the memory, classes. It means once our scenario depends on class method, we can’t keep clean test environment.
  • rake run_parallel_p
    • Run tests with process-fork programming. In this case, each process is isolated each other. So, we can keep the hermetic environment in each process.


# test file
require_relative '../../lib/appium_lib'
def des_server_caps
{
debug: true,
server_url: "#{ENV['appium_server'] ||= 'http://127.0.0.1:4723'}/wd/hub",
wait: 25,
wait_timeout: 20,
wait_interval: 0.3
}
end
class TestParallelRunThread
def initialize(capability)
@capability = capability
end
def setup
@appium = Appium::Driver.new({ caps: @capability, appium_lib: des_server_caps }, false)
@appium.start_driver
end
def teardown
@appium.quit_driver
puts "finish: #{@capability}"
end
def test_run
setup
# tap alert
@appium.find_element(:name, 'Alerts').click
@appium.wait_true do
@appium.find_element(:name, 'Show OK-Cancel').click
@appium.find_element(:name, 'UIActionSheet <title>').displayed?
end
@appium.alert action: 'accept'
@appium.back
sleep 5
# TouchAction
text_elem = @appium.text(@appium.app_strings['ButtonsExplain'])
@appium.tap x: 0, y: 0, element: text_elem
@appium.back
teardown
end
end
class TestParallelRunProcess
def initialize(capability)
@capability = capability
end
def setup
@appium = Appium::Driver.new({ caps: @capability, appium_lib: des_server_caps }, false)
Appium.promote_appium_methods TestParallelRunProcess, @appium
start_driver
end
def teardown
quit_driver
puts "finish: #{@capability}"
end
def test_run
setup
# tap alert
find_element(:name, 'Alerts').click
wait_true do
find_element(:name, 'Show OK-Cancel').click
find_element(:name, 'UIActionSheet <title>').displayed?
end
alert action: 'accept'
back
sleep 5
# TouchAction
text_elem = text(app_strings['ButtonsExplain'])
tap x: 0, y: 0, element: text_elem
back
teardown
end
end
# Rakefile
class Device
def self.one
{
automationName: 'xcuitest',
platformName: 'ios',
platformVersion: '11.0',
deviceName: 'iPhone 6',
app: "#{Dir.pwd}/../test_apps/UICatalog.app",
wdaLocalPort: 8100,
isCommandsQueueEnabled: false
}
end
def self.two
{
automationName: 'xcuitest',
platformName: 'ios',
platformVersion: '11.0',
deviceName: 'iPhone 6s',
app: "#{Dir.pwd}/../test_apps/UICatalog.app",
wdaLocalPort: 8200,
isCommandsQueueEnabled: false
}
end
end
desc 'Run tests with parallel thread'
task :run_parallel_t do
require 'thread'
require_relative 'parallel/test'
threads = []
[Device.one, Device.two].each do |capability|
threads << Thread.new do
TestParallelRunThread.new(capability).test_run
end
end
threads.each(&:join)
end
desc 'Run tests with parallel processes'
task :run_parallel_p do
require_relative 'parallel/test'
[Device.one, Device.two].each do |capability|
fork do
TestParallelRunProcess.new(capability).test_run
end
end
Process.waitall
end

I think process fork model is good for this time since we don’t need to depend on thread programming when we’d like to run tests in parallel.

2 Comments

  1. Unknown's avatar Anonymous says:

    How do you execute parallel tests with Android?

    1. KazuCocoa's avatar KazuCocoa says:

      As addressed in https://kazucocoa.wordpress.com/2018/08/10/appiumrun-tests-in-parallel-with-parallel_tests-gem/, you can run tests in parallel handling systemPort instead of wdaLocalPort in iOS case.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.