DesiredCapabilities capabilities = new DesiredCapabilities ();
capabilities.setCapability (MobileCapabilityType.DEVICE_NAME, deviceName);
capabilities.setCapability (MobileCapabilityType.PLATFORM_NAME, platformName);
capabilities.setCapability (MobileCapabilityType.PLATFORM_VERSION, platformVersion);
capabilities.setCapability (MobileCapabilityType.APP, apkPath);
capabilities.setCapability (AndroidMobileCapabilityType.APP_PACKAGE, appPackage);
capabilities.setCapability (AndroidMobileCapabilityType.APP_ACTIVITY, appActivity);
capabilities.setCapability (MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
这里我使用的是 TestNG 中的Parameters
注释来配置参数.
TestNG 又是什么鬼? 简单来说TestNG是java的一个测试框架,类似JUnit但功能更加强大,使用也方便.
TestNG
利用TestNg的一些注释,做准备化和收尾操作.
上面的setUp
方法我就使用了BeforeClass
和Parameters
这两种注释.
@BeforeClass
@Parameters({“driverName”, “url”, “deviceName”, “platformName”, “platformVersion”, “apkPath”, “appPackage”, “appActivity”})
public void setUp(String driverName, String url, String deviceName,
String platformName, String platformVersion, String apkPath,
String appPackage, String appActivity) throws Exception {
log.i (TAG, “BeforeClass”);
driver = setRemoteDriver (driverName, url, deviceName, platformName, platformVersion, apkPath, appPackage, appActivity);
actions = ElementActions.getInstance ().init (driver);
assertActions = actions.getAssertActions ();
Screenshot.getInstance ().init (driver);
prepare ();
}
同样在在AfterClass
后,进行了driver
的退出.
正常情况下我们写测试用例是下面这种情况:
一个TestClass
中包含多个TestMethod
.如果每个TestMethod
都相互独立,需要重新运行APP显然非常耗时,所以这里我将每一个TestClass
相互独立,而其中的TestMethod
又相互依赖,执行顺序通过TestNG
的XML来控制.如下:
但是有些情况如果需要TestMethod
也相互独立的话,可以利用AfterMethod
注释.
@AfterMethod
public void afterMethod() {
driver.resetApp ();
}
编写用例
查找元素
定位方式
查找元素可以通过很多方法(可以通过UIAutomatorViewer
获取页面的id,name等信息):
- id
- name
- className
- xpath
- uiautomator
高级定位
- 用
xpath
查找登录按钮:
by.xpath (“//button[@name=‘login’]”)
- 用
uiautomator
的API滚动查找:
String rule = “new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().textContains(”" + locator.value + “”))"
WebElement cl = driver.findElementByAndroidUIAutomator(rule));
其实就是用如果用uiautomator来写:
new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().textContains(value));
元素管理
为了让测试用例能够方便复用,简化写用例的时间,必要的封装是不可少的. 利用 Page Object 模式将页面上的元素进行封装.这样所有 Test 只需要简单的控制页面元素即可.
- 可以使用yaml文件进行管理页面元素:
然后在BasePage中将yaml解析封装成Locator
对象.并保存到集合.
这样所有的PageObject都可以通过下面方法来定位元素.
protected Locator getLocator(String locatorName) {
checkNotNull (locatorName);
Page page = getPage ();
List locators = page.locators;
for(Locator locator : locators) {
if (locatorName.equals (locator.name)) {
return locator;
}
}
return null;
}
public Locator 请输入手机号 = getLocator (“请输入手机号”);
public Locator 请输入验证码 = getLocator (“请输入验证码”);
public Locator 发送验证码 = getLocator (“发送验证码”);
~TODO: 用工具生成对应page类~
之所这么做是可以在用的时候直接通过IDE提示有哪些控件,但是写上述代码缺都是无聊的操作,所有我用了 freemarker 自动解析yaml来生成对应Page类,如下:
Map<String, Object> input = new HashMap<String, Object> ();
input.put (“pageName”, page.pageName);
List genLocators = new ArrayList<> ();
List locators = page.locators;
for(int i = 0; i < locators.size (); i++) {
System.out.println (“生成Locator:” + locators.get (i).name);
genLocators.add (new LocatorObject (locators.get (i).name, locators.get (i).name));
}
input.put (“locators”, genLocators);
Template template = cfg.getTemplate (“page-temp.ftl”);
Writer fileWriter = new FileWriter (new File (path, page.pageName + “.java”));
try {
template.process (input, fileWriter);
} finally {
fileWriter.close ();
}
如果不会用 freemarker
的可以搜索下相关资料.
元素交互
将交互事件,封装在ElementActions
中.使用起来非常简单:
actions.text (loginPage.请输入手机号, phone);
actions.click (loginPage.发送验证码);
actions.text (loginPage.请输入验证码, pwd);
actions.click (loginPage.登录);
常用的交互事件:单击,连击,上下左右滑动,后退,输入文本等等.
上面元素定位其实只是封装Locator,并没有真正的查找元素,查找元素实际上是在ElementActions
中处理的.由于应用经常处理网络请求,控件有时候需要过段时间才可见,所以在查找控件时候需要给予一定的时间.
WebElement element;
try {
element = (new WebDriverWait (mDriver, locator.timeOutInSeconds)).until (
new ExpectedCondition () {
@Override
public WebElement apply(WebDriver driver) {
List elements = getElement (locator);
if (elements.size () != 0) {
return elements.get (0);
}
return null;
}
});
} catch (NoSuchElementException | TimeoutException e) {
log.e (TAG, “超时[%4
d
秒
]
,
找不到元素
:
[
d秒],找不到元素:[%1
d秒],找不到元素:[s] , [By.%2
s
:
s : %3
s:s]”, locator.name, locator.type, locator.value, locator.timeOutInSeconds);
throw e;
}
断言
同样为了使用方便讲常用的断言封装,如Toast验证等.
public void validatesToast(final String msg) {
checkNotNull (msg);
final WebDriverWait wait = new WebDriverWait (mDriver, 10);
assertNotNull (wait.until (ExpectedConditions
.presenceOfElementLocated (By.xpath (String.format (“//*[@text=‘%s’]”, msg)))));
}
测试报告
测试报告可以直观的展示测试的成功率,截图等信息.这里选择extentreports做为测试报告的框架.
最终效果:
踩坑
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
其实要轻松掌握很简单,要点就两个:
- 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
- 多练。 (视频优势是互动感强,容易集中注意力)
你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。
阿里P7Android高级教程
下面资料部分截图,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。
附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。
Android核心高级技术PDF资料,BAT大厂面试真题解析;
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
…(img-uEraiTgJ-1712034944976)]
附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。
Android核心高级技术PDF资料,BAT大厂面试真题解析;
[外链图片转存中…(img-LlxDZ8Iz-1712034944976)]