unittest框架解析
unittest 是python 的单元测试框架,unittest 单元测试提供了创建测试用例,测试套件以及批量执行的方案, unittest 在安装pyhton 以后就直接自带了,直接import unittest 就可以使用。
作为单元测试的框架, unittest 也是可以对程序最小模块的一种敏捷化的测试。在自动化测试中,必须需要知道所使用语言的单元测试框架。利用单元测试框架,创建一个类,该类继承unittest的TestCase,这样可以把每个case看成是一个最小的单元, 由测试容器组织起来,到时候直接执行,同时引入测试报告。
构建测试套件
addTest() 的应用
当有多个或者几百测试用例的时候, 这样就需要一个测试容器( 测试套件) ,把测试用例放在该容器中进行执行,unittest 模块中提供了TestSuite 类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把每个测试用例加入到测试套件中。
def createsuite(): suite = unittest.TestSuite() #将测试用例加入到测试容器(套件)中 suite.addTest(testbaidu1.Baidu1("test_baidusearch")) suite.addTest(testbaidu1.Baidu1("test_hao")) suite.addTest(testbaidu2.Baidu2("test_baidusearch")) return suite if __name__=="__main__": suite=createsuite() runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
makeSuite()和TestLoader()的应用
在unittest 框架中提供了makeSuite() 的方法,makeSuite可以实现把测试用例类内所有的测试case组成的测试套件TestSuite ,unittest 调用makeSuite的时候,只需要把测试类名称传入即可。
TestLoader 用于创建类和模块的测试套件,一般的情况下,使TestLoader().loadTestsFromTestCase(TestClass)来加载测试类。
#手工添加案例到套件,
def createsuite(): suite = unittest.TestSuite() #将测试用例加入到测试容器(套件)中 suite.addTest(unittest.makeSuite(testbaidu1.Baidu1)) suite.addTest(unittest.makeSuite(testbaidu2.Baidu2)) return suite ''' suite1 =unittest.TestLoader().loadTestsFromTestCase(testbaidu1.Baidu1) suite2 = unittest.TestLoader().loadTestsFromTestCase(testbaidu2.Baidu2) suite = unittest.TestSuite([suite1, suite2]) return suite
``
discover()的应用
discover 是通过递归的方式到其子目录中从指定的目录开始, 找到所有测试模块并返回一个包含它们对象的TestSuite ,然后进行加载与模式匹配唯一的测试文件,discover 参数分别为discover(dir,pattern,top_level_dir=None)
def createsuite(): discover=unittest.defaultTestLoader.discover('../test',pattern='test*.py',top_level_dir=None) print discover return discover
用例的执行顺序
unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为: 09,AZ,a~z 。所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。对于测试目录与测试
文件来说, unittest 框架同样是按照这个规则来加载测试用例。
addTest()方法按照增加顺序来执行
忽略用例的执行
@unittest.skip("skipping")
unittest断言
自动化的测试中, 对于每个单独的case来说,一个case的执行结果中, 必然会有期望结果与实际结果, 来判断该case是通过还是失败, 在unittest 的库中提供了大量的实用方法来检查预期值与实际值, 来验证case的结果, 一般来说, 检查条件大体分为等价性, 逻辑比较以及其他, 如果给定的断言通过, 测试会继续执行到下一行的代码, 如果断言失败, 对应的case测试会立即停止或者生成错误信息( 一般打印错误信息即可) ,但是不要影响其他的case执行。
HTML报告生成
脚本执行完毕之后,还需要看到HTML报告,下面我们就通过HTMLTestRunner.py 来生成测试报告
if __name__=="__main__": curpath=sys.path[0] #取当前时间 now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time())) if not os.path.exists(curpath+'/resultreport'): os.makedirs(curpath+'/resultreport') filename=curpath+'/resultreport/'+now+'resultreport.html' with open(filename,'wb') as fp: #出html报告 runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'测试报告',description=u'用例执行 情况',verbosity=2) suite=createsuite() runner.run(suite)
异常捕捉与错误截图
用例不可能每一次运行都成功,肯定运行时候有不成功的时候。如果可以捕捉到错误,并且把错误截图保存,这将是一个非常棒的功能,也会给我们错误定位带来方便。
def savescreenshot(self,driver,file_name): if not os.path.exists('./image'): os.makedirs('./image') now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time())) #截图保存 driver.get_screenshot_as_file('./image/'+now+'-'+file_name) time.sleep(1)
数据驱动
之前我们的case都是数据和代码在一起编写。考虑如下场景:
需要多次执行一个案例,比如baidu搜索,分别输入中文、英文、数字等进行搜索,这时候需要编写3个案例吗?有没有版本一次运行?
python 的unittest 没有自带数据驱动功能。所以如果使用unittest,同时又想使用数据驱动,那么就可以使用DDT来完成。
@ddt class Baidu1(unittest.TestCase): def setUp(self): self.driver=webdriver.Chrome() self.url="http://www.baidu.com/" self.driver.implicitly_wait(5) # self.verificationErrors = [] # self.accept_next_alert = True def tearDown(self): self.driver.quit() # self.assertEqual([], self.verificationErrors) # @unittest.skip("skipping") @data("Lisa","张一凡","蒋欣") def test_baidu1(self,value): self.driver.get(self.url) self.driver.find_element_by_id("kw").clear() self.driver.find_element_by_id("kw") .send_keys(value) self.driver.find_element_by_id("su") .click() time.sleep(5)
————————————————
原文链接:https://blog.csdn.net/weixin_43688527/article/details/106723142