unittest 框架

用户头像
蜗牛前进
关注
发布于: 2020 年 05 月 22 日
unittest框架

Python自带的一个作为单元测试的测试框,PyUnit,相当于Java中的JUnit,



随着自动化技术的成熟,UnitTest成为了测试框架第一选择,可以完整的结合Selenium、Requests来实现l和接口的自动化,



由UnitTest再衍生出PyTest,PyTest可以完美结合UnitTest来实现自动化。



鄙视链:Py Test—Unit Test-RobotFrameWork基本应用:



1.环境搭建,

Python中已经直接加载了UnitTest框架,无须额外安装



2.四大组件:



a.test fixture:

setUp(前置条件)、tearDown(后置条件),用于初始化测试用例及清理和释放资源



b.test case:

测试用例,通过集成unitest.TestCase,来实现用例的继承,在UnitTest中,测试用例都是通过test来识别的。



c.test suite:

测试套件,也称之为测试用例集



d.test runner:

运行器,一般通过runner来调用suite去执行测试



3.UnitTest运行机制:

通过在main函数中,调用unittest.main()运行所有内容



UnitTest自动化实现实战:



1.自动化测试减少冗余,便于维护。



【案例1】

import unittest
class fortext(unittest.TestCase):
# 类的初始化
@classmethod
def setUpClass(cls) -> None:
print('class start')
@classmethod
def tearDownClass(cls) -> None: # 类的释放
print('class end')
#初始化
def setUp(self) -> None:
print('setup')
def tearDown(self) -> None:
print('teardown')
def plus(self,a,b):
c = a+b
print(c)
return c
def test_a(self):
print('aaa')
def test_b(self):
print('bbb')
def test_c(self):
self.plus(1,2)
print('c')
if __name__ == '__main__':
unittest.main()



【案例2】



import unittest
from selenium import webdriver
import time
class forTestTest(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.get('http://www.baidu.com')
def tearDown(self) -> None:
time.sleep(5)
self.driver.quit()
def test_1(self):
self.driver.find_element_by_id('kw').send_keys('虚竹')
self.driver.find_element_by_id('su').click()
def test_2(self):
self.driver.find_element_by_id('kw').send_keys('小龙女')
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
unittest.main()



2.ddt 数据驱动



data-driver-tests 数据驱动测试,



在实际测试中,单个测试是需要用多种不同条件(多种数据)进行测试的。



ddt中最基本的使用:



在class前定义@ddt



在基于实际的应用中,选择对应的装饰器使用即可。@data 是其中一个



data 用于设定参数



unpack 用于解析参数



【案例3】

import unittest
from selenium import webdriver
import time
from ddt import ddt,data
@ddt
class forTestTest(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.get('http://www.baidu.com')
def tearDown(self) -> None:
time.sleep(5)
self.driver.quit()
@data('虚竹','小龙女')
def test_1(self,txt):
self.driver.find_element_by_id('kw').send_keys(txt)
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
unittest.main()



web自动化测试



【案例:百度搜索】



import unittest
import time
from selenium import webdriver
class testBaidu(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.base_url ='https://www.baidu.com'
def test_serarch_key_selenium(self):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys('selenium')
self.driver.find_element_by_id('su').click()
time.sleep(10)
title = self.driver.title
self.assertEqual(title,"selenium_百度搜索")
def test_serarch_key_unittest(self):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys('unittest')
self.driver.find_element_by_id('su').click()
time.sleep(10)
title = self.driver.title
self.assertEqual(title,"unittest_百度搜索")
def tearDown(self) -> None:
self.driver.quit()
if __name__ == '__main__':
unittest.main()



【案例:百度搜索+关键字】



import unittest
import time
from selenium import webdriver
class testBaidu(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.base_url ='https://www.baidu.com'
def baidu_search(self,search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_key)
self.driver.find_element_by_id('su').click()
time.sleep(10)
def test_search_key_selenium(self):
search_key = 'selenium'
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+"_百度搜索")
def test_search_key_unittest(self):
search_key = 'unittest'
self.baidu_search(search_key)
self.assertEqual(self.driver.title, search_key + "_百度搜索")
def tearDown(self) -> None:
self.driver.quit()
if __name__ == '__main__':
unittest.main()



【案例:百度搜索+关键字+classmethod】



import unittest
import time
from selenium import webdriver
class testBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome()
cls.base_url = 'https://www.baidu.com'
def setUp(self) -> None:
print('我没用了吗,开始')
def baidu_search(self,search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_key)
self.driver.find_element_by_id('su').click()
time.sleep(10)
def test_search_key_selenium(self):
search_key = 'selenium'
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+"_百度搜索")
def test_search_key_unittest(self):
search_key = 'unittest'
self.baidu_search(search_key)
self.assertEqual(self.driver.title, search_key + "_百度搜索")
def tearDown(self) -> None:
print('我没用了吗,那我走了')
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
if __name__ == '__main__':
unittest.main()
"""
1.用setUp与setUpClass区别
setup():每个测试case运行前运行
teardown():每个测试case运行完后执行
setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次
2.@是修饰符,classmethod是python里的类方法
"""



小结



1.用setUp与setUpClass区别



setup():每个测试case运行前运行



teardown():每个测试case运行完后执行



setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次



tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次



2.@是修饰符,classmethod是python



生成HTML测试报告

下载安装

下载HTMLTestRunner.py文件,放入python\lib 即可。

下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

生成测试报告



import unittest
from HTMLTestRunner import HTMLTestRunner
#定义测试用例的目录为当前目录下的test_case目录
test_dir = './test_case'
suit = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
if __name__ == '__main__':
#生成HTML格式的报告
fp = open('./test_report/result20200523.html','wb')
rnnner = HTMLTestRunner(stream =fp,
title='百度搜索测试报告',
description='运行环境:Windows10,Chrome浏览器'
)
rnnner.run(suit)
fp.close()



加注释的测试报告

"""
使用 setUpModule/ tearDownModule 减少浏览器的启动
"""
import unittest
from time import sleep
from selenium import webdriver
class Browser:
driver = None
base_url = None
def setUpModule():
Browser.driver = webdriver.Chrome()
Browser.base_url = "https://www.baidu.com"
def tearDownModule():
Browser.driver.quit()
def baidu_search(search_key):
Browser.driver.get(Browser.base_url)
Browser.driver.find_element_by_id("kw").send_keys(search_key)
Browser.driver.find_element_by_id("su").click()
sleep(2)
class TestBaidu(unittest.TestCase):
"""百度搜索测试"""
def test_search_key_selenium(self):
'''搜索关键字:selenium '''
search_key = "selenium"
baidu_search(search_key)
self.assertEqual(Browser.driver.title, search_key + "_百度搜索")
def test_search_key_unttest(self):
'''搜索关键字:unittest '''
search_key = "unittest"
baidu_search(search_key)
self.assertEqual(Browser.driver.title, search_key + "_百度搜索")
class TestBaidu2(unittest.TestCase):
"""百度搜索测试2"""
def test_search_key_python(self):
"""搜索关键字:python"""
search_key = "python"
baidu_search(search_key)
self.assertEqual(Browser.driver.title, search_key + "_百度搜索")
if __name__ == '__main__':
unittest.main()



按当前时间生成测试报告名



import unittest
from HTMLTestRunner import HTMLTestRunner
import time
#定义测试用例的目录为当前目录下的test_case目录
test_dir = './web_case'
suit = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
if __name__ == '__main__':
#生成HTML格式的报告
now_time = time.strftime("%Y-%m-%d %H_%M_%S") # 取当前日期时间
fp = open(now_time+'result.html','wb')
rnnner = HTMLTestRunner(stream =fp,
title='百度搜索测试报告',
description='运行环境:Windows10,Chrome浏览器'
)
rnnner.run(suit)
fp.close()



数据驱动-csv文件



import csv
import codecs
import unittest
from time import sleep
from itertools import islice
from selenium import webdriver
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome()
cls.base_url = 'https://www.baidu.com'
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
def baidu_search(self,search_keys):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_keys)
self.driver.find_element_by_id('su').click()
sleep(3)
def test_search(self):
with codecs.open('baidu_data.csv','r','utf_8_sig') as f:
data = csv.reader(f)
for line in islice(data,1,None):
search_key = line[1]
self.baidu_search(search_key)
if __name__ == '__main__':
unittest.main(verbosity=2)





优化

import csv
import codecs
import unittest
from time import sleep
from itertools import islice
from selenium import webdriver
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome()
cls.base_url = 'https://www.baidu.com'
cls.test_data = []
with codecs.open('baidu_data.csv', 'r', 'utf_8_sig') as f:
data = csv.reader(f)
for line in islice(data, 1, None):
cls.test_data.append(line)
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
def baidu_search(self,search_keys):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_keys)
self.driver.find_element_by_id('su').click()
sleep(3)
def test_search_selenium(self):
self.baidu_search(self.test_data[0][1])
def test_search_unittest(self):
self.baidu_search(self.test_data[1][1])
def test_search_parameterized(self):
self.baidu_search(self.test_data[2][1])
if __name__ == '__main__':
unittest.main(verbosity=2)



Parameterized参数化库

import unittest
from time import sleep
from selenium import webdriver
from parameterized import parameterized
# import parameterized
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome()
cls.base_url = 'https://www.baidu.com'
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
def baidu_search(self,search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_key)
self.driver.find_element_by_id('su').click()
sleep(3)
#通过parameterized 参数化
@parameterized.expand([
("case1","selenium"),
("case2","unittest"),
("case3","parameterized")
])
def test_search(self,name,search_key):
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+"_百度搜索")
if __name__ == '__main__':
unittest.main(verbosity=2)



ddt参数库

参数一 列表
import unittest
from time import sleep
from selenium import webdriver
from ddt import ddt,data,file_data,unpack
@ddt
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome()
cls.base_url = 'https://www.baidu.com'
def baidu_search(self,search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_key)
self.driver.find_element_by_id('su').click()
sleep(3)
#参数化使用方式一 列表
@data(['case1','selenium'],['case2','ddt'],['case3','python'])
@unpack
def test_search1(self,case,search_key):
print('第一组测试用例 列表',case)
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+'_百度搜索')
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)



参数二 元祖
#参数化使用方式二 元祖
@data(('case1','selenium'),('case2','ddt'),('case3','python'))
@unpack
def test_search2(self,case,search_key):
print('第二组测试用例 列表',case)
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+'_百度搜索')



参数三 字典
#参数化使用方式二 元祖
@data(('case1','selenium'),('case2','ddt'),('case3','python'))
@unpack
def test_search2(self,case,search_key):
print('第二组测试用例 列表',case)
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+'_百度搜索')



参数四 JSON



ddt_data_file.json

{
"case1": {"search_key": "python"},
"case2": {"search_key": "ddt"},
"case3": {"search_key": "Selenium"}
}





#参数化读取JSON文件
@file_data('ddt_data_file.json')
def test_search4(self,search_key):
print('第四组测试用例:',search_key)
self.baidu_search(search_key)
self.assertEqual(self.driver.title,search_key+'_百度搜索')



未完待续 20200523

发布于: 2020 年 05 月 22 日 阅读数: 54
用户头像

蜗牛前进

关注

日拱一卒! 2020.02.21 加入

还未添加个人简介

评论 (3 条评论)

发布
用户头像
是不是可以考虑给文章加个标签?比如python,测试之类的
2020 年 05 月 22 日 17:25
回复
谢谢,接受建议
2020 年 05 月 23 日 12:34
回复
2020 年 05 月 23 日 21:35
回复
没有更多了
unittest框架