Welcome to Emcee project, an ultimate solution for running iOS tests in parallel locally and across many Macs.
Emcee allows you to run UI tests on many physical machines, distributing the work and getting the results of the test run faster. Shared queue manages the order of test execution. Emcee workers execute tests and maintain lifecycle of their simulators automatically. Emcee can generate the Junit and trace reports to make you see how the test run behaved on different machines.
Single test queue to run tests from multiple parallel pull requests
Prioritized jobs and job groups for different kinds of test runs
Load balancing of worker machines to achieve optimal parallelization performance
On-the-go maintenance of the workers
Integration into existing test management systems via plugins
Easy to use command line interface
Rich test discovery mechanism
Swift Package for using and extending Emcee the way you want
Getting started
In this guide will demonstrate how to use Emcee. We will use two MacOS machines to run unit and UI tests from a sample project. You can also use a single machine to try out Emcee to see if it works for your project. In this case, a single machine will act as a queue and a worker simultaneously. Alternatively, you can scale this guide to as many machines as you have.
If you encounter any issues while proceeding through the guide, please open an issue or reach out via https://t.me/emcee_ios.
You will need to grant SSH access to your machines.
Expand to see how to set up your machines.
We will be using two machines: ios-build-machine77 and ios-build-machine78.
ios-build-machine77 will be a worker and a queue - it will provide workers with tests to execute and execute some of those tests.
ios-build-machine78 will be a worker - it will only execute tests.
Both machines are set up with a standard non-administrator user emcee and a qwerty password.
Install Xcode and sudo xcode-select --switch /Applications/Xcode.app on all of your machines.
We will use Xcode 13.0 (13A233) and the iOS 15.0 simulator runtime bundled with this Xcode. If you want to use a specific version of simulator runtime, proceed to Xcode -> Preferences... -> Components -> Simulators and install the runtime on all the worker machines, where you want the tests to execute with the specific runtime version.
Emcee uses ssh to deploy itself to the machines specified as queue and workers. Enable SSH in your System Preferences -> Sharing -> Remote Login. To open this pane execute:
$ open "x-apple.systempreferences:com.apple.preferences.sharing?Services_RemoteLogin"
Now make sure that machines are accessible by ssh. For example:
ssh emcee@ios-build-machine77
If your machines are not accessible by DNS, use their IP addresses instead. You can check IP address in System Preferences -> Sharing. Please note IP addresses may change over time. To open this pane execute:
$ open "x-apple.systempreferences:com.apple.preferences.sharing"
Building the sample project
In this step, we will build a sample project that features different types of tests. Xcode and xcodebuild will produce build artifacts in derived data.
Expand to see how to build the sample project for testing purposes.
You can run this step from either machine. Clone the sample project:
cd ~
git clone https://github.com/avito-tech/Emcee.git
cd Emcee/Samples/EmceeSample
--queue - is a URL of a machine that will serve workers with tests
--worker - is a URL of a machine that will execute tests that it queries from the queue
--device and --runtime - are options that specify which simulators will run the tests
--test-bundle - is a path to the xctest bundle
--junit - is a path to the JUnit xml that will contain the result of the test run
You can find more about all options accepted by runTests and how to specify them using Emcee runTests -h.
After the test finishes, Emcee will create a tests_without_host_junit.xml file. The JUnit report contains four testcase entries matching the four test methods from the EmceeSampleTestsWithoutHost.xctest test bundle.
runTests command allows you to get Emcee up and running quickly; however, it doesn’t allow for a lot of configuration. On the other hand, runTestsOnRemoteQueue command allows for fine-grained control of how your tests execute. To get started with runTestsOnRemoteQueue check out the Queue Server Configuration and Test Arg File wiki pages.
Emcee uses Swift Package Manager for building, testing and exposing the Swift packages.
To start exploring code open Package.swift in Xcode 13 or execute make open to generate and open Xcode project.
Contributing
We are happy to accept your pull requests. If something does not work for you, please let us know by submitting an issue. Read the docs and suggest improvements to them as well!
General commands that help you with a development workflow:
To open a package in Xcode: make open
To generate Package.swift: make package
To build the binary into .build/debug/Emcee: make build
To run unit tests: make test
Package.swift file is generated automatically. You must update it before submitting a pull request (run make package). CI checks will fail if you forget to do so.
Welcome to Emcee project, an ultimate solution for running iOS tests in parallel locally and across many Macs.
Emcee allows you to run UI tests on many physical machines, distributing the work and getting the results of the test run faster. Shared queue manages the order of test execution. Emcee workers execute tests and maintain lifecycle of their simulators automatically. Emcee can generate the Junit and trace reports to make you see how the test run behaved on different machines.
Features
Rich test plans using simple JSON file format
Automatic simulator lifecycle management
Per-test timeouts, simulator settings, environment variables
Single test queue to run tests from multiple parallel pull requests
Prioritized jobs and job groups for different kinds of test runs
Load balancing of worker machines to achieve optimal parallelization performance
On-the-go maintenance of the workers
Integration into existing test management systems via plugins
Easy to use command line interface
Rich test discovery mechanism
Swift Package for using and extending Emcee the way you want
Getting started
In this guide will demonstrate how to use Emcee. We will use two MacOS machines to run unit and UI tests from a sample project. You can also use a single machine to try out Emcee to see if it works for your project. In this case, a single machine will act as a
queue
and aworker
simultaneously. Alternatively, you can scale this guide to as many machines as you have.If you encounter any issues while proceeding through the guide, please open an issue or reach out via https://t.me/emcee_ios.
Table of contents
Setting up machines
You will need to grant SSH access to your machines.
Expand to see how to set up your machines.
We will be using two machines:
ios-build-machine77
andios-build-machine78
.ios-build-machine77
will be a worker and a queue - it will provide workers with tests to execute and execute some of those tests.ios-build-machine78
will be a worker - it will only execute tests.Both machines are set up with a standard non-administrator user
emcee
and aqwerty
password.Install Xcode and
sudo xcode-select --switch /Applications/Xcode.app
on all of your machines.We will use
Xcode 13.0 (13A233)
and theiOS 15.0
simulator runtime bundled with this Xcode. If you want to use a specific version of simulator runtime, proceed toXcode -> Preferences... -> Components -> Simulators
and install the runtime on all the worker machines, where you want the tests to execute with the specific runtime version.Emcee uses ssh to deploy itself to the machines specified as
queue
andworkers
. Enable SSH in yourSystem Preferences -> Sharing -> Remote Login
. To open this pane execute:Now make sure that machines are accessible by ssh. For example:
If your machines are not accessible by DNS, use their IP addresses instead. You can check IP address in
System Preferences -> Sharing
. Please note IP addresses may change over time. To open this pane execute:Building the sample project
In this step, we will build a sample project that features different types of tests. Xcode and
xcodebuild
will produce build artifacts in derived data.Expand to see how to build the sample project for testing purposes.
You can run this step from either machine. Clone the sample project:
To build the project, create a simulator:
Now run xcodebuild:
Xcodebuild will place the build products in:
Running tests using Emcee
Now that the machines are ready, and the project is built, download Emcee on the same machine where you built the project by running:
If you download Emcee using a browser you will need to clear attributes and set the executable bit:
With Emcee installed it is finally time to run the tests. The sample project includes 3 test types:
Tests without a host application
Let’s first run tests that don’t require a host application. We will be using the
runTests
command:Here is what these options stand for:
--queue
- is a URL of a machine that will serve workers with tests--worker
- is a URL of a machine that will execute tests that it queries from thequeue
--device
and--runtime
- are options that specify which simulators will run the tests--test-bundle
- is a path to the xctest bundle--junit
- is a path to the JUnit xml that will contain the result of the test runYou can find more about all options accepted by
runTests
and how to specify them usingEmcee runTests -h
.After the test finishes, Emcee will create a
tests_without_host_junit.xml
file. The JUnit report contains fourtestcase
entries matching the four test methods from theEmceeSampleTestsWithoutHost.xctest
test bundle.For a more sophisticated test reporting mechanism such as Allure, check out the Plugins documentation.
Tests with a host application
Now let’s try running tests that require a host application. Host application path is specified using the
--app
option. For example:To get a visual confirmation that Emcee is running the tests, you can open the Simulator app on the worker machines:
XCUI tests
Finally, we will run XCUI tests by adding a
--runner
option and changing the--test-bundle
option to the XCUI test bundle:This is how the test run will look:
Advanced Emcee configuration
Complete documentation is available in our Wiki.
runTests
command allows you to get Emcee up and running quickly; however, it doesn’t allow for a lot of configuration. On the other hand,runTestsOnRemoteQueue
command allows for fine-grained control of how your tests execute. To get started withrunTestsOnRemoteQueue
check out the Queue Server Configuration and Test Arg File wiki pages.Publications
Getting Around the Code
Emcee uses Swift Package Manager for building, testing and exposing the Swift packages.
To start exploring code open
Package.swift
in Xcode 13 or executemake open
to generate and open Xcode project.Contributing
We are happy to accept your pull requests. If something does not work for you, please let us know by submitting an issue. Read the docs and suggest improvements to them as well!
General commands that help you with a development workflow:
make open
Package.swift
:make package
.build/debug/Emcee
:make build
make test
Package.swift
file is generated automatically. You must update it before submitting a pull request (runmake package
). CI checks will fail if you forget to do so.