android app日志分析,Appium的代码实例及日志分析

本文内容:Android及IOS基于TestNG的代码结构示例,

常用的元素定位方式的介绍

部分项目中使用的功能代码示例

Appium日志的具体分析

部分需要理解的概念

Android示例代码(TestNG):public class AndroidTest {

protected AndroidDriver driver;

URL url = new URL("http://127.0.0.1:4723/wd/hub");

@BeforeSuite

public void setUp() throws Exception {

DesiredCapabilities capabilities = new DesiredCapabilities();

capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "AndroidPhone");

capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.example.dev");

capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".MainActivity");

capabilities.setCapability(MobileCapabilityType.NO_RESET, true);

......

driver = new AndroidDriver<>(url, capabilities);

}

@AfterSuite

public void tearDown() throws Exception {

if (driver != null) {

driver.quit();

}

}

@Test

public void test_001(){}//Test Case One

@Test

public void test_002(){}//Test Case Two

}

IOS示例代码(TestNG):public abstract class IOSTest {

protected IOSDriver driver;

URL url = new URL("http://127.0.0.1:4723/wd/hub");

@BeforeSuite

public void setUp() throws Exception {

DesiredCapabilities capabilities = new DesiredCapabilities();

capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");

capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "10.3");

capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "My iPhone 6");

capabilities.setCapability(MobileCapabilityType.UDID, "c4ef2cbc8a1b39123838a8ad9fdea45547e44c20");

capabilities.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.example.dev");

......

driver = new IOSDriver<>(url, capabilities);

}

}

常用的元素定位方式:

Android:By.idView的id,最好用com.hello.uat:id/et_reg_mobile

android:id/button1

button1

By.classnameView的类型名android.widget.TextView

android.widget.Button

By.xpath根据element的属性及DOM层级查找,比较不稳定By.xpath(".//*[@text='Title']")根据text属性查找,

一般对于索引不确定的元素采用

MobileBy.

AndroidUIAutomatorAndroid自带UIAutomator框架的定位方式

IOS:MobileBy.

AccessibilityId组件的AccessibilityId,最好用一般同组件的name属性,使用Inspector获得

By.classname组件的类型名XCUIElementTypeStaticText

XCUIElementTypeButton

By.xpath根据element的属性及DOM层级查找,比较不稳定。By.xpath(".//*[@name='Title']")根据name属性查找,一般都可以用AccessibilityId替代,因为name和AccessibilityId一般是一样的

更精准可以带上classname:

//XCUIElementTypeStaticText[@name="Hello"]

一般对于索引不确定又没有AccessibilityId的元素采用

MobileBy.

IosUIAutomationIOS自带框架UIAutomation的定位方式

AccessibilityId

appium移除了在Selenium上常用的name和tagname定位方式

IOS上表示Accessibility Identifier,通常和Name、Label属性相同

Android上表示content description

交互操作

MobileElement:交互的对象,对应于Android中的一个View对象

点击:element.click();

输入:element.sendKeys("text");

滑动:driver.swipe()

点击:driver.tap();

等待方式:

//隐式等待

//全局设定查找元素时的等待时间,找不到会尝试10秒内间隔查找,找到了继续

//这里设定的值对driver的整个生命周期起作用,从现在开始到下次修改,每次查找都是10秒。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

//显式等待

//仅仅这次,指明最多等待5秒,指明结束条件为找到元素id=bt_next。超时抛出TimeoutException。

WebElement e = new WebDriverWait(driver, 5).until(

ExpectedConditions.presenceOfElementLocated(By.id("bt_next")));

//强行等待

//线程直接暂停,适合于单纯的等待。不查找元素

Thread.sleep(3000)

DesiredCapabilities

这是一个key-value的集合,用于告诉服务器建立连接的设备信息,不同平台有所不同。appium支持许多的属性设置,可以到官网做个全面的了解。

MobileCapabilityType:不同平台共用

AndroidMobileCapabilityType:Android专用

IOSMobileCapabilityType:IOS专用

Android一般至少需要:

1、platformName

2、platformVersion

3、deviceName

4、appPackage

5、appActivity

IOS一般至少需要:

1、platformName

2、platformVersion

3、deviceName

4、udid

5、bundleId

部分代码示例//对于弹出的权限对话框,如果找到Allow按钮则一直点击Allow。

protected void grantPermissionIfPrompt() {

int count = 0;//at most five times grant

MobileElement allowBtn = findElement(By.id(ConstConfig.ALLOW_BUTTON));

while (allowBtn != null && count++ 

allowBtn.click();

allowBtn = findElement(By.id(ConstConfig.ALLOW_BUTTON));

}

}

//向上滑动列表,直到找到目标元素

static public MobileElement scrollDownUnitFound(AndroidDriver driver, String content) throws Exception {

int width = driver.manage().window().getSize().getWidth();

int height = driver.manage().window().getSize().getHeight();

int count = 0;

String xpathStr = createXpathDesc(content);

do {

if (driver.findElementsByXPath(xpathStr).size() > 0) {

//in case of the element is still hiding, or the element is showing only a little part of it.

driver.swipe(width / 2, height / 2, width / 2, height / 3, 600);

Thread.sleep(1000);//sleep 1 second to avoid getting the element in the wrong position.

return driver.findElementsByXPath(xpathStr).get(0);

}

driver.swipe(width / 2, height / 2, width / 2, height / 4, 600);

count++;

} while (count 

return null;

}

//生成xpath字符串

static public String createXpathDesc(String content) {

return ".//*[@text='" + content + "']";

}

//滑动找到元素,并点击其左侧的CheckBox。CheckBox没有id,也不适合用classname,因为不知道是第几个,只能借助相邻元素坐标偏移。

MobileElement el = AndroidHelper.scrollDownUnitFound(driver, voteTarget);

if (el != null) {//find the checkbox to the left of the founded target.

int targetX = el.getLocation().getX() - 20;

int targetY = el.getLocation().getY() + 1;//event +0 is working

System.out.println("coordinates:x = " + targetX + "    y = " + targetY);

driver.tap(1, targetX, targetY, 300);

}

日志分析(Appium on AWS Device Farm):

Appium是Client/Server结构的,所以每一次操作都是以Client向Server发送http请求开始,以Server向Client发送http响应结束。查阅日志可以按这个规律过滤不必要的信息。

Android日志分析:

driver.findElement(By.id("compose_button")).click();

(Adnroid)findElement操作日志:2017-09-19 04:06:27:278 - [HTTP] --> POST /wd/hub/session/acfa31ae-321f-4ee1-a34b-294667393f8f/element {"using":"id","value":"compose_button"}

2017-09-19 04:06:27:278 - [debug] [MJSONWP] Calling AppiumDriver.findElement() with args: ["id","compose_button","acfa31ae-321f-4ee1-a34b-294667393f8f"]

2017-09-19 04:06:27:279 - [debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator

2017-09-19 04:06:27:279 - [debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator

2017-09-19 04:06:27:279 - [debug] [BaseDriver] Waiting up to 3000 ms for condition

2017-09-19 04:06:27:280 - [debug] [AndroidBootstrap] Sending command to android: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"compose_button","context":"","multiple":false}}

2017-09-19 04:06:27:310 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"compose_button","context":"","multiple":false}}

2017-09-19 04:06:27:310 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION

2017-09-19 04:06:27:310 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find

2017-09-19 04:06:27:311 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding 'compose_button' using 'ID' with the contextId: '' multiple: false

2017-09-19 04:06:27:311 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.example.hello:id/compose_button]

2017-09-19 04:06:27:329 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {"status":0,"value":{"ELEMENT":"9"}}

2017-09-19 04:06:27:330 - [debug] [AndroidBootstrap] Received command result from bootstrap

2017-09-19 04:06:27:330 - [debug] [MJSONWP] Responding to client with driver.findElement() result: {"ELEMENT":"9"}

2017-09-19 04:06:27:344 - [HTTP] 

(Android)click操作日志:2017-09-19 04:06:27:348 - [HTTP] --> POST /wd/hub/session/acfa31ae-321f-4ee1-a34b-294667393f8f/element/9/click {"id":"9"}

2017-09-19 04:06:27:348 - [debug] [MJSONWP] Calling AppiumDriver.click() with args: ["9","acfa31ae-321f-4ee1-a34b-294667393f8f"]

2017-09-19 04:06:27:359 - [debug] [AndroidBootstrap] Sending command to android: {"cmd":"action","action":"element:click","params":{"elementId":"9"}}

2017-09-19 04:06:27:375 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"element:click","params":{"elementId":"9"}}

2017-09-19 04:06:27:391 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION

2017-09-19 04:06:27:391 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: click

2017-09-19 04:06:27:876 - [debug] [AndroidBootstrap] Received command result from bootstrap

2017-09-19 04:06:27:876 - [debug] [MJSONWP] Responding to client with driver.click() result: true

2017-09-19 04:06:27:880 - [HTTP] 

IOS日志分析:

driver.findByAccessibilityId("Compose").click();

(IOS)findElement操作日志:2017-09-19 07:19:36:259 - [HTTP] --> POST /wd/hub/session/bbb16560-a4c7-43fc-a5d0-dea9057dff93/element {"using":"accessibility id","value":"Compose"}

2017-09-19 07:19:36:259 - [debug] [MJSONWP] Calling AppiumDriver.findElement() with args: ["accessibility id","Compose","bbb16560-a4c7-43fc-a5d0-dea9057dff93"]

2017-09-19 07:19:36:260 - [debug] [XCUITest] Executing command 'findElement'

2017-09-19 07:19:36:260 - [debug] [BaseDriver] Valid locator strategies for this request: xpath, id, name, class name, -ios predicate string, -ios class chain, accessibility id

2017-09-19 07:19:36:260 - [debug] [BaseDriver] Waiting up to 3000 ms for condition

2017-09-19 07:19:36:261 - [debug] [JSONWP Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8100/session/3FAA9ECD-8EE9-49BC-B1F9-010B03B9821B/element] with body: {"using":"accessibility id","value":"Compose"}

2017-09-19 07:19:37:826 - [debug] [JSONWP Proxy] Got response with status 200: {"value":{"ELEMENT":"E56F3927-08E6-4ECD-B3E4-05F30198FA6A","type":"XCUIElementTypeButton","label":"Compose"},"sessionId":"3FAA9ECD-8EE9-49BC-B1F9-010B03B9821B","status":0}

2017-09-19 07:19:37:829 - [debug] [MJSONWP] Responding to client with driver.findElement() result: {"ELEMENT":"E56F3927-08E6-4ECD-B3E4-05F30198FA6A","type":"XCUIElementTypeButton","label":"Compose"}

2017-09-19 07:19:37:843 - [HTTP] 

(IOS)click操作日志:2017-09-19 07:19:37:869 - [HTTP] --> POST /wd/hub/session/bbb16560-a4c7-43fc-a5d0-dea9057dff93/element/E56F3927-08E6-4ECD-B3E4-05F30198FA6A/click {"id":"E56F3927-08E6-4ECD-B3E4-05F30198FA6A"}

2017-09-19 07:19:37:870 - [MJSONWP] Driver proxy active, passing request on via HTTP proxy

2017-09-19 07:19:37:870 - [debug] [XCUITest] Executing command 'proxyReqRes'

2017-09-19 07:19:37:870 - [debug] [JSONWP Proxy] Proxying [POST /wd/hub/session/bbb16560-a4c7-43fc-a5d0-dea9057dff93/element/E56F3927-08E6-4ECD-B3E4-05F30198FA6A/click] to [POST http://127.0.0.1:8100/session/3FAA9ECD-8EE9-49BC-B1F9-010B03B9821B/element/E56F3927-08E6-4ECD-B3E4-05F30198FA6A/click] with body: {"id":"E56F3927-08E6-4ECD-B3E4-05F30198FA6A"}

2017-09-19 07:19:39:829 - [debug] [JSONWP Proxy] Got response with status 200: {"status":0,"id":"E56F3927-08E6-4ECD-B3E4-05F30198FA6A","value":"","sessionId":"3FAA9ECD-8EE9-49BC-B1F9-010B03B9821B"}

2017-09-19 07:19:39:829 - [JSONWP Proxy] Replacing sessionId 3FAA9ECD-8EE9-49BC-B1F9-010B03B9821B with bbb16560-a4c7-43fc-a5d0-dea9057dff93

2017-09-19 07:19:39:834 - [HTTP] 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值