背景介绍
最近在学习自动化测试,现在需要进行一个UI自动化测试的简单实现,具体要求如下:
- 使用unittest
- 针对百度的UI自动化测试,使用selenium
- 完成最少三个测试类
- 使用HTMLtestrunner输出测试报告。
- selenium要做基本的二次封装。
- 测试数据用excle进行管理。
针对以上要求,使用selenium+python的方式实现UI自动化测试,同时使用unittest辅助进行测试用例、测试报告的管理。
环境及使用软件信息
- python 3
- selenium 3.13.0
- xlrd 1.1.0
- chromedriver
- HTMLTestRunner
说明:
selenium/xlrd只需要再python环境下使用pip install 名称即可进行对应的安装。 安装完成后可使用pip list查看自己的安装列表信息。
chromedriver:版本需和自己的chrome浏览器对应, 下载地址:https://chromedriver.storage.googleapis.com/index.html。 作用:对chrome浏览器进行驱动。
HTMLTestRunner:HTMLTestRunner是Python标准库的unittest模块的一个扩展。它生成易于使用的HTML测试报告。 下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html。 下载后放在对应的包中,使用import引入即可使用。
项目结构
项目主要包括一下几个部分:
- cases #存放项目用例 -test01.py #测试用例存放
- datas #存在测试数据
- test.xls #测试数据存放
- drivers #存放项目使用到的驱动
- chromedriver.exe #chrome浏览器驱动文件
- reports #存放生成的测试报告
- unitls #存放第三方库
- HTMLTestRunner.py #用于生成HTML格式的测试报告
- pyselenium.py #对selenium代码的简单封装
- readExcel.py #封装xlrd的excel数据的读取
- webConfig.py #配置使用的浏览器信息
- run.py #代码启动入口
代码实现
unitls包
其中,unitls需要进行初始化,否则,在其他模块进行引用时无法找到。在python中定义包的方法是在对应的文件夹下创建一个__init__.py的文件即可。
readExcel.py
读取excel数据文件
1 import xlrd 2 3 4 # 读取excel文件中对应row和cel数据信息 5 def readExcel(path,row,cel): 6 workBook = xlrd.open_workbook(path) 7 sheet = workBook.sheet_by_name("Sheet1") 8 value = sheet.cell(row,cel).value 9 return value
webConfig.py
配置对应的浏览器
1 # 配置使用的浏览器 2 browers = "Chrome"
pyselenium.py
对selenium的简单封装
1 from selenium import webdriver 2 from selenium.webdriver.common.action_chains import ActionChains 3 4 class pyselenium(): 5 # 初始化浏览器驱动 6 def __init__(self, browers="Chrome"): 7 if browers == "Chrome": 8 driver = webdriver.Chrome(r"./drivers/chromedriver.exe") 9 elif browers =="edge": 10 driver = webdriver.Edge() 11 elif browers == "fireFox": 12 driver = webdriver.Firefox() 13 else: 14 print("浏览器错误,请确认") 15 # raise 16 self.driver = driver 17 18 # 打开对应的url 19 def openUrl(self, url): 20 self.driver.get(url) 21 22 # 最大化浏览器窗口 23 def maxWindow(self): 24 self.driver.maximize_window() 25 26 # 通过不同的方式查找界面元素 27 def findElement(self,by,value): 28 if(by == "id"): 29 element = self.driver.find_element_by_id(value) 30 return element 31 elif(by == "name"): 32 element = self.driver.find_element_by_name(value) 33 return element 34 elif(by == "xpath"): 35 element = self.driver.find_element_by_xpath(value) 36 return element 37 elif(by == "classname"): 38 element = self.driver.find_element_by_class_name(value) 39 return element 40 elif(by == "css"): 41 element = self.driver.find_element_by_css_selector(value) 42 return element 43 elif(by == "link_text"): 44 element = self.driver.find_element_by_link_text(value) 45 return element 46 else: 47 print("无对应方法,请检查") 48 return None 49 50 # 给指定元素发送值 51 def sendKeys(self,by,value,keys): 52 element = self.findElement(by,value) 53 element.send_keys(keys) 54 55 # 点击页面元素 56 def clinkElement(self,by,value): 57 element = self.findElement(by,value) 58 element.click() 59 60 # 鼠标悬停 61 def hover(self,by,value): 62 element = self.findElement(by,value) 63 ActionChains(self.driver).move_to_element(element).perform() 64 65 # 获取标题 66 def getTitle(self): 67 return self.driver.title 68 69 # 退出浏览器 70 def quit(self): 71 self.driver.quit()
测试用例管理(cases)
test01.py,包括3个测试用例:
1 import unittest,time 2 from units import pyselenium 3 from units import readExcel,webConfig 4 5 class baiduTest(unittest.TestCase): 6 @classmethod 7 def tearDownClass(cls): 8 cls.driver.quit() 9 10 @classmethod 11 def setUpClass(cls): 12 cls.driver = pyselenium.pyselenium(webConfig.browers) 13 14 # 百度selenium,并判断返回结果title 15 def testBaidu(self): 16 # 打开百度首页 17 url = "http://www.baidu.com" 18 # self.driver.maxWindow() 19 self.driver.openUrl(url) 20 # 从excel文件中读取并输入搜索条件 21 sendData = readExcel.readExcel("./datas/test.xls",0,0) 22 self.driver.sendKeys(by="xpath",value="//*[@id='kw']",keys=sendData) 23 # 点击搜索按钮 24 self.driver.clinkElement(by="xpath",value="//*[@id='su']") 25 time.sleep(3) 26 title = self.driver.getTitle() 27 # 使用断言验证搜索后title和预期是否相等 28 self.assertEqual(title,"selenium_百度搜索") 29 30 # 百度登陆,并判断是否正常登陆系统 31 def testLogin(self): 32 url = "http://www.baidu.com" 33 self.driver.openUrl(url) 34 time.sleep(3) 35 # 进入登录页面 36 self.driver.clinkElement(by="xpath",value="//*[@id='u1']/a[7]") 37 time.sleep(3) 38 self.driver.clinkElement(by="xpath",value="//*[@id='TANGRAM__PSP_10__footerULoginBtn']") 39 # 从excel文件中读取并输入用户名密码 40 userName = readExcel.readExcel("./datas/test.xls",1,0) 41 password = readExcel.readExcel("./datas/test.xls",1,1) 42 self.driver.sendKeys(by="name",value="userName",keys=userName) 43 self.driver.sendKeys(by="name",value="password",keys=password) 44 print("username:"+userName+",password:"+password) 45 self.driver.clinkElement(by="id",value="TANGRAM__PSP_10__submit") 46 time.sleep(3) 47 48 # 检查是否存在用户退出按钮,存在,登录成功,否则登录失败 49 self.driver.hover(by='xpath',value='//*[@id="s_username_top"]/span') 50 close = self.driver.findElement(by='xpath',value='//*[@id="s_user_name_menu"]/div/a[4]') 51 print(close) 52 if close != None: 53 self.assertEqual(1,1) 54 else: 55 self.assertEqual(1,0) 56 time.sleep(3) 57 58 def testLogout(self): 59 url = "http://www.baidu.com" 60 self.driver.openUrl(url) 61 time.sleep(3) 62 self.driver.hover(by='xpath',value='//*[@id="s_username_top"]/span') 63 self.driver.clinkElement(by='xpath',value='//*[@id="s_user_name_menu"]/div/a[4]') 64 time.sleep(3) 65 self.driver.clinkElement(by='xpath',value='//*[@id="tip_con_wrap"]/div[3]/a[3]') 66 time.sleep(3) 67 element = self.driver.findElement(by="xpath",value="//*[@id='u1']/a[7]") 68 self.assertEqual("登录",element.text) 69 time.sleep(3)
测试用例中的相关说明:
- setup():每个测试函数运行前运行
- teardown():每个测试函数运行完后执行
- setUpClass():必须使用@classmethod 装饰器,所有test运行前运行一次
- tearDownClass():必须使用@classmethod装饰器,所有test运行完后运行一次
测试用例执行
run.py,使用HTMLTestRunner执行测试用例,并生成测试报告。
1 from units import HTMLTestRunner 2 import unittest 3 import time 4 5 # 构建测试用例集,设定对应的测试用例存放文件以及匹配方式 6 suite = unittest.defaultTestLoader.discover(start_dir='./cases/', pattern="test*.py") 7 8 now = time.strftime('%Y-%m-%d-%H-%M-%S-') 9 reportName = "./reports/%s测试报告.html" % now 10 11 with open(reportName, "wb") as f: 12 runner = HTMLTestRunner.HTMLTestRunner(stream=f, verbosity=2, title="测试报告", description="执行人:阿绿") 13 # 执行测试用例集 14 runner.run(suite)
执行run.py文件,查看reports文件夹下,生成对应的测试报告文件,打开文件即可查看对应的测试报告信息。
遇到的问题及解决过程
用例执行时无法找到对应的用例
现象:编写了正确的用例目录,但是使用unittest进行对应的用例执行时,用例执行个数为0,原因:再uniittest中,用例名称中不能包含【-】,否则会发生兼容性问题。去除用例文件名称中的标记【-】后,问题解决。
无法定位URL无效
执行用例时报错:
1 unhandled inspector error: {"code":-32000,"message":"Cannot navigate to invalid URL"}
这个错误的意思是:“未经处理的检查员错误:{“代码”:32000,“消息”:“无法定位到URL无效”}”
全部代码如下:
1 import unittest,time 2 from units import pyselenium 3 from units import readExcel,webConfig 4 5 class baiduTest(unittest.TestCase): 6 @classmethod 7 def tearDownClass(cls): 8 cls.driver.quit() 9 10 @classmethod 11 def setUpClass(cls): 12 cls.driver = pyselenium.pyselenium(webConfig.browers) 13 14 # 百度selenium,并判断返回结果title 15 def testBaidu(self): 16 # 打开百度首页 17 url = "http://www.baidu.com" 18 # self.driver.maxWindow() 19 self.driver.openUrl(url) 20 # 从excel文件中读取并输入搜索条件 21 sendData = readExcel.readExcel("./datas/test.xls",0,0) 22 self.driver.sendKeys(by="xpath",value="//*[@id='kw']",keys=sendData) 23 # 点击搜索按钮 24 self.driver.clinkElement(by="xpath",value="//*[@id='su']") 25 time.sleep(3) 26 title = self.driver.getTitle() 27 # 使用断言验证搜索后title和预期是否相等 28 self.assertEqual(title,"selenium_百度搜索")
解决办法:将17行中的url修改为:http://www.baidu.com即可。
驱动版本不对应
报错信息如下:
1 selenium.common.exceptions.WebDriverException: Message: unknown error: Runtime.executionContextCreated has invalid 'context': {"auxData":{"frameId":"DBC672A35E293863B4120F2CB4C90D48","isDefault":true},"id":1,"name":"","origin":"://"} 2 (Session info: chrome=69.0.3497.100) 3 (Driver info: chromedriver=2.9.248315,platform=Windows NT 6.3 x86_64)
原因:浏览器驱动不存在或者驱动不适用当前版本
解决办法:到chrome浏览器驱动下载地址中(https://chromedriver.storage.googleapis.com/index.html)下载对应版本的驱动,对应替换即可。