×
广告

WebDriver使用入门

96
何小有
2017.12.29 14:31* 字数 1359

WD.py是一个Python WebDriver客户端,实现了WebDriver协议中的大部分API。 它最初是为Macaca(一个Node.js驱动的WebDriver服务器)而设计的,但也可以应用于WebDriver服务器的其他实现,比如Selenium,Appium等。

自动化测试

查找元素

WebDriver的查找元素命令允许分别查找单个元素和元素集合,定位策略如下:

  • 文本
  • id
  • XPath
  • 链接文本
  • 部分链接文本
  • 标签名
  • 类名
  • CSS选择器

找到元素的基本方法是element(),例如查找id为“login”的元素:

driver.element('id', 'login')

但是在大多数情况下,不需要使用这个基本的方法,为了方便起见,有很多扩展方法。

文本

例如,查找页面上name属性为“Login failed!”的元素:

driver.element_by_name('Login failed!')

id

例如,查找id为“login”的元素:

driver.element_by_id('login')

XPath

XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以可以使用XPath的语法来定位页面元素。这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。

例如,查找页面上id为“finding-elements-to-interact”的元素下的第4个table元素:

driver.element_by_xpath('//*[@id="finding-elements-to-interact"]/table[4]')

链接文本

这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。

例如,查找页面上文字为“macaca”的超文本链接:

driver.element_by_link_text('macaca')

部分链接文本

这个方法是上一个方法的扩展,当不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。

例如,查找页面上部分文字为“maca”的超文本链接:

driver.element_by_partial_link_text('maca')

标签名

该方法可以通过元素的标签名称来查找元素,需要注意的是,这个方法搜索到的元素通常不止一个。

例如,查找页面上的“ input”标签:

driver.element_by_tag_name('input')

此外,WebDriver上的所有元素方法都可以在WebElement上使用,也就是从当前Web元素中查找元素:

web_element.element_by_id('ss')

类名

一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,这个方法可以利用元素的css样式表所引用的伪类名称来进行元素查找。

例如,查找页面上className属性为“btn”的元素:

driver.element_by_class_name('btn')

CSS选择器

这种元素定位方式跟XPath比较类似,但执行速度较快,所以功能也是蛮强大的。

例如,查找页面上样式表为“.btn”的元素:

driver.element_by_css_selector('.btn')

异常处理

当没有找到元素时,会引发WebDriverException异常。为了避免这种情况,可是使用element_if_exists方法,如果元素存在,则返回True,否则返回False,例如:

driver.element_by_id_if_exists('login')

也可以使用element_or_none方法,如果元素存在,则返回元素,否则返回None,例如:

driver.element_by_id_or_none('login')

此外,还有wait_for方法等待元素满足给定条件,默认等待10秒,每个间隔1秒,断言器函数默认为asserters.is_displayed,例如:

driver.wait_for_element_by_id('login')

按键输入

当需要完成一个输入字段的操作时,可以将一系列的按键行为发送给一个元素:

driver.web_element.send_keys('123456')

send_keys方法也接受一个数组,这在发送特殊键(不是文本的按键)时非常有用:

driver.web_element.send_keys([1, 2, 3, 4, 5, 6])

PC按键映射:

映射 按键 键码
\uE002 HELP 259 (0x00000103)
\uE003 BACK_SPACE 67 (0x00000043)
\uE004 TAB 61 (0x0000003d)
\uE005 CLEAR 28 (0x0000001c)
\uE007 ENTER 66 (0x00000042)
\uE008 SHIFT 59 (0x0000003b)
\uE009 CONTROL 113 (0x00000071)
\uE00A ALT 57 (0x00000039)
\uE00B PAUSE 121 (0x00000079)
\uE00C ESCAPE 111 (0x0000006f)
\uE00E PAGE_UP 92 (0x0000005c)
\uE00F PAGE_DOWN 93 (0x0000005d)
\uE010 END 123 (0x0000007b)
\uE011 HOME 122 (0x0000007a)
\uE012 ARROW_LEFT 21 (0x00000015)
\uE013 ARROW_UP 19 (0x00000013)
\uE014 ARROW_RIGHT 22 (0x00000016)
\uE015 ARROW_DOWN 20 (0x00000014)
\uE016 INSERT 124 (0x0000007c)
\uE017 DELETE 112 (0x00000070)
\uE031 F1 131 (0x00000083)
\uE032 F2 132 (0x00000084)
\uE033 F3 133 (0x00000085)
\uE034 F4 134 (0x00000086)
\uE035 F5 135 (0x00000087)
\uE036 F6 136 (0x00000088)
\uE037 F7 137 (0x00000089)
\uE038 F8 138 (0x0000008a)
\uE039 F9 139 (0x0000008b)
\uE03A F10 140 (0x0000008c)
\uE03B F11 141 (0x0000008d)
\uE03C F12 142 (0x0000008e)
\uE03D META 117 (0x00000075)

Android按键映射:

映射 按键 键码
\uE101 POWER 电源键 26 (0x0000001a)
\uE102 VOLUME_UP 音量加 24 (0x00000018)
\uE103 VOLUME_DOWN 音量减 25 (0x00000019)
\uE104 VOLUME_MUTE 禁音 164 (0x000000a4)
\uE105 HOME_SCREEN HOME键 3 (0x00000003)
\uE106 BACK BACK键 4 (0x00000004)
\uE107 MENU MENU键 82 (0x00000052)
\uE108 CAMERA 拍照键 27 (0x0000001b)
\uE109 CALL 电话键 5 (0x00000005)
\uE10A END_CALL 结束电话键 6 (0x00000006)
\uE10B SEARCH 搜索键 84 (0x00000054)
\uE10C DPAD_LEFT 导航左键 21 (0x00000015)
\uE10D DPAD_UP 导航上键 19 (0x00000013)
\uE10E DPAD_RIGHT 导航右键 22 (0x00000016)
\uE10F DPAD_DOWN 导航下键 20 (0x00000014)
\uE110 DPAD_CENTER 导航确定键 23 (0x00000017)

iOS按键映射:

映射 按键
\uE105 HOME_SCREEN HOME键

使用数组发送特殊键非常方便:

driver.web_element.send_keys([1, DELETE, 1, 2, 3, 4, 5, 6])

屏幕快照

截图时可以返回截图的base64编码字符串:

base64_str = driver.take_screenshot()

或者保存截图到给定的路径:

driver.save_screenshot('./screen.png')

save_screenshot方法具有可选的第二个参数来决定是否由于某种原因无法保存到文件系统时忽略IOError。例如,没有读写权限时,忽略异常信息:

driver.save_screenshot('/etc/screen.png', True)

切换环境

对于移动端测试,可能需要在Native(原生)和Webview(H5)之间切换环境,首先获取现有的环境:

ctxs = driver.contexts
print(ctxs) # ['NATIVE', 'WEBVIEW_1', 'WEBVIEW_2']

然后切换到指定的环境:

driver.context = 'WEBVIEW_1'
print(driver.context) # WEBVIEW_1

执行JS片段

在一些复杂的情况下,可能需要在页面中插入一段JavaScript代码,并得到想要的任何东西。可以在脚本中使用arguments来表示脚本之后的索引参数。

script = 'return document.querySelector(".btn").tagName === arguments[0]'
args = ['div']
result = driver.execute_script(script, *args)

上面的脚本等于JavaScript中的IIFE:

function () {
  return document.querySelector(".btn").tagName === "div"
}()

WebElement方法

WebElement的实例方法主要与行为元素有关,比如点击元素、获取标签名或元素的内部文本。WebElement实例是通过查找元素命令返回的,例如通过id检索元素:

web_element = driver.element_by_id('login')
print(type(web_element) == WebElement) # True

例如点击元素:

web_element.click()

例如获取元素的标签名称:

tag_name = web_element.tag_name

例如获取元素的内部文本:

text = web_element.text

编码风格

建议使用官方推荐的两种编码风格,第一种是使用额外的括号:

(
    driver
        .get('https://www.google.com')
        .element_by_id('login')
        .click()
)

第二种是使用反斜杠:

driver                             \
    .get('https://www.google.com') \
    .element_by_id('login')        \
    .click()
测试工具及技术
Web note ad 1