去年,我一直想着要搭建一套持续集成系统。通过 Jenkins 去拉取 GitLab 上的更新,然后自动部署到指定的服务器上。
这个初步的设想,其实是为了实现自动化测试做的准备。
半年过去后,我又回来了。
于是继续研究这套系统,该学习 Selenium 了。
困扰
之前有学习过 Appium,困扰了我很久的问题不是怎么写测试代码,而是:我不知道如何定位元素!
大部分的时间都花在尝试寻找元素去了。
所以这次呢,恰好知道了可以用浏览器去找元素,就先从这里开始学习。记录一下。
通过 XPath 定位
通过 Chrome 浏览器的调试模式,可以定位到页面的每一个元素。
- 按下
F12
按钮,打开调试模式; - 在页面中找到元素之后,点击调试模式下该元素的
Elements
,右键点击Copy
,选择Copy XPath
就可以啦~
但是,通常这样获取到的 xpath 都很长,我一般的做法是,写 xpath 的时候,下尝试使用按钮的 span 去获取,获取不到的时候,才会用上面的方式去拿到 xpath。
其他定位方式
除了通过 XPath 定位之外,还可以通过很多其他的方式,比如 className
, id
, tagName
等…但是很多前端布局没有写 id,className 和 tagName 又是不唯一的,最后我用的多的还是 XPath …
unit test
在组织脚本的时候,用到了 python 的 unittest 模块。unittest.TestCase 类里会执行所有以 test 开头的方法。
setUp 和 tearDown 方法
每一个测试的类,都有 setUp 和 tearDown 方法。但是呢,每次执行 test 方法的时候,都会先 setUp 之后,再 tearDown。
举个例子:
import unittest
from selenium import webdriver
BASE_URL = "https://www.baidu.com/"
class TestBaidu(unittest.TestCase):
def setUp(self):
print("执行 setUp 开始测试")
def tearDown(self):
print("执行 tearDown 结束测试")
print("----------------------")
def test_1(self):
print("测试: test_1")
def test_2(self):
print("测试: test_2")
def test_2(self):
print("测试: test_2")
执行上面的脚本,得到的结果是:
执行 setUp 开始测试
测试: test_1
执行 tearDown 结束测试
----------------------
执行 setUp 开始测试
测试: test_2
执行 tearDown 结束测试
----------------------
执行 setUp 开始测试
测试: test_2
执行 tearDown 结束测试
----------------------
这显然很不符合一般的测试操作习惯,在测试的时候,一般只需要登录一次就可以了。
所以要改一下,把 setUp 改成 setUpClass,并加上 @classmethod
,tearDown 同理:
import unittest
from selenium import webdriver
BASE_URL = "https://www.baidu.com/"
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(self):
print("执行 setUp 开始测试")
@classmethod
def tearDownClass(self):
print("执行 tearDown 结束测试")
print("----------------------")
def test_1(self):
print("测试: test_1")
def test_2(self):
print("测试: test_2")
def test_2(self):
print("测试: test_2")
此时,得到的结果是:
执行 setUp 开始测试
测试: test_1
测试: test_2
测试: test_2
执行 tearDown 结束测试
----------------------
这样,才符合我的预期行为。
使用 Remote 执行测试
由于测试脚本可能会扔到 linux 服务器上运行,没有桌面环境,也没有浏览器,那么这个测试就需要通过 Remote 的方式,在其他机器上启动浏览器进行测试了。
Remote 的使用方法如下:
- 下载 selenium-server-standalone 的 jar 包。很有意思的是,selenium 说要运行这个 jar 包,但并没有给出下载这个 jar 包的地址,只好自己去找了,这里有:https://github.com/adamhooper/selenium-server-standalone-jar
- 在打算运行浏览器的机器上,运行上述 jar 包:
$ java -jar selenium-server-standalone-3.141.59.jar
- 修改脚本代码为:
import unittest from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities class TestBaidu(unittest.TestCase): @classmethod def setUpClass(self): print("执行 setUp 开始测试") # 这里的 command_executor 写上述运行 jar 包的机器地址,端口号默认是 4444,需要加 /wd/hub 路径 self.driver = webdriver.Remote(command_executor="http://192.168.0.xxx:4444/wd/hub", desired_capabilities=DesiredCapabilities.FIREFOX) self.driver.get("http://www.baidu.com/") @classmethod def tearDownClass(self): print("执行 tearDown 结束测试") print("----------------------") def test_1(self): print("执行测试 1")
- 在 Linux 服务器上运行脚本:
$ python test_baidu.py
此时,就会在运行 jar 包的机器上,打开 Firefox 浏览器,执行测试内容。