[Appium]Run tests in parallel with parallel_tests gem

Sometimes I heard how to implement test environment in parallel for Appium.

You can see which factors affect the parallel running in Appium server. http://appium.io/docs/en/advanced-concepts/parallel-tests/

In this article, I’d like to show you an example to run tests in parallel using parallel_tests gem by Ruby.

Factors

First, I’ll summarise which factors you must handle.

Android

You must utilise systemPort for appium-uiautomator2-driver. The uiautomator2 driver uses a particular port to communicate with the server running on devices. If you run with chrome driver, you also must handle chromeDriverPort.

udid is used to detect test devices.

iOS

You must utilise wdaLocalPort. The XCUITest driver communicates with WebDriverAgent with the port. If you use simulators as test devices, they use the host machine’s ports. Then, you also make sure if the the port, you’d like to use, is available on the host.

deviceName is also important to detect devices.

Read http://appium.io/docs/en/advanced-concepts/parallel-tests/ more if you’d like to know further.

With parallel_tests gem

Current iOS functional tests in ruby_core_lib are runnable in parallel. To achieve it, you should pre-create 2 simulators named iPhone 6 – 8100 and iPhone 6 – 8101.

Then, you can run them in parallel with below command.

PARALLEL=1 bundle exec parallel_test test/functional/ios -n 2

Configure parallel_test

The key to configuring the environment is capabilities. I pick parallel_tests gem here. I won’t explain about itself though.

In the gem, you can get a process number of current running one via ENV['TEST_ENV_NUMBER']. The number is "", "1", ….

Thus, if you specify wdaLocalPort and device names following the number, you can handle them programmatically.

For example, following Ruby code can define deviceName and wdaLocalPort for each running tests on each process.

def ios
  wda_local_port = get_wda_local_port
  device_name = parallel? ? "iPhone 6 - #{wda_local_port}" : 'iPhone 6'

  {
    caps: {
      platformName: :ios,
      automationName: 'XCUITest',
      app: 'test/functional/app/UICatalog.app',
      platformVersion: '10.3',
      deviceName: device_name,
      wdaLocalPort: wda_local_port
    },
    appium_lib: {
      wait: 30,
      wait_timeout: 20,
      wait_interval: 1
    }
  }
end

def get_wda_local_port
  number = ENV['TEST_ENV_NUMBER'] || ''
  core_number = number.empty? ? 0 : number.to_i - 1
  [8100, 8101][core_number] # In this case, the port available only `-n 2` though
end

If you do the similar implementation for Android, you also can run your test suites in parallel with parallel_tests gem.

Conclusion

This approach isn’t the only way to run tests in parallel. But I believe this way is a handy way to run your tests in parallel. The parallel_tests run tests on each process. Not Ruby thread. So, you can run this way with ruby_lib (not core).

Thanks,
happy testing in parallel


[Update]

Python => https://kazucocoa.wordpress.com/2018/09/01/appiumpythonrun-tests-in-parallel-with-pytest/

2 Comments

Leave a Comment

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