unittest框架:UI界面层的单元功能测试框架 (黑盒测试) Java单元测试框架 Junit (白盒测试)
unittest 各组件: 1)测试固件 setUp() 进行初始化工作 tearDown()进行测试完后的清理工作 2)TestCase 测试用例 测试方法:test_开头 3)批量执行 把多个测试用例(可以说一个脚本中,也可以是多个脚本中)放到一个测试套件中去执行 4)执行测试用例 TestRunner 5)生成测试报告 HTMLRunner
unittest 各组件的关系为: test fixture:初始化和清理测试环境,比如创建临时的数据库,文件和目录等,其中 setUp() :初始化和 setDown():清理工作
是最常用的方法 test case:单元测试用例,TestCase 是编写单元测试用例最常用的类 test suite:单元测试用例的集合,TestSuite 是最常用的类 test runner:执行单元测试 test report:生成测试报告
一个测试方法:
from selenium import webdriver
import unittest
import os
import time
class Baidu1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
def test_hao(self):
driver=self.driver
self.driver.get(self.url)
driver.find_element_by_link_text("hao123").click()
time.sleep(6)
if __name__=="__main__":
unittest.main(verbosity=0)
self:类的实例
批量执行脚本
构建测试套件
假设我们已经编写了test001.py,test002.py两个文件,那么我们怎么同时执行这两个文件呢? test001.py:
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException
class testCase1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.get(self.url)
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
def test_baidu1(self):
driver=self.driver
driver.find_element_by_id("kw").send_keys("刘亦菲")
driver.find_element_by_id("su").click()
time.sleep(6)
def test_baidu2(self):
driver = self.driver
driver.find_element_by_link_text("新闻").click()
time.sleep(6)
def is_alter_exist(self):
try:
self.driver.switch_to.alert
except NoAlertPresentException as e:
return False
return True
if __name__=="__main__":
unittest.main(verbosity=0)
test002.py:
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException
class testCase2(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.get(self.url)
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
def test_baidu1(self):
driver=self.driver
driver.find_element_by_id("kw").send_keys("陕西")
driver.find_element_by_id("su").click()
time.sleep(6)
def test_baidu2(self):
driver = self.driver
driver.find_element_by_link_text("hao123").click()
time.sleep(6)
def is_alter_exist(self):
try:
self.driver.switch_to.alert
except NoAlertPresentException as e:
return False
return True
if __name__=="__main__":
unittest.main(verbosity=0)
addTest() 的应用
把一个脚本文件类中的所有测试用例一个一个添加进测试套件 当有多个或者几百测试用例的时候, 这样就需要一个测试容器( 测试套件) ,把测试用例放在该容器中进行执行,unittest 模块中提供了TestSuite 类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把每个测试用例加入到测试套件中。 将test001.py、test002.py、runall.py放在同一个目录testcase中
import unittest
from src0717 import test001
from src0717 import test002
def createSuite():
suite=unittest.TestSuite()
suite.addTest(test001.testCase1("test_baidu1"))
suite.addTest(test001.testCase1("test_baidu2"))
suite.addTest(test002.testCase2("test_baidu1"))
suite.addTest(test002.testCase2("test_baidu2"))
return suite
if __name__ =="__main__":
suite=createSuite()
runner=unittest.TextTestRunner(verbosity=2)
runner.run(suite)
上述做法有两个不方面的地方,阻碍脚本的快速执行,必须每次修改runall.py: 1)需要导入所有的py文件,比如import test001,每新增一个需要导入一个 2)addTest需要增加所有的testcase,如果一个py文件中有10个case,就需要增加10次
runner=unittest.TextTestRunner(verbosity=2)
=0(静默模式:只能获取总的测试用例数和总的结果比如总共有100个失败20,成功80
=1(默认模式):非常类似静默模式,只是在每个成功的用例前面有个"."每个失败的用例前面有个”F“
=2(详细模式):测试结果会显示每个测试用例的所有相关的信息
makeSuite()和TestLoader()的应用
以上两种方法都可以把一个脚本中的所有测试用例添加进一个测试套件中 在unittest 框架中提供了makeSuite() 的方法,makeSuite可以实现把测试用例类内所有的测试case组成的测试套件TestSuite ,unittest 调用makeSuite的时候,只需要把测试类名称传入即可。 TestLoader 用于创建类和模块的测试套件,一般的情况下,使TestLoader().loadTestsFromTestCase(TestClass)来加载测试类。 runall.py:
import unittest
from src0717 import test001
from src0717 import test002
def createSuite():
suite=unittest.TestSuite()
suite1=unittest.TestLoader().loadTestsFromTestCase(test001.testCase1)
suite2=unittest.TestLoader().loadTestsFromTestCase(test002.testCase2)
suite=unittest.TestSuite([suite1,suite2])
return suite
if __name__ =="__main__":
suite=createSuite()
runner=unittest.TextTestRunner(verbosity=2)
runner.run(suite)
discover()的应用
discover 是通过递归的方式到其子目录中从指定的目录开始, 找到所有测试模块并返回一个包含它们对象的TestSuite ,然后进行加载与模式匹配唯一的测试文件,discover 参数分别为 discover(dir,pattern,top_level_dir=None)
import unittest
from src0717 import test001
from src0717 import test002
def createSuite():
discover=unittest.defaultTestLoader.discover('../src0717',pattern='test00*.py',top_level_dir=None)
print(discover)
return discover
if __name__ =="__main__":
suite=createSuite()
runner=unittest.TextTestRunner(verbosity=2)
runner.run(suite)
总结:
1.unittest测试固件 setUp():初始化 tearDown():清理工作 2.TestDown Test_运行这个类的时候默认执行 3.测试套件:存放测试用例(测试方法)的一个容器 addTest 可以一次存放一个测试脚本里一个类的一个方法(提供方法名) makeSuite 可以一次性存放一个测试脚本的一个类的所有方法 TestLoader 可以一次性存放一个测试脚本的一个类的所有方法 discover 可以把指定文件夹下,所有特定格式命名的测试脚本中类的所有以test_开头的方法 4.runner
测试用例的执行顺序
unit test框架中测试用例执行顺序:0~9,A ~ Z ,a ~z
忽略测试用例的执行
加上标签:@unittest.skip(“skipping”)
unit test断言
测试报告
脚本执行完毕之后,还需要看到HTML报告,下面我们就通过HTMLTestRunner.py 来生成测试报告。 HTMLTestRunner支持python2.7 HTMLTestRunner.py 文件,下载地址: http://tungwaiyip.info/software/HTMLTestRunner.html python3 下载地址: http://pan.baidu.com/s/1tp3Ts 下载后将其放在testcase目录中去或者放入…\Python3\Lib 目录下(windows)。
import unittest
import HTMLTestRunner
import os,sys
import time
def createSuite():
discover = unittest.defaultTestLoader.discover('../src0717', pattern='test00*.py', top_level_dir=None)
print(discover)
return discover
if __name__ =="__main__":
curpath=sys.path[0]
print(curpath)
print(sys.path[0])
if not os.path.exists("/resultReport"):
os.makedirs(curpath+"/resultReport")
now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))
print(time.time)
print(time.location(time.time()))
filename=curpath+"/resultReport"+now+"-"+"resultReport.html"
with open(filename,'wb') as fp:
runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u"测试报告",
description=u'用例执行情况',verbosity=2)
suite=createSuite()
runner.run(suite)
查看报告:
sys.path 和sys.path[0]
sys.path[0] 😄:\java\python\test\src0717 sys.path 是一个路径集合 [‘D:\java\python\test\src0717’, ‘D:\java\python\test’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\python38.zip’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\DLLs’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\lib’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\lib\site-packages’]
time.time:Linux 时间戳 time.location()格式化本地时间
异常捕捉和错误截图
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException
class testCase1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
@unittest.skip("skipping")
def test_baidu1(self):
driver=self.driver
driver.find_element_by_id("kw").send_keys("刘亦菲")
driver.find_element_by_id("su").click()
time.sleep(6)
def test_baidu2(self):
driver = self.driver
self.driver.get(self.url)
try:
self.assertEqual(driver.title,"百度一下,你就知道",msg="判断失败")
except:
self.save_error_image(driver,"baidu.png")
time.sleep(6)
def save_error_image(self,driver,name):
if not os.path.exists("./errorImage"):
os.makedirs("./errorImage")
now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
driver.get_screenshot_as_file("./errorImage/"+now+"-"+name)
def is_alter_exist(self):
try:
self.driver.switch_to.alert
except NoAlertPresentException as e:
return False
return True
if __name__=="__main__":
unittest.main(verbosity=0)
数据驱动
安装ddt: pip install ddt 查看是否安装上:pip show ddt
from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data
@ddt
class testCase1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
@data("刘亦菲", "Lisa", "腾讯", "阿里巴巴")
def test_baidu1(self,value):
driver=self.driver
driver.get(self.url)
driver.find_element_by_id("kw").send_keys(value)
driver.find_element_by_id("su").click()
time.sleep(6)
if __name__=="__main__":
unittest.main(verbosity=0)
方法二: test_baidu.json.py:
[
"jolin",
"林俊杰"
]
test.py:
from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data
@ddt
class testCase1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
@file_data('test_baidu.json.py')
def test_baidu1(self,value):
driver=self.driver
driver.get(self.url)
driver.find_element_by_id("kw").send_keys(value)
driver.find_element_by_id("su").click()
time.sleep(6)
if __name__=="__main__":
unittest.main(verbosity=0)
传递一组参数,每组参数位两个及两个以上:
from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data
@ddt
class testCase1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.url="https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
def tearDown(self):
self.driver.quit()
@data(["Jojin","Jojin_百度搜索"],["刘亦菲","刘亦菲_百度搜索"])
@unpack
def test_baidu1(self,value1,value2):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("kw").send_keys(value1)
driver.find_element_by_id("su").click()
time.sleep(6)
print(driver.title)
self.assertEqual(driver.title,value2,msg="fail")
time.sleep(6)
if __name__=="__main__":
unittest.main(verbosity=0)
方法二: 创建一个test_baidu.txt: data 刘亦菲,刘亦菲_百度搜索 汉服,汉服_百度搜索 西安,西安_百度搜索 创建一个test.py:
from selenium import webdriver
import unittest
import os,sys
import time,csv
from ddt import ddt,file_data,unpack,data
def getCsv(file_name):
rows=[]
path=sys.path[0]
with open(path+'/data/'+file_name,'rt') as f:
readers=csv.reader(f,delimiter=',',quotechar='|')
next(readers,None)
for row in readers:
temprows=[]
for i in row:
temprows.append(i)
rows.append(temprows)
return rows
@ddt
class Baidu1(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome()
self.driver.implicitly_wait(30)
self.base_url="https://www.baidu.com/"
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
@data(*getCsv('test_baidu_data.txt'))
@unpack
def test_baidu2(self,value,expect_value):
driver = self.driver
driver.get(self.base_url+"/")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys(value)
driver.find_element_by_id("su").click()
driver.maximize_window()
time.slee(6)
print(expect_value)
print(driver.title)
self.assertEqual(expect_value,driver.title,msg="和预期结果不一致!")
time.sleep(6)
if __name__=='__main__':
unittest.main()
|