在学习实际UI自动化测试的时候,首先就需要定位元素,然而定位元素也是最头疼的地方,因为元素各种控件名称的缺失会影响元素的准确定位。
下面针对Android上点击tab的操作来尝试一下多种方式的元素定位方法。
一个tab的组成可能是,一整个tab框,tab框中也可能包含ImageView或TextView,那么其实只要实现点击其中一种都可完成点击tab的操作了。
例子项目中,tab可拆分成元素1(一整个tab框)、元素2(ImageView)和元素3(TextView)。
(一)元素1,如下图:
红框标注的就是那个tab框
在图片左侧是元素1对应的所有属性,这里对定位元素有帮助的主要有type(对应classname)、resource-id(对应id)和xpath(对应xpath)。
由于元素1缺失resource-id,要实现点击这个tab框,这里我们只能通过classname和xpath去定位了。
classname方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_elements_by_class_name(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.support.v7.app.ActionBar.e"</span>).__getitem__(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
因为classname在该界面不唯一,所以加了getitem来区分第几个。
xpath方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_element_by_xpath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"//android.widget.LinearLayout[1]/android.support.v7.app.ActionBar.e[2]"</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
用xpath来定位基本不知道是干啥的,一般都得加备注,不然维护起来很麻烦。
(二)元素2,如下图:
这里红框标注的是tab框中的ImageView,通过点击该元素也可以实现点击tab的操作。
classname方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_elements_by_class_name(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.widget.ImageView"</span>).__getitem__(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
id方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_elements_by_id(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com.boohee.secret:id/iv_icon"</span>).__getitem__(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
xpath方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_element_by_xpath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"//android.widget.LinearLayout[1]/android.support.v7.app.ActionBar.e[2]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]"</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
(三)元素3,如下图:
这里红框标注的是tab框中的TextView,通过点击该元素也可以实现点击tab的操作。
classname方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_elements_by_class_name(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.widget.TextView"</span>).__getitem__(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
id方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_elements_by_id(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com.boohee.secret:id/tv_tab"</span>).__getitem__(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
xpath方法:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_element_by_xpath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"//android.widget.LinearLayout[1]/android.support.v7.app.ActionBar.e[2]/android.widget.RelativeLayout[1]/android.widget.TextView[1]"</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
上面用的是绝对路径,由于元素3的text有值,这边也可以用相对路径来实现:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self.driver.find_element_by_xpath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"//*[@text='超模25']"</span>).click()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
那么看到这里,会发现在Android上classname和id定位时都用到了getitem来区分第几个,而xpath又特别不易理解,维护起来都不太方便。
如果程序中同一个界面上,元素的classname或id是唯一的话,定位元素将会方便很多。