如何在测试期间在 Android 设备之间切换
How to switch between Android devices during the tests
我是自动化初学者。我正在本机应用程序上编写自动测试。
使用一台设备通过测试时,一切正常。
但我希望在测试期间涉及 2 个或更多可以分布式工作的设备。
例子:
设备 1(用户 1)
申请开始
登录应用程序
创建一条消息并发送给用户 2
设备 2(用户 2)
申请开始
登录应用程序
检查从用户 1
收到的消息
由于我是初学者,在我的理解中应该是一次测试,以免做多个测试相互依赖,只是在驱动程序(设备)之间切换
现在一切都在以下层次结构中完成:
MobileDriver class - 在其中初始化驱动程序
Class 测试
helper classes - 用于延迟、期望等。
A class 带有测试本身的逻辑方法
如果我的逻辑有误或无法做到,请提出更正确的解决方案
我在创意工作
Java 8
Appium 1.14.0
Windows10
public class MobileDriver {
public static AppiumDriver<MobileElement> driver;
public static AppiumDriver<MobileElement> driver2;
public void mobileDriver(String arg) throws MalformedURLException {
if (arg.equals("1")) {
emulatorDevice5554();
} else if (arg.equals("2")) {
emulatorDevice5556();
} else if (arg.equals("3")) {
realDevice();
} else if (arg.equals("4")) {
test2devices();
}
public void emulatorDevice5554() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
//desiredCapabilities.setCapability(CapabilityType.BROWSER_NAME, "");
//desiredCapabilities.setCapability("deviceName", "Android Emulator");
desiredCapabilities.setCapability("deviceName", "emulator-5554");
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("platformVersion", "8.1.0");
desiredCapabilities.setCapability("systemPort", "8201");
//desiredCapabilities.setCapability("automationName", "Appium");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
//initialize mobileDriver
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
public void emulatorDevice5556() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
//desiredCapabilities.setCapability(CapabilityType.BROWSER_NAME, "");
//desiredCapabilities.setCapability("deviceName", "Android Emulator");
desiredCapabilities.setCapability("deviceName", "emulator-5556");
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("platformVersion", "7.0");
desiredCapabilities.setCapability("systemPort", "8202");
//desiredCapabilities.setCapability("automationName", "Appium");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
//initialize mobileDriver
driver2 = new AndroidDriver(new URL("http://127.0.0.1:5000/wd/hub"), desiredCapabilities);
driver2.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
}
public abstract class Page {
public MobileDriver driver;
public WEBDriver chromeDriver;
}
public class CreateQuestionScreen extends Page {
public CreateQuestionScreen(MobileDriver driver) {
super.driver = driver;
}
public SwipesAndClicks swipesAndClicks = new SwipesAndClicks(driver);
public WaitsMobile waitsMobile = new WaitsMobile(driver);
public Randomizer randomizer = new Randomizer();
Logger logger = LoggerFactory.getLogger(ContinueScreen.class);
public void searchQuestion() {
waitsMobile.waitForElementAndClick(By.xpath(C.BTN_FORUM),
"element BTN_FORUM not found",
2);
logger.info("success click to BTN_FORUM element");
waitsMobile.waitForElementAndClick(By.xpath(C.CHOOSE_BUSINESS_CATEGORY),
"element CHOOSE_BUSINESS_CATEGORY not found",
2);
logger.info("success choose CHOOSE_BUSINESS_CATEGORY element");
try {
waitsMobile.waitForElementAndClick(By.xpath("//android.widget.TextView[@text='" + testQuestion + "']"),
"element" + testQuestion + "not found from try",
2);
logger.info("message '" + testQuestion + "' found");
} catch (NoSuchElementException e) {
System.out.println("element" + testQuestion + "not found from catch");
}
}
}
public class SendMessageToExpertTest extends utility.tested.Test {
public static MobileDriver driver;
public static SwipesAndClicks swipesAndClicks;
public static WaitsMobile waitsMobile;
public static ContinueScreen continueScreen;
public static SignInScreen signInScreen;
public static ProfileScreen profileScreen;
public static ExpertProfileScreen expertProfileScreen;
@BeforeClass
public static void setUp() throws MalformedURLException, InterruptedException {
driver = new MobileDriver();
continueScreen = new ContinueScreen(driver);
signInScreen = new SignInScreen(driver);
profileScreen = new ProfileScreen(driver);
waitsMobile = new WaitsMobile(driver);
driver.mobileDriver("1");
driver2.mobileDriver("2");
swipesAndClicks = new SwipesAndClicks(driver);
expertProfileScreen = new ExpertProfileScreen(driver);
continueScreen.clickContinueButton();
signInScreen.signInViaGoogle();
Thread.sleep(6000);
swipesAndClicks.clickToTips();
}
@Category(Regression.class)
@Test
public void sendMessageToExpertTest() throws Exception{
expertProfileScreen.sendMessageToExpert();
swipesAndClicks.clickToPinCode();
expertProfileScreen.checkMessage();
}
}
你的代码有点乱。我建议您使用 Java 阅读更多有关面向对象编程的内容。因为我认为同时使用两个设备很有趣,所以我会尽力帮助你,我稍微清理了你的代码(我没有测试它,它应该只会引导你朝着正确的方向前进)。
我改变的东西:
- 移动驱动程序class:
- 我会将 class
MobileDriver
重命名为 SetUpDriver
(或类似名称)并将其用作实用程序 class。
- 隐藏构造函数,没有人可以创建它的实例。 Can a constructor in Java be private?
- 使 class 最终无法扩展。 What is the point of “final class” in Java?
- 从 class 外部只能调用方法
getMobileDriver
。此方法 returns 一个新的 AndroidDriver。
- 从 Java7 开始,可以在 switch 语句中使用字符串。 New Java 7 Feature: String in Switch support
- 移动通用功能将减少重复代码。您可以使用参数而不是两种类似的方法来设置端口和其他功能。
- 现在开始测试:
- 如果您在所有测试中都需要这两种设备,您可以将它们添加到基础 class
Page.java
。如果不是,我会在需要的地方将第二个驱动程序添加到那些测试 classes 中。
- 不要将这些字段设为静态。 What is the exact meaning of static fields in Java?
- 初始化两个设备后,您可以在测试方法中随意使用它们。
SetUpDriver.java
public final class SetUpDriver {
private SetUpDriver() {
// Hide the constructor.
}
public static AndroidDriver<MobileElement> getMobileDriver(String type) throws MalformedURLException {
switch (type) {
case "1":
return emulatorDevice5554();
case "2":
return emulatorDevice5556();
default:
throw new IllegalArgumentException();
}
}
private static AndroidDriver<MobileElement> emulatorDevice5554() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = getCommonCapabilities();
desiredCapabilities.setCapability("deviceName", "emulator-5554");
desiredCapabilities.setCapability("platformVersion", "8.1.0");
desiredCapabilities.setCapability("systemPort", "8201");
// initialize mobileDriver
AndroidDriver<MobileElement> driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"),
desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
return driver;
}
private static AndroidDriver<MobileElement> emulatorDevice5556() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = getCommonCapabilities();
desiredCapabilities.setCapability("deviceName", "emulator-5556");
desiredCapabilities.setCapability("platformVersion", "7.0");
desiredCapabilities.setCapability("systemPort", "8202");
// initialize mobileDriver
AndroidDriver<MobileElement> driver = new AndroidDriver<>(new URL("http://127.0.0.1:5000/wd/hub"),
desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
return driver;
}
private static DesiredCapabilities getCommonCapabilities() {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
return desiredCapabilities;
}
}
SendMessageToExpertTest.java
public class SendMessageToExpertTest extends utility.tested.Test {
private AndroidDriver<MobileElement> driver; // first device
private AndroidDriver<MobileElement> driver2; // second device
// Other members if needed.
@BeforeClass
public void setUp() throws MalformedURLException, InterruptedException {
driver = SetUpDriver.getMobileDriver("1");
driver2 = SetUpDriver.getMobileDriver("2");
// Init other objects if needed.
}
@Category(Regression.class)
@Test
public void sendMessageToExpertTest() throws Exception {
// Perform your test.
// TODO
}
}
总而言之,我认为最好在开始编写自动化测试之前学习 Java 和 OOP。
我是自动化初学者。我正在本机应用程序上编写自动测试。 使用一台设备通过测试时,一切正常。 但我希望在测试期间涉及 2 个或更多可以分布式工作的设备。 例子: 设备 1(用户 1) 申请开始 登录应用程序 创建一条消息并发送给用户 2
设备 2(用户 2) 申请开始 登录应用程序 检查从用户 1
收到的消息由于我是初学者,在我的理解中应该是一次测试,以免做多个测试相互依赖,只是在驱动程序(设备)之间切换
现在一切都在以下层次结构中完成: MobileDriver class - 在其中初始化驱动程序 Class 测试 helper classes - 用于延迟、期望等。 A class 带有测试本身的逻辑方法
如果我的逻辑有误或无法做到,请提出更正确的解决方案
我在创意工作 Java 8 Appium 1.14.0 Windows10
public class MobileDriver {
public static AppiumDriver<MobileElement> driver;
public static AppiumDriver<MobileElement> driver2;
public void mobileDriver(String arg) throws MalformedURLException {
if (arg.equals("1")) {
emulatorDevice5554();
} else if (arg.equals("2")) {
emulatorDevice5556();
} else if (arg.equals("3")) {
realDevice();
} else if (arg.equals("4")) {
test2devices();
}
public void emulatorDevice5554() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
//desiredCapabilities.setCapability(CapabilityType.BROWSER_NAME, "");
//desiredCapabilities.setCapability("deviceName", "Android Emulator");
desiredCapabilities.setCapability("deviceName", "emulator-5554");
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("platformVersion", "8.1.0");
desiredCapabilities.setCapability("systemPort", "8201");
//desiredCapabilities.setCapability("automationName", "Appium");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
//initialize mobileDriver
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
public void emulatorDevice5556() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
//desiredCapabilities.setCapability(CapabilityType.BROWSER_NAME, "");
//desiredCapabilities.setCapability("deviceName", "Android Emulator");
desiredCapabilities.setCapability("deviceName", "emulator-5556");
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("platformVersion", "7.0");
desiredCapabilities.setCapability("systemPort", "8202");
//desiredCapabilities.setCapability("automationName", "Appium");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
//initialize mobileDriver
driver2 = new AndroidDriver(new URL("http://127.0.0.1:5000/wd/hub"), desiredCapabilities);
driver2.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
}
public abstract class Page {
public MobileDriver driver;
public WEBDriver chromeDriver;
}
public class CreateQuestionScreen extends Page {
public CreateQuestionScreen(MobileDriver driver) {
super.driver = driver;
}
public SwipesAndClicks swipesAndClicks = new SwipesAndClicks(driver);
public WaitsMobile waitsMobile = new WaitsMobile(driver);
public Randomizer randomizer = new Randomizer();
Logger logger = LoggerFactory.getLogger(ContinueScreen.class);
public void searchQuestion() {
waitsMobile.waitForElementAndClick(By.xpath(C.BTN_FORUM),
"element BTN_FORUM not found",
2);
logger.info("success click to BTN_FORUM element");
waitsMobile.waitForElementAndClick(By.xpath(C.CHOOSE_BUSINESS_CATEGORY),
"element CHOOSE_BUSINESS_CATEGORY not found",
2);
logger.info("success choose CHOOSE_BUSINESS_CATEGORY element");
try {
waitsMobile.waitForElementAndClick(By.xpath("//android.widget.TextView[@text='" + testQuestion + "']"),
"element" + testQuestion + "not found from try",
2);
logger.info("message '" + testQuestion + "' found");
} catch (NoSuchElementException e) {
System.out.println("element" + testQuestion + "not found from catch");
}
}
}
public class SendMessageToExpertTest extends utility.tested.Test {
public static MobileDriver driver;
public static SwipesAndClicks swipesAndClicks;
public static WaitsMobile waitsMobile;
public static ContinueScreen continueScreen;
public static SignInScreen signInScreen;
public static ProfileScreen profileScreen;
public static ExpertProfileScreen expertProfileScreen;
@BeforeClass
public static void setUp() throws MalformedURLException, InterruptedException {
driver = new MobileDriver();
continueScreen = new ContinueScreen(driver);
signInScreen = new SignInScreen(driver);
profileScreen = new ProfileScreen(driver);
waitsMobile = new WaitsMobile(driver);
driver.mobileDriver("1");
driver2.mobileDriver("2");
swipesAndClicks = new SwipesAndClicks(driver);
expertProfileScreen = new ExpertProfileScreen(driver);
continueScreen.clickContinueButton();
signInScreen.signInViaGoogle();
Thread.sleep(6000);
swipesAndClicks.clickToTips();
}
@Category(Regression.class)
@Test
public void sendMessageToExpertTest() throws Exception{
expertProfileScreen.sendMessageToExpert();
swipesAndClicks.clickToPinCode();
expertProfileScreen.checkMessage();
}
}
你的代码有点乱。我建议您使用 Java 阅读更多有关面向对象编程的内容。因为我认为同时使用两个设备很有趣,所以我会尽力帮助你,我稍微清理了你的代码(我没有测试它,它应该只会引导你朝着正确的方向前进)。
我改变的东西:
- 移动驱动程序class:
- 我会将 class
MobileDriver
重命名为SetUpDriver
(或类似名称)并将其用作实用程序 class。 - 隐藏构造函数,没有人可以创建它的实例。 Can a constructor in Java be private?
- 使 class 最终无法扩展。 What is the point of “final class” in Java?
- 从 class 外部只能调用方法
getMobileDriver
。此方法 returns 一个新的 AndroidDriver。 - 从 Java7 开始,可以在 switch 语句中使用字符串。 New Java 7 Feature: String in Switch support
- 移动通用功能将减少重复代码。您可以使用参数而不是两种类似的方法来设置端口和其他功能。
- 我会将 class
- 现在开始测试:
- 如果您在所有测试中都需要这两种设备,您可以将它们添加到基础 class
Page.java
。如果不是,我会在需要的地方将第二个驱动程序添加到那些测试 classes 中。 - 不要将这些字段设为静态。 What is the exact meaning of static fields in Java?
- 初始化两个设备后,您可以在测试方法中随意使用它们。
- 如果您在所有测试中都需要这两种设备,您可以将它们添加到基础 class
SetUpDriver.java
public final class SetUpDriver {
private SetUpDriver() {
// Hide the constructor.
}
public static AndroidDriver<MobileElement> getMobileDriver(String type) throws MalformedURLException {
switch (type) {
case "1":
return emulatorDevice5554();
case "2":
return emulatorDevice5556();
default:
throw new IllegalArgumentException();
}
}
private static AndroidDriver<MobileElement> emulatorDevice5554() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = getCommonCapabilities();
desiredCapabilities.setCapability("deviceName", "emulator-5554");
desiredCapabilities.setCapability("platformVersion", "8.1.0");
desiredCapabilities.setCapability("systemPort", "8201");
// initialize mobileDriver
AndroidDriver<MobileElement> driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"),
desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
return driver;
}
private static AndroidDriver<MobileElement> emulatorDevice5556() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = getCommonCapabilities();
desiredCapabilities.setCapability("deviceName", "emulator-5556");
desiredCapabilities.setCapability("platformVersion", "7.0");
desiredCapabilities.setCapability("systemPort", "8202");
// initialize mobileDriver
AndroidDriver<MobileElement> driver = new AndroidDriver<>(new URL("http://127.0.0.1:5000/wd/hub"),
desiredCapabilities);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
return driver;
}
private static DesiredCapabilities getCommonCapabilities() {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("app", "C:/Users/Asus/IdeaProjects/iopayphonex/app/app.apk");
desiredCapabilities.setCapability("appPackage", "package");
desiredCapabilities.setCapability("appActivity", "Activity");
desiredCapabilities.setCapability("noReset", true);
return desiredCapabilities;
}
}
SendMessageToExpertTest.java
public class SendMessageToExpertTest extends utility.tested.Test {
private AndroidDriver<MobileElement> driver; // first device
private AndroidDriver<MobileElement> driver2; // second device
// Other members if needed.
@BeforeClass
public void setUp() throws MalformedURLException, InterruptedException {
driver = SetUpDriver.getMobileDriver("1");
driver2 = SetUpDriver.getMobileDriver("2");
// Init other objects if needed.
}
@Category(Regression.class)
@Test
public void sendMessageToExpertTest() throws Exception {
// Perform your test.
// TODO
}
}
总而言之,我认为最好在开始编写自动化测试之前学习 Java 和 OOP。