org.testobject.appium.junit.TestObjectAppiumSuite Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of testobject-appium-java-api Show documentation
Show all versions of testobject-appium-java-api Show documentation
java wrapper for testobject's appium java apis
package org.testobject.appium.junit;
import com.google.common.base.Optional;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Suite;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerScheduler;
import org.testobject.appium.junit.internal.Util;
import org.testobject.rest.api.RestClient;
import org.testobject.rest.api.appium.common.Env;
import org.testobject.rest.api.appium.common.TestObject;
import org.testobject.rest.api.appium.common.data.SuiteReport;
import org.testobject.rest.api.appium.common.data.Test;
import org.testobject.rest.api.resource.AppiumSuiteReportResource;
import org.testobject.rest.api.resource.AppiumSuiteResource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TestObjectAppiumSuite extends Suite {
private class PerDeviceRunner extends BlockJUnit4ClassRunner {
private final String deviceId;
public PerDeviceRunner(Class> clazz, String deviceId) throws InitializationError {
super(clazz);
this.deviceId = deviceId;
}
@Override
protected Description describeChild(FrameworkMethod method) {
return Description
.createTestDescription(getTestClass().getJavaClass(), testName(method) + "[" + deviceId + "]", method.getAnnotations());
}
@Override
protected List getTestRules(Object target) {
List testRules = super.getTestRules(target);
for (TestRule testRule : testRules) {
if (testRule instanceof TestObjectTestResultWatcher) {
TestObjectTestResultWatcher resultWatcher = (TestObjectTestResultWatcher) testRule;
resultWatcher.configureForSuiteExecution(testObjectApiKey, testObjectSuiteId, suiteReport);
}
}
return testRules;
}
@Override
protected String getName() {
return super.getName() + "[" + deviceId + "]";
}
}
protected static class ThreadPoolScheduler implements RunnerScheduler {
private final int timeout;
private final TimeUnit timeoutUnit;
private final ExecutorService executor;
public ThreadPoolScheduler(int numberOfThreads, int timeout, TimeUnit timeoutUnit) {
this.timeout = timeout;
this.timeoutUnit = timeoutUnit;
executor = Executors.newFixedThreadPool(numberOfThreads);
}
public void schedule(final Runnable childStatement) {
executor.submit(childStatement);
}
public void finished() {
executor.shutdown();
try {
executor.awaitTermination(timeout, timeoutUnit);
} catch (InterruptedException exc) {
throw new RuntimeException(exc);
}
}
}
private static final List NO_RUNNERS = Collections.emptyList();
private static final int timeoutDefault = 60;
private static final TimeUnit timeunitDefault = TimeUnit.MINUTES;
private final RestClient client;
private final List perDeviceRunners;
private String testObjectApiKey;
private long testObjectSuiteId;
private Optional testObjectAppId;
private String[] testObjectDeviceIds;
private boolean runLocally;
private SuiteReport suiteReport;
public TestObjectAppiumSuite(Class> clazz) throws InitializationError {
super(clazz, NO_RUNNERS);
TestObject config = getConfig(clazz);
Optional runLocallyFromEnvironment = Env.isTestLocally();
runLocally = runLocallyFromEnvironment.isPresent() ? Boolean.valueOf(runLocallyFromEnvironment.get()) : config.testLocally();
if (runLocally) {
this.client = null;
Set deviceIds = getLocalDeviceId();
this.perDeviceRunners = toRunners(clazz, deviceIds);
this.setScheduler(new ThreadPoolScheduler(deviceIds.size(), timeoutDefault, timeunitDefault));
} else {
Optional endpointFromEnvironment = Env.getApiEndpoint();
String testObjectApiEndpoint = endpointFromEnvironment.isPresent() ? endpointFromEnvironment.get() : config.testObjectApiEndpoint();
Optional apiKeyFromEnvironment = Env.getApiKey();
testObjectApiKey = apiKeyFromEnvironment.isPresent() ? apiKeyFromEnvironment.get() : config.testObjectApiKey();
Optional suiteIdFromEnvironment = Env.getSuiteId();
testObjectSuiteId = suiteIdFromEnvironment.isPresent() ? Long.parseLong(suiteIdFromEnvironment.get()) : config.testObjectSuiteId();
Optional appIdFromEnvironment = Env.getAppId();
Optional appIdFromAnnotation = config.testObjectAppId() != 0 ? Optional.of(Long.toString(config.testObjectAppId())) : Optional.absent();
testObjectAppId = appIdFromEnvironment.isPresent() ? appIdFromEnvironment : appIdFromAnnotation;
Optional deviceIdsFromEnvironment = Env.getDevicesIds();
testObjectDeviceIds = deviceIdsFromEnvironment.isPresent() ? deviceIdsFromEnvironment.get().split(", ") : config.testObjectDeviceIds();
Optional timeoutFromEnvironment = Env.getTimeout();
int testObjectTimeout = timeoutFromEnvironment.isPresent() ? Integer.parseInt(timeoutFromEnvironment.get()) : config.timeout();
this.client = RestClient.Builder.createClient()
.withUrl(testObjectApiEndpoint)
.withToken(testObjectApiKey)
.path(RestClient.REST_APPIUM_PATH)
.build();
Set deviceIds;
if (testObjectDeviceIds.length == 0) {
deviceIds = getRemoteDeviceIds();
} else {
deviceIds = new HashSet(Arrays.asList(testObjectDeviceIds));
}
this.perDeviceRunners = toRunners(clazz, deviceIds);
this.setScheduler(new ThreadPoolScheduler(deviceIds.size(), testObjectTimeout, config.timeoutUnit()));
}
}
@Override
public void run(RunNotifier notifier) {
Set tests = getTests(getDescription());
if (runLocally) {
super.run(notifier);
} else {
AppiumSuiteReportResource suiteReportResource = new AppiumSuiteReportResource(client);
try {
this.suiteReport = suiteReportResource.startSuiteReport(testObjectSuiteId, testObjectAppId, tests);
try {
super.run(notifier);
} finally {
suiteReportResource.finishSuiteReport(testObjectSuiteId, suiteReport.getId());
}
} finally {
client.close();
}
}
}
protected List getChildren() {
return this.perDeviceRunners;
}
private static TestObject getConfig(Class> clazz) {
TestObject testobject = clazz.getAnnotation(TestObject.class);
if (testobject == null) {
throw new IllegalStateException("class " + clazz + " must be annotated with " + TestObject.class.getName());
}
return testobject;
}
private Set getRemoteDeviceIds() {
if (testObjectDeviceIds != null && testObjectDeviceIds.length > 0) {
return new HashSet(Arrays.asList(testObjectDeviceIds));
}
AppiumSuiteResource suiteReportResource = new AppiumSuiteResource(client);
Set deviceIds = suiteReportResource.readSuiteDeviceIds(testObjectSuiteId);
return deviceIds;
}
private Set getLocalDeviceId() {
return new HashSet(Collections.singletonList("Local_device"));
}
private List toRunners(Class> clazz, Set deviceIds) throws InitializationError {
List runners = new ArrayList(deviceIds.size());
for (String deviceId : deviceIds) {
runners.add(new PerDeviceRunner(clazz, deviceId));
}
return runners;
}
private static Set getTests(Description description) {
Set tests = new HashSet();
for (Description childDescription : description.getChildren()) {
for (Description testDescription : childDescription.getChildren()) {
tests.add(Util.from(testDescription));
}
}
return tests;
}
}