Appium 是一个开源的自动化测试工具,用于测试原生、混合和移动 Web 应用。在 Appium 中进行移动应用自动化测试时,元素定位是测试脚本中非常关键的一部分,因为正确识别应用中的 UI 元素是执行测试的前提
Appium Inspector
Finding elements by xpath
WebElement digit_9 = driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.support.v4.view.viewPager[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.Button[3]"));
Finding elements by name
WebElement editBox = driver.findElement(By.name("IntegerB"));
Finding elements by IosUIAutomation
findElements(By.IosUIAutomation(String IosUIAuto));
//这个方法会返回一个元素的数组,我们需要通过索引定位到唯一的元素,例如
WebElement editBox = driver.findElements(By.IosUIAutomation(".elements()[0]"));
WebElement editBox = driver.findElements(By.IosUIAutomation(".textFields()[0]"));
uiautomatorviewer
在WIndows系统上进行元素定位,建议使用这个工具,在Mac上建议用Appium Inspector
启动uiautomatorviewer.bat
链接移动设备
- 确认连接手机状态正常-》打开手机qq页面,让屏幕处于点亮状态
- 点左上角安卓机器人按钮 Devices Screenshot 按钮刷新页面
定位元素
点击登录按钮代码实例
如上图所示,定位了登陆按钮,代码实例如下
1
2 package testscript;/*
3 * @FileName testscript.Test_Calculator:
4 * @author davieyang
5 * @create 2018-11-20 11:02
6 */
7 import org.apache.log4j.xml.DOMConfigurator;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.concurrent.TimeUnit;
11
12 import org.openqa.selenium.By;
13 import org.openqa.selenium.remote.DesiredCapabilities;
14 import org.testng.Assert;
15 import org.testng.annotations.BeforeTest;
16 import org.testng.annotations.DataProvider;
17 import org.testng.annotations.Test;
18
19 import io.appium.java_client.android.AndroidDriver;
20
21 public class Test_Calculator {
22 static {
23 //指定log4j配置文件为log4j.xml
24 DOMConfigurator.configure("log4j.xml");
25 }
26 AndroidDriver driver;
27 @BeforeTest
28 public void setUp() throws MalformedURLException{
29 DesiredCapabilities caps = new DesiredCapabilities();
30 // des.setCapability("app", "c:\\");
31 caps.setCapability("automationname", "Appium");
32 caps.setCapability("platformName", "Android");
33 caps.setCapability("platformVersion", "23");
34 caps.setCapability("udid", "WTKDU17105005171");
35 caps.setCapability("deviceName", "Honor");
36 caps.setCapability("appPackage", "com.tencent.qqpimsecure");//com.android.contacts
37 caps.setCapability("appActivity", "com.tencent.server.fore.QuickLoadActivity");//.activities.PeopleActivity
38 caps.setCapability("appWaitActivity", "com.tencent.server.fore.QuickLoadActivity");
39 caps.setCapability("unicodeKeyboard", "True");
40 caps.setCapability("resetKeyboard", "True");
41 caps.setCapability("newCommandTimeout", "15");
42 caps.setCapability("nosign", "True");
43 driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),caps);
44 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
45 }
46 @Test
47 public void add() {
48 driver.findElement(By.xpath("com.tencent.mobileqq:id/btn_login")).click();
49 }
元素定位方式及语法
Finding Elements By ID
WebElement digit_5 = driver.findElement(By.id("com.android.calculator2:id/digit5"));
Finding Elements By Name
WebElement delete = driver.findElement(By.name("DELETE"));
Finding Elements By CLASSNAME
WebElement editBox = driver.findElement(By.className("android.widget.EditText"));
If the same class is used for multiple elements, then we need to select an element on the basic of indexing. For example:
List<WebElement>editBox = driver.findElements(By.className("android.widget.Button"));
editBox.get(1).click();
Finding Elements By AccessibilityID
WebElement plusSign=driver.findElementByAccessibilityId("plus");
Finding Elements By AndroidUIAutomator
//findElement(By.AndroidUIAutomator(String UIAuto));
WebElement equal = driver.findElementByAndroidUiAutomator("new UiSelector().resourceId(\"com.android.calculator2:id/equal\")")
WebElement equal = driver.findElementByAndroidUiAutomator("new UiSelector().description(\"equals\")");
其他定位方式
测试计算器代码实例
Java结合TestNG单元测试框架结合DP实现数据驱动,实现移动端计算器测试【源码】
package testscript;
/*
* @FileName testscript.Test_Calculator:
* @author davieyang
* @create 2018-11-20 11:02
*/
import io.appium.java_client.remote.MobileCapabilityType;
import org.apache.log4j.xml.DOMConfigurator;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import io.appium.java_client.android.AndroidDriver;
public class Test_Calculator {
static {
//指定log4j配置文件为log4j.xml
DOMConfigurator.configure("log4j.xml");
}
AndroidDriver driver;
@BeforeTest
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
// des.setCapability("app", "c:\\");
caps.setCapability("automationname", "Appium");
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", "23");
caps.setCapability("udid", "WTKDU17105005171");
caps.setCapability("deviceName", "Honor");
//com.android.contacts
caps.setCapability("appPackage", "com.android.calculator2");
//.activities.PeopleActivity
caps.setCapability("appActivity", ".Calculator");
caps.setCapability("appWaitActivity", ".Calculator");
caps.setCapability("unicodeKeyboard", "True");
caps.setCapability("resetKeyboard", "True");
caps.setCapability("newCommandTimeout", "15");
caps.setCapability("nosign", "True");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
@DataProvider(name="testdata")
public Object[][] getData(){
return new Object[][]{{"20","80","100","+"},{"90","3","270","×"},{"6","2","3","÷"}};
}
@Test(dataProvider = "testdata")
public void calcTestcase(String num1,String num2,String result,String calcType){
for(char num:num1.toCharArray()){
driver.findElement(By.xpath("//android.widget.Button[@text='"+String.valueOf(num)+"']")).click();
}
driver.findElement(By.xpath("//android.widget.Button[@text='"+calcType+"']")).click();
for(char num:num2.toCharArray()){
driver.findElement(By.xpath("//android.widget.Button[@text='"+String.valueOf(num)+"']")).click();
}
driver.findElement(By.xpath("//android.widget.Button[@text='=']")).click();
String value = driver.findElement(By.xpath("//android.widget.EditText[@class='android.widget.EditText']"))
.getAttribute("text");
Assert.assertEquals(value, result);
}
}
package testscript;
/*
* @FileName testscript.Test_Calculator:
* @author davieyang
* @create 2018-11-20 11:02
*/
import io.appium.java_client.remote.MobileCapabilityType;
import org.apache.log4j.xml.DOMConfigurator;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import io.appium.java_client.android.AndroidDriver;
public class Test_Calculator {
static {
//指定log4j配置文件为log4j.xml
DOMConfigurator.configure("log4j.xml");
}
AndroidDriver driver;
@BeforeTest
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
// des.setCapability("app", "c:\\");
caps.setCapability("automationname", "Appium");
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", "23");
caps.setCapability("udid", "WTKDU17105005171");
caps.setCapability("deviceName", "Honor");
//com.android.contacts
caps.setCapability("appPackage", "com.android.calculator2");
//.activities.PeopleActivity
caps.setCapability("appActivity", ".Calculator");
caps.setCapability("appWaitActivity", ".Calculator");
caps.setCapability("unicodeKeyboard", "True");
caps.setCapability("resetKeyboard", "True");
caps.setCapability("newCommandTimeout", "15");
caps.setCapability("nosign", "True");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
@Test
public void add() {
driver.findElement(By.xpath("//android.widget.Button[@text='5']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='+']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='8']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='=']")).click();
String value = driver.findElement(By.xpath("//android.widget.EditText[@class='android.widget.EditText']"))
.getAttribute("text");
Assert.assertEquals(value, "13");
}
@Test(enabled = false)
public void sub() {
driver.findElement(By.xpath("//android.widget.Button[@text='1']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='0']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='-']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='8']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='=']")).click();
String value = driver.findElement(By.xpath("//android.widget.EditText[@class='android.widget.EditText']"))
.getAttribute("text");
Assert.assertEquals(value, "2");
}
@Test(enabled = false)
public void mul() {
driver.findElement(By.xpath("//android.widget.Button[@text='5']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='×']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='8']")).click();
driver.findElement(By.xpath("//android.widget.Button[@text='=']")).click();
String value = driver.findElement(By.xpath("//android.widget.EditText[@class='android.widget.EditText']"))
.getAttribute("text");
Assert.assertEquals(value, "40");
}
}