• Stars
    star
    331
  • Rank 127,323 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 6 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Emcee is a tool that runs Android and iOS tests in parallel using multiple simulators and emulators across many servers

Emcee Banner

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 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.

Table of contents

  1. Setting up machines
  2. Building the sample project
  3. Running tests using Emcee
    1. Tests without a host application
    2. Tests with a host application
    3. XCUI tests
  4. Advanced Emcee configuration

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 and ios-build-machine78.

machines

  • 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"

Remote Login SSH Settings

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

To build the project, create a simulator:

xcrun simctl create '15.0' 'iPhone X' 'iOS15.0'

Now run xcodebuild:

xcodebuild build-for-testing \
	-project EmceeSample.xcodeproj \
	-destination "platform=iOS Simulator,name=15.0,OS=15.0" \
	-scheme AllTests \
	-derivedDataPath derivedData

Xcodebuild will place the build products in:

derivedData/Build/Products/Debug-iphonesimulator

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:

curl -L https://github.com/avito-tech/Emcee/releases/download/16.0.0/Emcee -o Emcee && chmod +x Emcee

If you download Emcee using a browser you will need to clear attributes and set the executable bit:

xattr -c Emcee && chmod +x Emcee

With Emcee installed it is finally time to run the tests. The sample project includes 3 test types:

  • Tests that don't require a host application
  • Tests that require a host application
  • XCUI tests

Tests without a host application

Let's first run tests that don't require a host application. We will be using the runTests command:

./Emcee runTests \
	--queue "ssh://emcee:qwerty@ios-build-machine77" \
	--worker "ssh://emcee:qwerty@ios-build-machine77" \
	--worker "ssh://emcee:qwerty@ios-build-machine78" \
	--device "iPhone X" \
	--runtime "15.0" \
	--test-bundle derivedData/Build/Products/Debug-iphonesimulator/EmceeSampleTestsWithoutHost.xctest \
	--junit tests_without_host_junit.xml

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 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.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="xctest" tests="4" failures="1">
    <testsuite name="EmceeSampleTestsWithoutHost" tests="4" failures="1">
        <testcase classname="EmceeSampleTestsWithoutHost" name="test_0___from_tests_without_host___that_always_succeeds" timestamp="2021-12-29T01:15:16+03:00" time="0.012196063995361328"></testcase>
        <testcase classname="EmceeSampleTestsWithoutHost" name="test_1___from_tests_without_host___that_always_succeeds" timestamp="2021-12-29T01:15:27+03:00" time="0.02156198024749756"></testcase>
        <testcase classname="EmceeSampleTestsWithoutHost" name="test_2___from_tests_without_host___that_always_succeeds" timestamp="2021-12-29T01:15:36+03:00" time="0.021990060806274414"></testcase>
        <testcase classname="EmceeSampleTestsWithoutHost" name="test___from_tests_without_host___that_always_fails" timestamp="2021-12-29T01:15:31+03:00" time="0.1255110502243042">
            <failure message="failed - Failure from tests without host">/Users/emcee/Emcee/SampleProject/EmceeSampleTestsWithoutHost/EmceeSampleTestsWithoutHost.swift:17</failure>
            <failure message="failed - Failure from tests without host">/Users/emcee/Emcee/SampleProject/EmceeSampleTestsWithoutHost/EmceeSampleTestsWithoutHost.swift:17</failure>
        </testcase>
    </testsuite>
</testsuites>

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:

./Emcee runTests \
    --queue "ssh://emcee:qwerty@ios-build-machine77" \
    --worker "ssh://emcee:qwerty@ios-build-machine77" \
    --worker "ssh://emcee:qwerty@ios-build-machine78" \
    --device "iPhone X" \
    --runtime "15.0" \
    --app derivedData/Build/Products/Debug-iphonesimulator/EmceeSample.app \
    --test-bundle derivedData/Build/Products/Debug-iphonesimulator/EmceeSample.app/PlugIns/EmceeSampleHostedTests.xctest \
    --junit tests_with_host_junit.xml

To get a visual confirmation that Emcee is running the tests, you can open the Simulator app on the worker machines:

open "$(xcode-select -p)"/Applications/Simulator.app

XCUI tests

Finally, we will run XCUI tests by adding a --runner option and changing the --test-bundle option to the XCUI test bundle:

./Emcee runTests \
    --queue "ssh://emcee:qwerty@ios-build-machine77" \
    --worker "ssh://emcee:qwerty@ios-build-machine77" \
    --worker "ssh://emcee:qwerty@ios-build-machine78" \
    --device "iPhone X" \
    --runtime "15.0" \
    --runner derivedData/Build/Products/Debug-iphonesimulator/EmceeSampleUITests-Runner.app \
    --app derivedData/Build/Products/Debug-iphonesimulator/EmceeSample.app \
    --test-bundle derivedData/Build/Products/Debug-iphonesimulator/EmceeSampleUITests-Runner.app/PlugIns/EmceeSampleUITests.xctest \
    --junit ui_tests_junit.xml

This is how the test run will look:

running_tests

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 with runTestsOnRemoteQueue 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 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.

More Repositories

1

playbook

AvitoTech team playbook
1,443
star
2

Paparazzo

Custom iOS camera and photo picker with editing capabilities
Swift
769
star
3

avito-android

Infrastructure of Avito android
Kotlin
356
star
4

bioyino

High performance and high-precision multithreaded StatsD server
Rust
229
star
5

netramesh

Ultra light service mesh for any orchestrator
Go
228
star
6

go-transaction-manager

Transaction manager for GoLang
Go
227
star
7

Marshroute

Marshroute is an iOS Library for making your Routers simple but extremely powerful
Swift
224
star
8

deepsecrets

Secrets scanner that understands code
Python
180
star
9

aqueduct

Framework for create performance-efficient prediction
Python
171
star
10

Mixbox

iOS UI testing framework https://t.me/mixbox_english https://t.me/mixbox_russian
Swift
152
star
11

go-mutesting

Mutation testing for Go source code. Fork from https://github.com/zimmski/go-mutesting
Go
145
star
12

krop

Small widget for image cropping in Instagram-like style
Kotlin
126
star
13

avitotech-presentations

Go
112
star
14

autumn-2021-intern-assignment

98
star
15

internship_backend_2022

Тестовое задание на позицию стажера-бэкендера
Go
84
star
16

Calcifer

Calcifer
Swift
72
star
17

nginx-log-collector

nginx-log-collector
Go
55
star
18

sx-frontend-trainee-assignment

Тестовое задание для стажёра Frontend в команду Seller Experience
53
star
19

Konveyor

Kotlin
48
star
20

auto-backend-trainee-assignment

Тестовое задание на позицию бекенд разработчика в юнит Авто
42
star
21

navigator

Multicluster service mesh solution based on envoy
Go
39
star
22

pulemet

Controlled RPS for interservice communication
Python
39
star
23

android-ui-testing

Kotlin
39
star
24

python-trainee-assignment

Тестовое задание по python
37
star
25

normalize

Go
35
star
26

adv-backend-trainee-assignment

Тестовое задание для стажёра Backend в команду Advertising
29
star
27

frontend-trainee-assignment-2023

27
star
28

internship_frontend_2022

Тестовое задание на позицию стажера-фронтендера
TypeScript
26
star
29

job-backend-trainee-assignment

Тестовое задание на позицию стажера-бекендера в юнит "Работа"
26
star
30

safedeal-frontend-trainee

22
star
31

pg_reindex

Console utility for rebuilding indexes and primary keys for PostgreSQL in automatic mode with analysis of index bloating and without table locking
Python
21
star
32

msg-backend-trainee-assignment

В ДАННЫЙ МОМЕНТ НЕ АКТУАЛЬНО! Тестовое задание на позицию стажера-бекендера
21
star
33

internship

Тестовое задание для iOS-стажировки
20
star
34

geo-backend-trainee-assignment

20
star
35

android-trainee-task-2021

20
star
36

blur-layout

Support for blurred semitransparent backgrounds in Android.
Assembly
19
star
37

verticals

Публичный репозиторий кластера Verticals
19
star
38

pro-fe-trainee-task

Тестовое задание для FE стажера в Авито Pro (Команда ARPU)
19
star
39

ios-trainee-problem-2021

Тестовое задание для стажера по направлению iOS
19
star
40

smart-redis-replication

Go
18
star
41

mi-backend-trainee-assignment

Тестовое задание для стажёра Backend в команду MI
17
star
42

dba-utils

Shell
17
star
43

clickhouse-vertica-udx

UDF to seamlessly connect ClickHouse to Vertica using external tables
C++
15
star
44

abito

Python package for hypothesis testing. Suitable for using in A/B-testing software
Python
15
star
45

prop-types-definition

Patch for prop-types to get property type definition in runtime
JavaScript
15
star
46

tm-backend-trainee

Тестовое задание для стажёра Backend в команду Trade Marketing
13
star
47

CommandLineToolkit

Small swift package to create command line tools faster
Swift
13
star
48

antibot-developer-trainee

Тестовая задача для разработчика-стажёра в команду Информационной безопасности Авито для защиты сайта от ботов
13
star
49

bx-backend-trainee-assignment

Тестовое задание на позицию стажера-бекендера в юнит Buyer Experience
12
star
50

mx-backend-trainee-assignment

Тестовое задание для стажёра Backend в команду MX
11
star
51

internship_ios_2022

Тестовое задание на позицию стажёра в iOS
Swift
10
star
52

patterns-and-practices-abstracts

9
star
53

dba-docs

PLpgSQL
9
star
54

qa-trainee-task

Тестовое задание для стажёра-автоматизатора
8
star
55

gravure

Image processing microservice
Rust
8
star
56

ImageSource

Image abstraction toolkit
Swift
8
star
57

pgmock

PostgreSQL 9.4+ extension for unit tests
PLpgSQL
8
star
58

mi-trainee-task-2021

7
star
59

puppet-controlrepo-template

Шаблон control repo для Puppet к статье «Инфраструктура как код в Авито: уроки которые мы извлекли»
Ruby
7
star
60

ap-frontend-trainee-assignment

7
star
61

pro-backend-trainee-assignment

6
star
62

mi-trainee-task

Тестовое задание для стажера в Market Intelligence.
6
star
63

android-trainee-task

6
star
64

ShopX-QA-trainee

задания к собеседованию
6
star
65

ios-trainee-problem

Задача для стажера на платформу iOS
6
star
66

iOS-trainee-assignment-2023

5
star
67

protocol-writer

Simplest of apps to write timed protocols from interviews
JavaScript
5
star
68

bx-android-trainee-assigment

5
star
69

safedeal-backend-trainee

5
star
70

puppet-module-template

Шаблон Puppet модуля к статье «Инфраструктура как код в Авито: уроки которые мы извлекли»
Ruby
5
star
71

android-peerlab-moscow

5
star
72

GraphiteClient

Lightweight Swift framework for feeding data into Graphite and statsD.
Swift
4
star
73

video-course-patterns-and-practices

PHP
4
star
74

xrpcd

PostgreSQL RPC built on top of pgq.
Python
4
star
75

doner

Centralized file downloading service
Rust
4
star
76

trainspotting

Python Dependency Injector based on interface binding
Python
4
star
77

moira

Go
3
star
78

qa-trainee-general

Тестовое задание для QA-cтажёра
3
star
79

aaa-ml-sys-design

ML System Design lectures materials
Python
3
star
80

aaa-ml-datasets-course

Репозиторий курса по созданию датасетов Академии Аналитиков Авито
Jupyter Notebook
3
star
81

vas-frontend-trainee-assignment

Задание для стажёра в команду VAS
2
star
82

Emcee.cloud.action

GItHub action for emcee.cloud
Shell
2
star
83

moira-client

Python
2
star
84

alert-autoconf

Python
2
star
85

homebrew-tap

Homebrew Tap of Avito products and tools
Ruby
2
star
86

avito-pixel

HTML
2
star
87

qa-into-CoE-trainee-task

Тестовое задание для стажёра QA в Центр экспертизы по Обеспечению качества
2
star
88

moira-web

JavaScript
1
star
89

test-asap

Package for easy to start browser testing
JavaScript
1
star
90

EmceePluginSupport

Swift package that allows to extend Emcee with plugins
Swift
1
star
91

avito-vault

Puppet модуль, автоматизирующий выкладку секретов из vault.
Ruby
1
star
92

brave-new-billing

Тестовое задание для backend-стажёра в юнит Billing, Avito
1
star
93

Emcee.cloud-CLI

Shell
1
star