使用Browserstack教程(https://www.browserstack.com/app-automate/appium-junit)和示例项目(https://github.com/browserstack/junit-appium-app-browserstack),我在并行测试的设置上很挣扎。
特别是,我需要使用Cucumber.class(@RunWith(Cucumber.class)
)运行suirte,以便从场景中读取我的测试,而Browserstack文档告诉我要使用Parameterized.class(public class Parallelized extends Parameterized
)运行。如果使用Cucumber类运行套件,我遇到的最大问题是如何将多个device + os配置解析到Browserstack。
我的跑步者课程:
package step_definitions;
import org.junit.runner.RunWith;
import io.cucumber.junit.CucumberOptions;
import io.cucumber.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(features = {
"src/main/resources/FeatureFiles" }, dryRun = false, strict = false, monochrome = true, plugin = {
"html:target/cucumber", "json:target/cucumber.json" },
// glue = {"iOSAutomation/src/test/java/step_definitions"},
tags = { "@Login"})
public class RunTest {
}
启动器:
package step_definitions;
import (...)
public class Launcher {
public static IOSDriver<IOSElement> driver;
public static WebDriverWait wait;
// Parallel BS tests
private static JSONObject config;
@Parameter(value = 0)
public static int taskID;
@Parameters
public static Iterable<? extends Object> data() throws Exception {
List<Integer> taskIDs = new ArrayList<Integer>();
if (System.getProperty("config") != null) {
JSONParser parser = new JSONParser();
config = (JSONObject) parser.parse(new FileReader("src/main/resources/conf/" + System.getProperty("config")));
int envs = ((JSONArray) config.get("environments")).size();
for (int i = 0; i < envs; i++) {
taskIDs.add(i);
}
}
return taskIDs;
}
@Before
public static void Launchapp(Scenario scenario) throws InterruptedException, FileNotFoundException, IOException, ParseException {
JSONArray envs = (JSONArray) config.get("environments");
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "xcuitest");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
caps.setCapability("bundleId", bundleId);
caps.setCapability(MobileCapabilityType.APP, "useNewWDA");
caps.setCapability(MobileCapabilityType.APP, "clearSystemFiles");
caps.setCapability(MobileCapabilityType.APP, app);
caps.setCapability("browserstack.local", "false");
caps.setCapability("webkitResponseTimeout", "60000");
caps.setCapability("browserstack.localIdentifier", "Test123");
caps.setCapability("browserstack.appium_version", "1.9.1");
caps.setCapability("startIWDP", true);
caps.setCapability("instrumentApp", true);
caps.setCapability("webkitResponseTimeout", 70000);
Map<String, String> envCapabilities = (Map<String, String>) envs.get(taskID);
Iterator it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
caps.setCapability(pair.getKey().toString(), pair.getValue().toString());
}
driver = new IOSDriver<IOSElement>(
new URL("http://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub"), caps);
sessionId = driver.getSessionId().toString();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 30);
}
@After
public void tearDown(Scenario scenario) throws Exception {
driver.quit();
}
}
Parallelized.java:
package step_definitions;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.runners.Parameterized;
import org.junit.runners.model.RunnerScheduler;
import io.cucumber.junit.Cucumber;
public class Parallelized extends Parameterized {
private static class ThreadPoolScheduler implements RunnerScheduler {
private ExecutorService executor;
public ThreadPoolScheduler() {
String threads = System.getProperty("junit.parallel.threads", "4");
int numThreads = Integer.parseInt(threads);
executor = Executors.newFixedThreadPool(numThreads);
}
@Override
public void finished() {
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException exc) {
throw new RuntimeException(exc);
}
}
@Override
public void schedule(Runnable childStatement) {
executor.submit(childStatement);
}
}
public Parallelized(Class klass) throws Throwable {
super(klass);
setScheduler(new ThreadPoolScheduler());
}
}
和配置文件:
{
"environments": [{
"device": "iPhone XR",
"os_version": "12"
}, {
"device": "iPhone 6S",
"os_version": "11"
}, {
"device": "iPhone XS",
"os_version": "13"
}, {
"device": "iPhone XS Max",
"os_version": "12"
}]
}
如何使其运作?我可以使用Cucumber.class运行它,并以某种方式合并Parallelized.java中的方法吗?
您可以使用MakeFile来提供所有设备或平台的功能,并且使用cumcum-jvm-parallel-plugin可以在Browserstack中并行运行测试。这将是最简单的解决方案。
示例MakeFile:
browserstack_parallel:使-j bs_iPhoneXS bs_iPhoneX
bs_iPhoneXS:mvn test -Dbs_local_testing = false -Dbs_device = iPhoneXS -Dbs_app = bs:// 0fb247cde17a979db4d7e5a521bc600af7620b63
bs_iPhoneX:mvn test -Dbs_local_testing = false -Dbs_device = iPhoneX -Dbs_app = bs:// 0fb247cde17a979db4d7e5a521bc600af7620b63