Web自动化测试(自动化测试和测试开发的区别)
1.selenium使用方法
1.1操作浏览器
1、启动浏览器(实例化浏览器)
1.7下拉框元素定位
选择获取反选下拉框元素首先要实例化select元素
from selenium.webdriver.support.ui import Select # 引入包
select_element=Select(element) # 实例化select
三种常用选择方法
select_element.select_by_index(index) 根据index定位,从0开始 select_element.select_by_value(value) 根据value属性定位 select_element.select_by_visible_text(text) 根据文本定位
反选的方法
select_element.deselect_by_index(index) 根据index定位,从0开始 select_element.deselect_by_value(value) 根据value属性定位 select_element.deselect_by_visible_text(text) 根据文本定位 select_element.deselect_all() 取消全部选择
获取选项的值
select_element.options 返回这个select元素所有的options select_element.all_selected_options 所有被选中的options select_element.first_selected_option 第一个被选中的option
创建select.html 文件,代码如下:
<form> <select id="s1Id"> <option></option> <option value="o1" id="id1">o1</option> <option value="o2" id="id2">o2</option> <option value="o3" id="id3">o3</option> </select> <br/><br/> <select id="s2Id" multiple="multiple" size="6"> <option></option> <option value="o1val">o1</option> <option value="o2val">o2</option> <option value="o3val">o3</option> <option value="o4val"> With spaces</option> <option value="o4val"> With nbsp</option> </select> </form>示例1:采用三种方法依次选择's1Id'的值
s1 = Select(driver.find_element_by_id('s1Id')) # 实例化Select,页面第一个下拉框 s1.select_by_index(1) # 选择第二项选项:o1 s1.select_by_value("o2") # 选择value="o2"的项 s1.select_by_visible_text("o3") # 选择text="o3"的值,即在下拉时我们可以看到的文本示例2:想查看一个's1Id'所有的选项
s1 = Select(driver.find_element_by_id('s1Id')) for select in s1.options: print(select.text)示例3:查看我已选中的所有选项,'s2Id'可以多选的选择框
s4 = Select(driver.find_element_by_id('s2Id')) s4.select_by_index(1) # 根据顺序选择第2个 s4.select_by_value("o2val") # 根据value属性选择o2val s4.select_by_visible_text("With spaces") # 根据展示文本选择With spaces s4.select_by_visible_text(u" With nbsp") # 注意空格,只有为 是才用空格 for select in s4.all_selected_options: # 循环获取所有的值 print(select.text)注意:只有只有为 的空格才是空格,在html中代码只有 才代表空格,代码中的空格不是空格。
示例4:查看选择框的默认值或选中的值
s1 = Select(driver.find_element_by_id('s1Id')) print(s1.first_selected_option.text) # 查看选择默认值 s1.select_by_value("o2") print (s2.first_selected_option.text) # 查看选中的值示例5:取消选择
s4 = Select(driver.find_element_by_id('s2Id')) s4.select_by_index(1) s4.select_by_value("o2val") s4.select_by_visible_text("With spaces") s4.select_by_visible_text(u" With nbsp") s4.deselect_by_index(1) # 根据值顺序取消选择 s4.deselect_by_value("o2val") # 根据value属性取消选择 s4.deselect_by_visible_text("With spaces") # 根据文本取消选择 s4.select_by_value("o2val") s4.select_by_index(1) s4.deselect_all() # 取消全部选择1.8定位frame和iframe中的元素对象
< frame> <iframe> 标签,浏览器会在标签中打开一个特定的页面窗口(框架),它在本窗口中嵌套进入一个网页,当用selenium定位页面元素的时候会遇到定位不到frame框架内的元素的问题。
定位frame中的元素前我们需要driver.switch_to.frame()切换到对应的frame中,执行操作后,要操作frame框架外的元素,需要通过driver.switch_to.default_content()切换回主文档页面。
driver.switch_to.frame(index/id/name/WebElement) 切入frame裤架中,参数可以为id/name/index
driver.switch_to.parent_frame() 切换回当前frame的上一层,如果当前已是主文档,则无效果
driver.switch_to.default_content() 切换回主文档
创建如下两个html文件,两个文件放入同一个文件夹内
frame.html
<html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <title>frame</title> </head> <body> <div class="row-fluid"> <label>frame外输入框</label> <input type='text' id="frameinput"> <div class="span10 well"> <h3>frame</h3> <iframe id="f1" name="frame2" src="inner_frame.html" width="800" height="600"></iframe> </div> </div> </body> </html>inner_frame.html
<html> <head> <title>inner frame</title> </head> <body> <label id="innerlable">frame1内多选按钮 </label> <input type="checkbox" id="innercheck" name="inner"> <div class="row-fluid"> <h3>inner frame</h3> <iframe id="f2" name="frame2" src=" " width="700" height="400"> </iframe> </div> </body> </html>示例:操作主文档的元素 --> 切换到外层frame 操作外层frame的元素 --> 切换到内层frame 操作内层的元素 --> 切换回外层frame 操作外层frame 的元素 --> 再次切入内层frame操作元素 --> 切换回主文档操作文档元素 -->再去切换到外层frame操作元素
from selenium import webdriver import time driver = webdriver.Chrome() driver.get(r'E:\frame.html') # 打开frame.html页面,注意修改为你的位置 driver.find_element_by_id('frameinput').send_keys('操作frame外的元素') driver.switch_to.frame(0) # 根据index切换,从0开始 text = driver.find_element_by_id('innerlable').text print(text) driver.find_element_by_id('innercheck').click() driver.switch_to.frame('f2') # 根据id切入 内层frame driver.find_element_by_id('index-kw').send_keys('selenium frame') driver.switch_to.parent_frame() # 切换到上一层表单 driver.find_element_by_id('innercheck').click() driver.switch_to.frame('frame2') # 根据name再次切入内层frame driver.find_element_by_id('index-bn').click() driver.switch_to.default_content() # 切换回主文档 driver.find_element_by_ta('frameinput').clear() driver.switch_to.frame(driver.find_elements_by_tag_name('iframe')) # 通过webelement切换driver.find_element_by_id('innercheck').click() time.sleep(3) driver.quit()1、 driver.switch_to.frame(frame_reference)切换进入frame
switch_to_frame() 将淘汰使用,建议使用switch_to.frame()。
switch_to.frame() 切换frame支持4种不同参数方法进行切换,元素的frame的index,frame的id或name属性,frame元素的WebElement元素对象。
通常采用id和name就能够解决绝大多数问题。但有时候frame并无这两项属性,则可以用index和WebElement来定位:
index从0开始,整型参数,根据同层frame的顺序定位WebElement对象,即find_element方法所取得的对象,我们可以用tag_name、xpath等来定位frame对象。如上示例的:driver.switch_to.frame(driver.find_elements_by_tag_name('iframe'))2、 driver.switch_to.default_content() 切换回主文档
切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档。
driver.switch_to.default_content() # 切换到主文档中。注意:很多人都会忘记这步操作
3、driver.switch_to.parent_frame() 切换到上一层表单
<html> <iframe id="frame1"> <iframe id="frame2" / > </iframe> </html>嵌套frame很少会遇到,如下frame1为外层,frame2嵌套在frame1中。我们进行切换操作如下:
a. 从主文档切到frame2,一层层切进去
driver.switch_to.frame("frame1") driver.switch_to.frame("frame2")b. 从frame2再切回frame1,selenium提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。
driver.switch_to.parent_frame() # 如果当前已是主文档,则无效果parent_frame()这个相当于后退的方法,我们可以随意切换不同的frame。
1.9Alert/Confirm/Prompt 弹出窗口处理
一、Alert/Confirm/Prompt弹出窗口特征说明
Alert弹出窗口:
提示用户信息只有确认按钮,无法通过页面元素定位,不关闭窗口无法在页面上做其他操作。
Confirm 弹出窗口:
有确认和取消按钮,该弹出窗口无法用页面元素定位,不关闭窗口无法在页面上做其他操作。
Prompt弹出窗口:
有输入框、确认和取消按钮,该弹出窗口无法用页面元素定位,不关闭窗口无法在页面上做其他操作。
注意:3种窗口为浏览器自带的窗口,该窗口无法定位到元素,能定位到元素需要使用WebElement操作。
二、Alert/Confirm/Prompt弹出窗口操作
第一步:需要获取弹出窗口,两种方法 与Alert(driver)
alert=driver.switch_to.alert或
from selenium.webdriver.common.alert import Alert alert=Alert(driver)第二步:对获取到的窗口进行操作,常用方法如下:
alert.text() # 获取窗口信息 alert.accept() # 确认 alert.dismiss() # 取消 alert.send_keys(keysToSend) # 输入信息alert.authenticate(username, password) # 用户认证信息登录,已有确认操作
三、实例说明
创建下面3个html文件
alertTest.html
<html> <head> <title>Alert Test</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> </head> <script type="text/javascript"> function showAlert(){ alert(document.from1.t1.value); } function showMultilineAlert(){ alert("你必须纠正以下错误:\n你必须输入XXXX.\n你必须做XXXX.\n你必须XXXX"); } </script> <body> <h2>Alert Test</h2> <form name="from1"> <input type="text" name="t1" value="可以输入 Alert 信息"><br><br> <input type="button" name="button1" value="点击Alert获取输入框信息" onclick="showAlert()"><br><br> <input type="button" name="button2" value="Alert自带多行文本信息" onclick="showMultilineAlert()"><br> </form> </body> </html>confirmTest.html
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Confirm Test</title> </head> <script type="text/javascript"> function showConfirm(){ var t1 = document.from1.t1; if (confirm("请点击确认或取消")){ t1.value = "确认"; }else{ t1.value = "取消"; } } </script> <body> <h2>Confirm Test</h2> <form name="from1"> <input type="button" name="button1" value="点击Confirm按钮" onclick="showConfirm()"><br><br> <input type="text" name="t1"> </form> </body> </html>promptTest.html
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Prompt Test</title> </head> <script type="text/javascript"> function showPrompt(){ var t1 = document.from1.t1; t1.value = prompt("请输入信息,信息将填入页面输入框."); } </script> <body> <h2>Prompt Test</h2> <form name="from1"> <input type="button" name="button1" value="点击Prompt按钮" onclick="showPrompt()"><br><br> <input type="text" name="t1"> </form> </body> </html>示例1:Alert弹窗获取文本与确认操作
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.expected_conditions import alert_is_present from selenium.webdriver.common.alert import Alert driver = webdriver.Chrome() driver.get(r'E:\XXX\alertTest.html') driver.find_element_by_name('button1').click() # 点击第一个按钮 WebDriverWait(driver, 5).until(alert_is_present()) # 等待弹出窗口出现 alert = driver.switch_to.alert # 获取弹出窗口 text1 = alert.text # 获取窗口文本信息 print(text1) # 打印窗口文本信息 alert.accept() # 确认 print('----------') driver.find_element_by_name('button2').click() # 点击第二个按钮 WebDriverWait(driver, 5).until(alert_is_present()) # 等待弹出窗口出现 alert = Alert(driver) # 获取弹出窗口 text1 = alert.text # 获取窗口文本信息 print(text1) # 打印窗口文本信息 alert.accept() # 确认 driver.quit()注意:WebDriverWait(driver, 5).until(alert_is_present()) 加上这个可提高代码的可靠性
示例2:Comfirm弹窗获取文本、确认、取消操作
driver = webdriver.Chrome() driver.get(r'E:\XXX\confirmTest.html') driver.find_element_by_name('button1').click() # 点击按钮 WebDriverWait(driver, 5).until(alert_is_present()) # 等待弹出窗口出现 alert = driver.switch_to.alert # 获取弹出窗口 print(alert.text) # 打印窗口信息 alert.accept() # 确认 time.sleep(2) driver.find_element_by_name('button1').click() # 点击按钮 WebDriverWait(driver, 5).until(alert_is_present()) # 等待弹出窗口出现 alert = driver.switch_to.alert # 获取弹出窗口 alert.dismiss() # 取消 time.sleep(2) driver.quit()示例3:Prompt 弹窗获取文本、输入内容、确认操作
driver = webdriver.Chrome() driver.get(r'E:\XXX\promptTest.html') driver.find_element_by_name('button1').click() # 点击按钮 WebDriverWait(driver, 5).until(alert_is_present()) # 等待弹出窗口出现 alert = Alert(driver) # Alert 获取弹出窗口 alert.send_keys('selenium Alert弹出窗口输入信息') # 输入信息 alert.accept() # 确认 time.sleep(2) driver.quit()1.10上传文件
一、input控件上传文件
查看长传文件的页面元素标签,如果为input表明是通过input控件上传文件。我们可以直接采用WebElement.send_keys(‘文件地址’) 长传文件。
创建html文件,如下:
upload.html
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>upload file</title> </head> <body> <h3>upload file</h3> <input type="file" name="file"/> </body> </html>示例:长传C:\install.log文件。
from selenium import webdriver import time driver = webdriver.Chrome() driver.get(r'E:\XXXX\Html\upload.html') # 文件的地址 driver.find_element_by_name('file').send_keys(r'C:\install.log') # 上传文件 time.sleep(2) driver.quit()1.11浏览器多窗口切换
有时web应用会打开多个浏览器窗口,当我们要定位新窗口中的元素时,我们需要将webDriver的handle(句柄)指定到新窗口。
什么意思?
假设我们打开web应用,在系统运行过程中重新打开一个新窗口(可以是页签,当前浏览器存在两个窗口),这时我们webDriver对浏览器的操作指针(句柄)还再原窗口,如果需要操作新窗口元素就要将handle句柄切换到新窗口。
一、常用方法
driver.current_window_handle 获取当前窗口handle
driver.window_handles 获取所有窗口的handle,返回list列表
driver.switch_to.window(handle) 切换到对应的窗口
driver.close() 关闭当前窗口
二、示例
示例:进入搜狗搜索 --> 打开搜狗输入法页面 --> 输入法页面查看皮肤 --> 关闭搜狗搜索页面 --> 输入法页面查看词库
from selenium import webdriver import time driver = webdriver.Chrome() driver.get(' cssref/css_selectors.asp例子是搜狗搜索中的元素为例:
1.14JavaScript获取页面元素
1、DOM获取元素
HTML DOM 定义了访问和操作 HTML 文档的标准。每个页面都是一个DOM Tree 结果,如下图
通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。我们通过JavaScript返回该节点就是我们的元素。
document.getElementById() 获取带有指定 ID 的元素
document.getElementsByClassName() 获取包含带有指定类名的所有元素的节点列表
document.getElementsByName() 获取指定Name的所有元素的节点列表
document.getElementsByTagName() 获取带有指定标签名称的所有元素的节点列表
注意:getElementsByClassName() 在 Internet Explorer 5,6,7,8 中无效
示例:通过DOM的JavaScript脚本获取元素
js='return document.getElementById("query")' js='return document.getElementsByClassName("sec-input")[0]' js='return document.getElementsByName("query")[0]' js='return document.getElementsByTagName("input")[0]' js='return document.getElementById("sf").getElementsByTagName("input") ' # id=sf的input子元素 element=driver.execute_script(js) # 执行js获取元素注意:由于getElements返回的为列表所以需要使用[0]指定为第1个元素,如果查找出对应元素存在多个可以指定第几个。
2、JQuery获取元素
JQuery获取元素也是通过返回值获取,比DOM的兼容性高。
常用语法格式如下:
return $("p:contains('包含的字符')")[0] 根据页面文本获取元素
return $(css定位)[0] css定位获取对象
return $x(xpath定位)[0] xpath定位获取对象
示例:
js = 'return $("input[name=w]+input")[0]' js = 'return $("form#sf input[type=text]")[0]' js = 'return $x("//input[@name=\'w\']/following-sibling::input")[0]' js='$("p:contains(\'搜狗搜索APP\')")[0]' element=driver.execute_script(js) # 执行js获取元素附件:JQuery选择器
来自于: jquery/jquery_ref_selectors.asp
1.15JavaScript操作元素对象
avaScript操作元素对象可以使用DOM操作元素,如果应用有JQuery可以使用JQuery操作元素对象。
selenium运行JavaScript有两种形式,一种是接收JavaScript脚本语言,另一种是将WebElement传入JavaScript中执行脚本。如下:
driver.execute_script("window.open(' website/onlinedemo.html') # 打开网页 driver.switch_to.frame(driver.find_element_by_xpath('//div[@id="edui1_iframeholder"]/iframe')) # 切换iframe WebDriverWait(driver, 15).until(lambda driver: driver.find_element_by_css_selector('body.view')) element = driver.find_element_by_css_selector('body.view') driver.execute_script('arguments[0].innerHTML="<b>selenium</b><br><p>selenium<p>"', element)示例:滚动条拖动到元素位置
driver.get(' ') element=driver.find_element_by_id('auto') driver.execute_script('arguments[0].scrollIntoViewIfNeeded(true);',element)1.16cookie 处理
river.get_cookies() # 获得cookie 信息
driver.get_cookies(name) # 获得对应name的cookie信息
add_cookie(cookie_dict) # 向cookie 添加会话信息
delete_cookie(name) # 删除特定(部分)的cookie
delete_all_cookies() # 删除所有cookie
示例:
from selenium import webdriver driver=webdriver.Chrome() driver.get(' ') cookies = driver.get_cookies() # 获得所有cookie 信息 print('删除前cookies:',cookies) # 打印cookie信息 driver.add_cookie({'name': 'key-name', 'value': 'value-123456'}) #添加cookie信息 print('key-name cookie信息:',driver.get_cookie('key-name')) # 查看添加的key-name的cookie信息 driver.delete_cookie("key-name") # 删除一个特定的cookie driver.delete_all_cookies() # 删除所有cookie print('删除后cookies:',driver.get_cookies()) driver.quit()2.unittest单元测试框架
2.1 unittest单元测试实例
创建计算器类calculator
# Calculator.py class calculator(object): def __init__(self, a, b): self.a = a self.b = b def add(self): return (self.a + self.b) def minus(self): return (self.a - self.b) def multip(self): return (self.a * self.b) def divide(self): return (self.a / self.b)创建一个简单的单元测试用例
import unittest # 导入unittest 包 from unittest_doc.com.Calculator.Calculator import calculator # 引入需要测试的包 # 所有用例需继承TestCase类或者其子类 class simple_test(unittest.TestCase): def setUp(self): print('@@@初始化test_simple@@@') self.a = calculator(1, 2) def test_add(self): print('---测试用例test_simple add---') self.assertEqual(self.a.minus(), -1, '两值不相等') self.assertEqual(self.a.add(), 3, '两值不相等') self.assertNotEqual(self.a.divide(), 1, '两值不相等') def test_divide(self): print('---测试用例test_simple divide---') self.assertEqual(self.a.divide(), 0.5) def tearDown(self): print('@@@结束test_simple@@@') if __name__ == '__main__': unittest.main()运行结果:
@@@初始化test_simple@@@ ---测试用例test_simple add--- @@@结束test_simple@@@ @@@初始化test_simple@@@ ---测试用例test_simple divide--- @@@结束test_simple@@@2.2 TestCase详解
测试用例由setUp(),test_add(),test_divide(),tearDown() 4个部分组成,它们放在一个继承于unittest.TestCase 的测试类下。
2.2.1继承
unittest提供一个基类TestCase,如果我们要编写一个测试用例,就需要继承这个抽象基类,这样当我们运行测试程序时它会自动的运行这些测试用例。
2.2.2测试方法的名称
测试方法要以test开头,这样测试程序能够自动找到要运行的方法,在上述例子中包含3个测试方法,
test_add_5_5test_bool_valuetest_raise2.2.3setUp和tearDown
setUp() 用于测试用例执行前的准备工作。如测试用例中需要访问数据库,可以在setUp中建立数据库连接并进行初始化;用例需要使用web,可以先实例化浏览器;app测试需先要启动app,可先实例化app。
tearDown() 用于用例执行之后的善后工作。如关闭数据库连接,关闭浏览器,关闭app。当用例没运行成功是他也会执行。
setUpClass() 所有测试用例运行前运行,必须使用@classmethod装饰器装饰,在setUp()方法前执行,整个测试过程只执行一次,主要作用是单元测试前的准备工作。
tearDownClass() 所有测试用例运行后运行,必须使用@classmethod装饰器装饰,在tearDown()方法后执行,整个测试过程只执行一次,主要作用是单元测试后的清理工作。
2.2.4断言
assertEqual()来检查预期的输出;调用assertTrue()或assertFalse()来验证一个条件;调用assertRaises()来验证抛出了一个特定的异常。
2.3TestSuite测试套件
2.3.1TestSuite 测试套件简介
对一个功能的验证往往是需要很多多测试用例,可以把测试用例集合在一起执行,这就产生了测试套件TestSuite 的概念,它是用来组装单个测试用例,规定用例的执行的顺序,而且TestSuite也可以嵌套TestSuite。
2.3.2初始化套件
suite = unittest.TestSuite()2.3.3添加测试用例
把测试用例放入一个列表中suite = unittest.TestSuite() suite.addTest(simple_test('test_add')) suite.addTest(simple_test('test_divide'))用suite.addTests()把测试用例列表加入套件suite = unittest.TestSuite() tests = [Case('test_raise'), Case('test_bool_value'), Case('test_add_5_5')] suite.addTests(tests)unittest.makeSuite根据文件批量创建测试套件,如果一个文件中有非常多测试用例,可以根据用例名称的相似性创建测试套件。unittest.makeSuite(testCaseClass, prefix) #testCaseClass<Class类型>为测试用例类的名称 #prefix <str类型>用例相似的部分名称示例:suite = unittest.makeSuite(simple_test, 'test') # 创建并批量加载测试用例统计测试套件中的用例个数suite.countTestCases()2.4 TestLoader 加载测试用例
unittest.TestLoader()根据目录批量创建测试套件,可以指定用例存放目录,根据文件名称匹配测试用例。
注意:用例存放的子目录中必须具备init.py 文件,否则无法加载用例。
语法:
unittest.TestLoader().discover(start_dir, pattern='test\*.py', top_level_dir=None)* ''' start_dir要测试的模块名或测试用例目录。 pattern='test.py' 表示用例文件名的匹配原则。星号“*”表示任意多个字符。 top_level_dir=None 测试模块的顶层目录。None <=> 测试用例不是放在多级目录中 '''示例:
suites=unittest.defaultTestLoader.discover('./testDirectory', pattern='*_test.py')或
suites=unittest.TestLoader().discover('./testDirectory', pattern='*_test.py')2.5 TestsRunner 执行测试用例
2.5.1TextTestRunner
创建测试套件后,执行测试用例使用unittest.TextTestRunner().run(TestSuite)
示例:执行加载simple_test用例的测试套件
suites = unittest.TestLoader().discover('./testDirectory', pattern='*_test.py') #加载测试用例 runner = unittest.TextTestRunner(verbosity=2) runner.run(suites) # 执行测试用例测试套件灵活运用
为测试用例文件添加suite 方法,方便加载测试套件import unittest # 导入unittest 包 from unittest_doc.com.Calculator.Calculator import calculator # 引入需要测试的包 # 所有用例需继承TestCase类或者其子类 class simple_test(unittest.TestCase): def setUp(self): print('@@@初始化test_simple@@@') self.a = calculator(1, 2) def test_add(self): print('---测试用例test_simple add---') self.assertEqual(self.a.minus(), -1, '两值不相等') self.assertEqual(self.a.add(), 3, '两值不相等') self.assertNotEqual(self.a.divide(), 1, '两值不相等') def test_divide(self): print('---测试用例test_simple divide---') self.assertEqual(self.a.divide(), 0.5) def tearDown(self): print('@@@结束test_simple@@@') def test_suite(): # 创建测试添加测试套件函数 suite = unittest.TestSuite() # 建立测试套件 suite.addTests([simple_test('test_add'), simple_test('test_divide')]) return suite if __name__ == '__main__': runner = unittest.TextTestRunner(verbosity=2) runner.run(test_suite())嵌套测试套件,多个测试套件组合在一起suite1 = unittest.TheTestSuite() suite2 = unittest.TheTestSuite() alltests = unittest.TestSuite((suite1, suite2))2.5.2 HTMLTextRunner
示例fp=open(filename, 'wb') # 写方式打开报告文件 runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='报告标题',description='报告说明' ) #执行测试 runner.run(Suite) # Suite为TestSuite测试套件产生不同文件测试报告#构建测试用例集 suite=unittest.defaultTestLoader.discover('../testDirectory', pattern='*_test.py') #测试套件组合在一起 now=time.strftime("%Y%m%d%H%M%S", time.localtime()) filename=r'./report/'+now+r'result.html' # 根据时间生成文件名 with openopen(filename, 'wb') as fp: runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='报告标题',description='报告说明' ) runner.run(suite)#执行测试2.6跳过测试
class SkipCase(unittest.TestCase): def setUp(self): self.test_class = TestClass() @unittest.skip("Skip test.") def test_add_5_5(self): self.assertEqual(self.test_class.add(5, 5), 10) @unittest.skipIf(NUM < 3, "Skiped: the number is too small.") def test_bool_value(self): self.assertTrue(self.test_class.is_string("hello world!")) @unittest.skipUnless(NUM==3, "Skiped: the number is not equal 3.") def test_raise(self): self.assertRaises(KeyError, self.test_class.raise_error)unittest中使用装饰器的方式来实现跳过测试与预计的失败,常用的主要有3中,
@unittest.skip:直接跳过测试用例;@unittest.skipIf:当满足条件时跳过测试用例;@unittest.skipUnless:只有满足某一条件时不跳过,其他的都跳过;2.7断言assert
assertEqual(a,b,[msg]):断言a和b是否相等,相等则测试用例通过。
assertNotEqual(a,b,[msg]):断言a和b是否相等,不相等则测试用例通过。
assertTrue(x,[msg]):断言x是否True,是True则测试用例通过。
assertFalse(x,[msg]):断言x是否False,是False则测试用例通过。
assertIs(a,b,[msg]):断言a是否是b,是则测试用例通过。
assertNotIs(a,b,[msg]):断言a是否是b,不是则测试用例通过。
assertIsNone(x,[msg]):断言x是否None,是None则测试用例通过。
assertIsNotNone(x,[msg]):断言x是否None,不是None则测试用例通过。
assertIn(a,b,[msg]):断言a是否在b中,在b中则测试用例通过。
assertNotIn(a,b,[msg]):断言a是否在b中,不在b中则测试用例通过。
assertIsInstance(a,b,[msg]):断言a是是b的一个实例,是则测试用例通过。
assertNotIsInstance(a,b,[msg]):断言a是是b的一个实例,不是则测试用例通过。
assertRaises(Exceptm,a,value,[msg]):value值是否有异常
msg='测试失败时打印的信息'
2.8参数化
2.8.1参数化代码 1.导包 unittest/parameterized 2.定义测试类 3.书写测试方法(用到的测试数据使用变量代替) 4.组织测试数据并传参
2.8.2代码实现
方式一:使用数组作为测试数据testcase3.py# 1.导包 unittest/parameterizedimport unittestfrom parameterized import parameterizedfrom tools import login# 组织测试数据[(),(),()]or[[],[],[]]data = [('admin','123456','登录成功'),('root','123456','登录失败'),('admin','123123','登录失败')]# 2.定义测试类class TestLogin(unittest.TestCase):# 3.书写测试方法(用到的测试数据使用变量代替)@parameterized.expand(data)def test_login(self,username,password,expect):self.assertEqual(expect,login(username,password))# 4.组织测试数据并传参(装饰器@)if __name__=="__main__":unittest.main()方式二:使用Json文件作为测试数据data.json[{"desc":"正确的用户名和密码","username":"admin","password":"123456","expect":"登录成功"},{"desc":"错误的用户名","username":"root","password":"123456","expect":"登录失败"},{"desc":"错误的密码","username":"admin","password":"123123","expect":"登录失败"},{"desc":"错误的用户名和密码","username":"root","password":"123123","expect":"登录失败"}]testcase4.py# 1.导包 unittest/parameterizedimport jsonimport unittestfrom parameterized import parameterizedfrom tools import login# 组织测试数据[(),(),()]or[[],[],[]]# "desc":"正确的用户名和密码",# "username":"admin",# "password":"123456",# "expect":"登录成功"def build_data():with open('data.json',encoding="utf-8") as f:result = json.load(f) #[{},{},{}]data = [] for i in result: #i {}data.append((i.get("expect"),i.get('username'),i.get("password")))return data# 2.定义测试类class TestLogin(unittest.TestCase):# 3.书写测试方法(用到的测试数据使用变量代替)@parameterized.expand(build_data())def test_login(self,expect,username,password):self.assertEqual(expect,login(username,password))# 4.组织测试数据并传参(装饰器@)if __name__=="__main__":unittest.main()3.自动化框架搭建
tests 存放测试用例data 测试数据reports 测试报告logs 日志文件config 处理配置文件path等common 所有项目通用的代码根目录下放:
readme 自动化测试项目的说明文件run.py 项目入口主程序免责声明:本文内容由互联网用户贡献,不作为任何投资建议。投资决策需建立在独立思考之上,本文内容仅供参考,风险自担!如有侵权请联系我们删除,本文链接:http://www.panmou.com/web3/61021.html。