-
Notifications
You must be signed in to change notification settings - Fork 28
Plugins
Emcee supports plugins for both workers and queue processes. Plugins do not alter any logic of Emcee, but they can listen to the events and react to them accordingly.
Possible use cases for plugins:
-
Integrate your tests with your test management system - for example, update test statuses in your TMS when test finishes.
-
Record videos of tests: e.g. you may develop a logic to purge video if test succeeds, and upload video to your internal storage if test fails, for further investigation. Use
SimulatorVideoRecorder
module for that.
Tests can leave various artifacts in a place where plugin can pick them up later. Emcee creates a special folder and passes it into tests using EMCEE_TESTS_WORKING_DIRECTORY
environment variable.
Plugin can use TestsWorkingDirectoryDeterminer
class from TestsWorkingDirectorySupport
module to determine that path, and then pick up the artifacts left by tests.
It is up to you to determine the protocol between tests and the plugin. As an example, tests can create their reports and store them as JSON files, and plugin can then read these files and operate on them as needed. Tests and plugin can share underlying models to be in sync.
It is convenient to develop Emcee plugins as Swift packages.
This is a base module for implementing Emcee plugin. In your Package.swift
, import the library that has all required APIs to implement a plugin:
dependencies: [
.package(url: "https://github.com/avito-tech/Emcee", .branch("master"))
]
In your plugin target add EmceePlugin
dependency:
targets: [
.target(
name: "TestPlugin",
dependencies: [
"EmceePlugin"
]
)
]
Plugin will listen to Emcee event bus via EventStream
instance. Emcee provides DefaultBusListener
open class for your convenience (available is EventBus
module). Subclass it and override its methods to receive corresponding events.
Example implementation of capturing commonly used events related to test execution flow.
import EventBus
import Models
import Plugin
class MyPluginListener: DefaultBusListener {
override func runnerEvent(_ event: RunnerEvent) {
switch event {
case .willRun(let testEntries, let testContext):
// will be called when Emcee is preparing to run bucket with tests
break
case .didRun(let testEntryResults, let testContext):
// will be called when Emcee finish running a set of tests
// and already has test results
break
case .testStarted(let testEntry, let testContext):
// will be called when test has started
break
case .testFinished(let testEntry, let succeeded, let testContext):
// will be called when test has finished
break
}
}
override func tearDown() {
// will be called before Emcee will terminate your plugin
// close your pipes here
}
}
Plugin can take advantage from TestContext
object passed into most events - it describes the test environment.
Since any plugin is an regular executable, you will need to provide main.swift
file - your executable entry point. It may contain the following code:
import EventBus
import LoggingSetup
import Plugin
// Make use of Emcee logging
// Logs will be written to a hosting machine
// at ~/Library/Logs/ru.avito.emcee.logs/Plugin/
try LoggingSetup.setupLogging(stderrVerbosity: Verbosity.debug)
// Create an event bus that will get the events from the Emcee
let eventBus = EventBus()
// Subscribe to the event bus by providing your instance of EventStream
eventBus.add(stream: MyPluginListener())
// Plugin class will stream all events into event bus
let plugin = Plugin(eventBus: eventBus)
plugin.streamPluginEvents()
// Wait for plugin to finish:
plugin.join()
First, build your plugin using swift build
command.
Emcee expects all plugins to have the following bundle structure:
YourPlugin.emceeplugin/
Plugin <-- your plugin executable
You can use some basic Bash skills to prepare bundle and ZIP it:
#!/bin/bash
set -e
pluginName="YourPlugin.emceeplugin"
pluginPath=".build/debug/$pluginName/"
rm -rf "$pluginPath"
mkdir -p "$pluginPath"
cp .build/debug/Plugin "$pluginPath"
cd "$pluginPath/../"
rm -rf "$pluginName".zip
zip -r "$pluginName".zip "$pluginName"
You should upload your YourPlugin.zip
to your web server. Then you can declare URL to this file as plugins
value of queue server configuration.