在dos命令中输入python,在dos命令中输入pip Pip是Python官方推荐的包管理工具,提供了对Python包的查找、下载、安装、卸载的功能,属于python的一部分。 Python3.0以上的版本都是自带pip的,无需再次下载安装。 如需升级pip,有一下两种方式,命令行中输入以下命令: python -m pip install —upgrade pip 或 easy_install.exe pip,即可升级pip 使用pip安装第三方库,命令行中执行: pip install xxx xx 是我们需要安装库的名称。比如安装requests库 UI自动化搭建手册(配置第三方自动化测试工具):
UI自动化中python语法:首先通过网页F12定位到我们需要操作的元素的源代码(通过元素的属性值来定位元素) 1. from 第三方库名import驱动名从第三方库引入库里的驱动模块 from selenium import webdriverimport time
29. 单元测试框架及测试集合 ”'单元测’’’unittest 1.类名随便起,类要继承unittest.TestCase,name前后的__下划线是两个 2.测试用例必须以test开头,测试用例的执行顺序是按照26个英文字母以及阿拉伯数字 3.在执行整个脚本的时候要把光标放在if __name上边否则是以单元测试框架的形式运行的 4.鼠标放在类的:后边代表以单元测试框架形式运行所有的测试用例 5.setUp代表预操作(即一部分需要重复利用的代码,前置条件那些代码) 6.tearDown代表最后一步操作,一般都是关闭浏览器”’ ’’’ort unittestclass suit(unittest.TestCase): def setUp(self): print("测试开始"“ ”def test_001(self): print("执行tes“001--case— ”def test_002(self): print("执行tes“002--case— ”def test_003(self): print("执行tes“003--case— ”def tearDown(self): print("测试结束"“if ”_name__ =="__mai“__": ” '''执行类'’’的用例''' ’ # unittest.main() #使用主函数执行所有的测试用例 '''通过建'’’执行类中的部分用例''' ’ su=unittest.TestSuite() #建立测试集合 su.addTest(suit('test_'01')) #向测试集合里添加suit类中对应的第一条测试用例 su.addTest(suit('test_'03')) ’ runner=unittest.TextTestRunner() #生成执行器 runner.run(su) #执行测试集合 30. 以测试报告形式来执行测试集合 #引用unittest类和time类import unittest,time#从HTMLTestRunner文件中引入HTMLTestRunner类from HTMLTestRunner import HTMLTestRunnerclass suit(unittest.TestCase): def setUp(self): print("测试开始"“ ”def test_001(self): print("执行tes“001--case— ”def test_002(self): print("执行tes“002--case— ”def test_003(self): print("执行tes“003--case— ”def tearDown(self): print("测试结束"“if ”_name__ =="__mai“__": ” su=unittest.TestSuite() #建立测试集合 su.addTest(suit('test_'01')) #向测试集合里添加suit类中对应的第一条测试用例 su.addTest(suit('test_'03')) ’ #description描述 stream数据流 w(写入方式)b(二进制),wb即以二进制方式写入 now=time.strftime('%Y-%m'%d %H-%M-%S') #使用当前时间并格式化时间为年月日时分秒 fp=open('../re'ort/'+now+'report.html','wb') #'../report/'+now+'report.html'通过+组合成一个指定路径的文件 runner=HTMLTestRunner(stream=fp,title='自动化测试'告',desc’iption='用例描述'' ’ runner.run(su) fp.close() 31. 以测试报告的形式输出 from selenium import webdriverfrom HTMLTestRunner import HTMLTestRunnerimport timeimport unittesturl='http:'/192.168.2.110/geeknet/user.php'clas’ Test_Login(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.get(url) time.sleep(1) def test_login(self): self.driver.find_element_by_name("usern“me").sen”_keys('bbb')' ’ self.driver.find_element_by_name("passw“rd").sen”_keys('01234'6') ’ self.driver.find_element_by_id("remem“er").cli”k() time.sleep(1) self.driver.find_element_by_class_name("us_Su“mit").cli”k() def tearDown(self): self.driver.close()if __name__ =="__mai“__": ”su=unittest.TestSuite() su.addTest(Test_Login('test_'ogin')) ’ now=time.strftime("%Y-%m“%d %H-%M-%S") ”fp=open('../re'ort/'+now+'repor’.html','wb'’’ ’runner=HTMLTestRunner(stream=fp,title='自动化测试'告', des’ription='用例描述'' ’runner.run(su) fp.close() 32. 断言 a=self.driver.find_element_by_class_name('f4_b''.tex’ self.assertTrue(a=='lee00'000') ’ # self.assertEqual(a,'lee00’000') ’ # self.assertIn(a,'lee00’000')**案’**from HTMLTestRunner import HTMLTestRunnerurl='http:'/192.168.2.110/geeknet/user.php'clas’ login(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.get(url) self.driver.maximize_window() def test_login(self): self.driver.find_element_by_name('usern'me').sen’_keys('lee00'000') ’ time.sleep(1) self.driver.find_element_by_name('passw'rd').sen’_keys('00000'') ’ time.sleep(1) self.driver.find_element_by_id("remem“er").cli”k() time.sleep(1) self.driver.find_element_by_class_name("us_Su“mit").cli”k() time.sleep(1) #断言 a=self.driver.find_element_by_class_name('f4_b''.tex’ self.assertTrue(a=='lee00'000') ’ # self.assertEqual(a,'lee00’000') ’ # self.assertIn(a,'lee00’000') ’ def tearDown(self): self.driver.close() 项目:1. 新建一个项目geek_Auto,在其中新建文件case(存放用例)、common(共用代码存放位置)、data(数据)、pages(存放页面,一个页面一个文件)、report(存放报告)和python文件run_all(存放所有的执行代码)  2. 在common中新建一个base.py文件,存放基层代码(类,函数) #基层代码from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitclass Base(object):#基于selenium进行二次封装 def __init__(self,driver:webdriver.Firefox): #__init__初始化函数,当调用这个类,会直接执行这个初始化函数 self.driver=driver def findelement(self,loc):#以显示等待的方式定位元素#loc是元素的定位方式,比如:(By.ID,'zenta’')*是把loc的2个值分开传入find_element的2个参数中 相当于:find_element(loc[0],loc[1]) print("正在获取元“位置信息:定位方式-->%s,—元素value-->%s"%(loc”0],loc[1])) ele=WebDriverWait(self.driver,5,0.5).until( lambda x:x.find_element(*loc)#匿名函数 ) return ele def sendkeys(self,loc,text): #对findelement函数再次封装,对定位的元素中输入文本 return self.findelement(loc).send_keys(text) def click(self,loc): #对findelement函数再次封装,对定位的元素进行点击 return self.findelement(loc).click() def get_text(self,loc): #对findelement函数再次封装,获取元素位置的文本 try: a= self.findelement(loc).text return a except: print('获取文本失',返回为空') ’ return "" i“”__name__=='__mai'__': ’url="http:“/192.168.2.110/geeknet/user.php" ”river=webdriver.Firefox() driver.get(url) d=Base(driver) loc_user=(By.NAME,'usern’me') ’loc_pwd=(By.NAME,'passw’rd') ’loc_rem=(By.ID,'remem’er') ’loc_login_button=(By.CLASS_NAME,'us_Su’mit') ’loc_login_username=(By.CLASS_NAME,'f4_b'’ ’d.sendkeys(loc_user,'test0’1') ’d.sendkeys(loc_pwd,'test0’1') ’d.click(loc_rem) d.click(loc_login_button) m=d.get_text(loc_login_username) #获取登录后用户名文本 if m=='test0'1': ’ print("登录成功"“ 3” 在pages文件夹中新建一个python文件login_page.py,对base.py的代码进行再次封装。 from common.base import * #引入common文件夹中base文件的所有内容import timeclass Login_Page(Base): #将元素赋值给变量 loc_user=(By.NAME,'usern’me') ’loc_pwd=(By.NAME,'passw’rd') ’loc_rem=(By.ID,'remem’er') ’loc_login_button=(By.CLASS_NAME,'us_Su’mit') ’loc_login_username=(By.CLASS_NAME,'f4_b'’ ’#三次封装 def input_user(self,text): #输入用户名 self.sendkeys(self.loc_user,text) def input_pwd(self,text): #输入密码 self.sendkeys(self.loc_pwd,text)time.sleep(3) def click_keep_login(self): #点击保存登录信息 self.click(self.loc_rem) def click_login(self): #点击登录 self.click(self.loc_login_button) #四次封装 def login(self,user,pwd,keep_login=False): #keep_login登录状态默认为假 self.input_user(user) self.input_pwd(pwd) if keep_login==True: #如果给的keep_login的参数为真 self.click_keep_login() self.click_login() def get_login_username(self): #获取登录后的用户名文本 return self.get_text(self.loc_login_username)if __name__=='__main_'': u’l="http://“92.168.2.110/geeknet/user.php" dr”ver=webdriver.Firefox() driver.get(url)#Login_Page继承Base的类,Base类需要传递一个参数(浏览器驱动),所以它也需要传递参数 c=Login_Page(driver) #将Login_Page类实例化为c c.login('test001','test0’1’,True)’ d=c.get_login_username() if d=='test001': ’ print('登录成功') 4’ 编写用例,在case包中新建文件test_login_case #四次封装from selenium import webdriverimport unittest,timefrom pages.login_page import Login_Pageclass Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) # time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect): self.login(user,pwd,True) #登录并进行断言 result=self.get_login_username() self.assertTrue(result==expect) def test_001(self): self.login_case('test001','test0’1’,'test0’1’) d’f test_002(self): self.login_case('123456'''test0’1’,'') ’ ’’f test_003(self): self.login_case('test001','12345’'’'') ’ ’’f test_004(self): self.login_case('12551','45646’2’','') ’ ’’f tearDown(self): self.driver.close() if __name__=='__main_'': u’ittest.main() 5. 使用ddt框架 #测试数据testdata=[{'user':''est0’1’,'pwd':’t’st0’1’,'expec’'’'test0’1’}, ’ {'user':''est0’1’,'pwd':’1’345’'’'expec’'’''}, ’ ’’ {'user':''3232’'’'pwd':’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''2321’,’pwd':’1’332’'’'expec’'’''}, ’ ’’ {'user':''est0’1’,'pwd':’'’'ex’e’’'’''}, ’ ’’ {'user':'','pw’'’’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''test’0’','pwd':’t’st0’1’,'expec’'’'test0’1’}, ’ {'user':''est ’0’','pwd':’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''est0’1’','pwd':'t’st0’1’,'expec’'’'test0’1’}, ’ ]from selenium import webdriverimport unittest,time,ddtfrom pages.login_page import Login_Page@ddt.ddt #引用ddt数据驱动框 class Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect):#登录并且进行断言 self.login(user,pwd,True) #登录函数 result=self.get_login_username()#获取登录后的用户名 self.assertTrue(result==expect) #断言 @ddt.data(*testdata)#将测试数据传递给测试用例 *指的是将测试用例的元素全部遍历出来 def test_001(self,data):#每次遍历testdata里的元素传给data print(data) self.login_case(data['user'],'ata[’pwd'],d'ta[’expect'') ’ef tearDown(self): self.driver.close()if __name__=='__main_'': u’ittest.main() 6. 在项目的data文件夹中新建一个Excel文件data.xls,**然后将此事用例写入进去,纯数字要在数据前加一个英文单引号如: ****’****11223354**userpwdexpecttest001test001test001test0011223456 1234256test001 21245641232465 test001 test001 test001test001test001test 001test001 test001 test001test001**通过xlrd类导入****Excel****表格**import xlrdclass ExcelUtil(): def __init__(self,excelPath,sheetName="sheet1"“: ” # 打开excel表格 self.data=xlrd.open_workbook(excelPath) # 通过名称获取 self.table=self.data.sheet_by_name(sheetName) #获取第一行作为key值 self.keys=self.table.row_values(0) # 获取总行数 self.rowNum=self.table.nrows # 获取总列数 self.colNum = self.table.ncols def dict_data(self): if self.rowNum<=1: print("总行数小于1"“ ” else: r=[] #空列表 j=1 for i in ranIe(self.rowNum-1): s={} #获取行里的值,以列表的形式存在 values=self.table.row_values(j) for x in range(self.colNum): s[self.keys[x]]=values[x] r.append(s) j=j+1 return rif __name__=="__main_“": ”xcelPath = "../data“data.xls" s”eetName = "Sheet1"“ d”ta = ExcelUtil(excelPath, sheetName) print(data.dict_data()) 7. 引用ddt数据驱动框架 from selenium import webdriverimport unittest,time,ddtfrom pages.login_page import Login_Pagefrom common.read_excel import ExcelUtil#测试数据excelPath='D:\pyth'n\geek_Auto\data\data.xls'sheetN’me='Sheet1''data= ’xcelUtil(excelPath, sheetName)testdata=data.dict_data() @ddt.ddt #引用ddt数据驱动框架class Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect):#登录并且进行断言 self.login(user,pwd,True) #登录函数 result=self.get_login_username()#获取登录后的用户名 self.assertTrue(result==expect) #断言 @ddt.data(*testdata)#将测试数据传递给测试用例 *指的是将测试用例的元素全部遍历出来 def test_001(self,data):#每次遍历testdata里的元素传给data print(data) #打印每次传的值 self.login_case(data['user'],'ata[’pwd'],d'ta[’expect'') ’ef tearDown(self): self.driver.close() if __name__=='__main_'': u’ittest.main() 8. 在run_all中运行所有的用例 import unittest,timefrom HTMLTestRunner import HTMLTestRunner#测试的路径test_dir='./case/'a=unit'est.defaultTestLoader.discover(test_dir,pattern='test_lo'in_excel*.py')#通过d’scover方法,去测试用例目录下 查找以test开头的测试用例文件,并将查找到的测试用例组装到测试套件里。if __name__=='__main_'': n’w=time.strftime('%Y-%m-%' %H-%M-%S') f’=open('./repor'/'+now+'r'port.’tml','wb')’ ’ r’nner=HTMLTestRunner(stream=fp,title='geek购物网'动化测试报告',descri’tion='用例描述')' r’nner.run(a)fp.close() # UI自动化理论
2. PO的优势是什么? PO提供了一种在UI层操作,业务流程与验证分离的模式,这使得测试代码变得更加清晰、可读、易维护。对象库与测试用例的分离,使得我们更好的复用对象,甚至能与不同的工具进行深度的结合应用,可复用的代码会变得更加优化。 3. 功能测试和自动化测试各占多少比例? 一般情况下,自动化测试不会超过30%,还是以功能测试为主,即在3:7左右 4. 你会不会搭建自动化测试环境? 会的,我去公司前已经搭建好了,我们那边有个10年自动化测试经验的工程师,他搭建的自动化测试框架。我们有完整的自动化环境搭建手册。我们只需要按照安装手册一步一步安装软件,配置相应的环境变量即可。 比如我们采用的是python + selenium +unittest + ddt 以及PO设计模式来进行自动化测试的,我们先安装python3.6,然后安装selenium,pip,pillow,ddt,pymysql,HTMLTestRunner等第三方库,然后配置相应的环境变量就可以了。
2. 你们的测试数据怎么进入到测试用例的? 我们首先通过xlrd来封装读取Excel的方法,然后用封装的方法读取data目录下的Excel数据文件,最后将读取的数据放在列表里,通过ddt数据驱动工具,将列表里的数据循环添加到执行的测试用例里。 3. 自动化测试中下拉列表元素是如何处理的? 我们首先引入selenium里的select类,定位下拉列表元素位置并将其赋值给一个变量,然后将元素的位置传到select类里,调用select_by_value的方法或者select_by_visible_text的方法进行下拉列表的选取 4. 自动化中如何截图? 我们是通过get_screenshot_as_file函数进行截图 5. 自动化中怎么截取部分截图? 首先对整个页面进行截图保存,接下来通过location获取要截取图片的左上角坐标,通过size获取元素的尺寸(宽和高),然后就得到了图片的右下角坐标,再通过PIL的Image方法读取保存的图片。最后通过左上角及右下角坐标使用crop进行裁切,最后保存成图片就可以了。 6. 如何处理时间控件? 定位这个时间控件,然后写一段js脚本去除时间控件的只读属性,然后执行js代码,再采用send_keys去输入内容就可以了。 7. 如何处理弹框? 我们通过driver.swith_to.alert,切换到弹框页面上,通过accept点击确定,或者通过dismiss点击取消,或者send_keys向弹框里输入值 8. 定位元素的方式有哪些? 有8种元素定位方式:id定位,name定位,class_name定位,tag_name标签名定位, link_text文本定位,partail_link_text部分文本定位,xpath定位,css定位 9. 自动化是如何生成测试报告的? 首先引入HTMLTestRunner外部文件,先将时间格式化成年月日时分秒的格式来定义测试报告的文件名,然后定位报告的储存路径,通过open函数采用wb的方式打开这个文件,然后采用HTMLTestRunner方法,传入打开的测试报告文件,测试用例的标题,测试用例的描述生成执行器,最后让执行器执行测试套件即可生成测试报告了。 10. 如何提高自动化脚本的稳定性? 11. 不要右键复制Xpath,自己写相对路径,多用id节点查找 12. 保证元素定位没又问题,第二个影响的因素就是等待,少用强制等待与隐式等待 13. 定位元素方法重新封装,结合显示等待,自己定义一套定位元素的方法。 14. Selenium的特点有什么? 开源,免费,API(封装的函数)简单、灵活 多浏览器支持:Firefox chrome ie等 多平台支持:linux macos windows 多语言支持:java python JavaScript PHP ruby等 对页面有良好的支持 16. 什么是*UI*自动化测试? 使用自动化工具来批量自动运行测试用例测试页面 17. 单元自动化测试 单元测试框架 Java:testNG、Junit Python:unittest、pytest C#:Nunit 几乎主流的语言里边都会有单元测试框架 18. 接口自动化(不分*Web*和*App*) 接口测试工具:jmeter、postman、soapUI、loadrunner 代码执行接口自动化:python的requests库 java的httpclient/httpunit 19. UI自动化测试(*web*自动化测试) QTP(最早)、Robot Framework、Selenium(目前最流行的) 20. APP自动化测试 Monkey以及Monkey runner是Android自带的测试工具 Appium(目前市场最流行的) 21. 什么样的项目适合做自动化测试? (1)如果一个项目频繁做回归测试。 (2)系统界面比较稳定(页面变动少的适合做UI自动化,页面变动多的适合做接口自动化) (3)软件维护周期比较长,项目进度压力不是太大。 (4)测试人员具备较强的编程能力。 22. 使用*poython*连接*Oracle*数据库 需要用到cx_oracle这个第三方库。首先,先引入cx_oracle,然后准备好连接数据,如:用户名/登录密码@Oracle服务器IP:端口号(:1521)/连接的数据库名。 例如:test001/test001@192.168.2.2:1521/orcl 代码如下: import os,cx_OracleuserName = 'test001’pwd='test001’ip='192.168.2.2’db='orcl’sql=“select id from student” def get_value_from_db(userName,pwd,ip,db,sql): #建立oracle数据库连接,格式如下:test001/test001@192.168.2.2:1521/orcl conn=cx_Oracle.connect(userName+ '/' + pwd + '@' + ip + ':1521/' + db) #获取指针 cur=conn.cursor() #执行sql语句 cur.execute(sql) #获取执行结果 row=cur.fetchone() #把值返回给函数 return row[0] #关闭指针 cur.close #关闭数据库连接 conn.close AA=get_value_from_db(userName,pwd,ip,db,sql)print(AA) 1.使用句柄切换页面 from selenium import webdriver from selenium.webdriver.common.by import Byfrom common.base import Base driver=webdriver.Firefox() driver.get(' # handle=driver.current_window_handle # print('当前的handle为: ',handle)ba=Base(driver)loc_text=(By.ID,’kw’)loc_cl=(By.ID,’su’)loc=(By.XPATH,’/html/body/div/div[3]/div/div[3]/div[3]/h3/a’)loc_2=(By.XPATH,”.//*[@id='2’]/h3/a”)ba.sendkeys(loc_text,'句柄') ba.click(loc_cl)ba.click(loc)handles=driver.window_handles #将所有窗口的句柄输出到一个列表中print('所有的handle为: ',handles)driver.switch_to.window(handles[0]) #使用切片的方式切换到初始页面# ba.click(loc_2) |
|