unittest
提供了两种单元测试的加载方法:
1. 直接通过unittest.main()方法加载单元测试的测试模块;
2. 将所有的单元测试用例添加到测试套件集合中,然后一次性加载所有测试对象。
单元测试用例
Unittest框架通过TestCase类来构建测试用例,并要求所有自定义的测试类都必须继承该类,它是所有测试用例的基类。创建一个自定义测试方法,该方法必须以“test”开头。
TestCase类中定义的几个特殊方法如下:
1. setUpClass():所有的测试方法运行前运行,单元测试前期准备,必须使用@classmethod装饰器进行修饰,setUp函数之前执行,整个测试过程只执行一次。
2. setUp():每个测试方法运行前,测试前的初始化工作;
3. tearDown():每个测试方法运行结束后运行,测试后的清理工作;
4. tearDownClass():所有的测试方法运行结束后执行,单元测试后期清理,必须使用@classmethod装饰器进行修饰,tearDown()之后执行,整个测试过程只执行一次。
#引入时间
import time
#引入webdriver库
from selenium import webdriver
#引入unittest模块
import unittest
class Visit(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
# API调用代码会包含在以“test”命令开始的方法中
def test_visit(self):
self.driver.get("http://www.baidu.com")
self.driver.find_element_by_id("kw").send_keys("selenuim")
time.sleep(2)
print(self.driver.current_url)
def tearDown(self):
self.driver.quit()
# main()方法默认执行的是类下的test开头的方法,不一定是按照从上到下执行测试用例,而是根据方法名按照ASCII编码的位置先后顺序执行。
if __name__ == '__main__':
unittest.main()
断言方法
通过unittest提供的assertEqual()方法来断言结果是否与预期结果相同。还有很多断言方法,这里不列举了。
测试结果:
用“.”点号表示一条运行通过的测试用例;
用“F”表示一条运行失败的测试用例;
用“s”表示一条运行跳过的测试用例;
用“E”表示一条运行出错的测试用例;
忽略测试用例
忽略测试用例分为无条件忽略和有条件忽略。在运行测试时,有时候需要直接跳过某些测试用例,或者当测试用例符合某个条件时跳过测试,又或者直接将测试用例设置为失败。
unittest提供了实现这些需求的装饰器。
import unittest
class MyTest(unittest.TestCase):
@unittest.skip("无条件地跳过装饰的测试,需要说明跳过测试的原因")
def test_skip(self):
print("test a")
@unittest.skipIf(3 > 2,"当条件为真时,则跳过装饰的测试")
def test_skipIf(self):
print("test b")
@unittest.skipUnless(3 > 2,"当条件为真时,则执行装饰的测试")
def test_skip_unless(self):
print("test c")
# 下行装饰器不管执行结果是否失败,都将测试标记为失败,但不会抛出失败信息
@unittest.expectedFailure
def test_expected_failure(self):
self.assertEqual(2, 3)
使用HTMLTestRunner生成HTML测试报告
单元测试结束后,可以通过HTMLTestRunner生成HTML测试报告。之前执行的测试结果都是输出到控制台,既不方便阅读,也不美观。
下载HTMLTestRunner.py文件:
1)下载HTMLTestRunner.py文件:http://tungwaiyip.info/software/HTMLTestRunner.html
2)windows操作系统则将下载下来的文件放到python安装路径下的lib文件夹中;
Ubuntu操作系统则将下载的文件放到python安装路径下的dist-packages文件夹中;
MacOSX操作系统则将下载的文件放到python安装路径下的site-packages文件夹中;
打开命令终端切换到上图红线的目录文件夹下:
cd /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/
然后将下载下来的HTMLTestRunner.py文件拷贝到当前文件夹下:
HTMLTestRunner是python2中的,由于python2与3的部分语法有改动,所以需要对下载的文件进行修改才能在python3中使用。
修改文件HTMLTestRunner.py文件:
第94行,将import StringIO修改成import io
第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
第766行,将uo = o.decode('latin-1')修改成uo = e
第772行,将ue = e.decode('latin-1')修改成ue = e
第631行,将print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
3、引入使用:
1)引包:from HTMLTestRunner import *
2)使用,如:
if __name__ == '__main__':
report = REPORT_PATH + '\\report.html'
with open(report, 'wb') as f:
runner = HTMLTestRunner(f, verbosity=2, title='Test', description='测试报告')
runner.run(TestBaidu('test_search'))
备注:
1)中我最开始用的import HTMLTestRunner,执行的时候上述
2)中倒数第二行报错:TypeError: 'module' object is not callable。
发现2种方式使用时有区别,import module:使用时需加上模块名的限定,而from HTMLTestRunner import * 不需要加。如下2种方式都可以:
1、
from HTMLTestRunner import *
runner = HTMLTestRunner(f, verbosity=2, title='Test', description='测试报告')
2、
import HTMLTestRunner
runner = HTMLTestRunner.HTMLTestRunner(f, verbosity=2, title='Test', description='测试报告')
举例说明:
# 引入时间
import time, os
# 引入webdriver库
from selenium import webdriver
# 引入unittest模块
import unittest
# 引入HMTL测试报告模块
import HTMLTestRunner
class Visit(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
# API调用代码会包含在以“test”命令开始的方法中
def test_visit(self):
self.driver.get("http://www.baidu.com")
self.driver.find_element_by_id("kw").send_keys("selenium")
self.driver.find_element_by_css_selector("input#su.bg.s_btn").click()
time.sleep(2)
self.assertEqual("selenium_百度搜索", self.driver.title)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
# 测试套件
testunit = unittest.TestSuite()
# 添加测试用例到测试套件中
testunit.addTest(visit("test_visit"))
# 获取当前时间
nowtime =time.strftime("%Y_%m_%d %H:%M:%S")
# 定义一个报告存放路径,且通过执行脚本时间生成多个报告名不同来区分
REPORT_PATH = '/Users/yuandaping/Downloads/'
report = REPORT_PATH + '/' + nowtime + 'report.html'
# 定义测试报告
with open(report, 'wb') as f:
runner = HTMLTestRunner.HTMLTestRunner(stream=f, title='百度搜索测试报告', description='用例执行情况:')
# 运行测试用例
runner.run(testunit)
# 关闭报告文件
f.close()
运行脚本后生成的报告文件:/Users/yuandaping/Downloads/2019_09_23 17:53:54report.html
注:
DDT是针对unittest单元测试框架设计的扩展库。允许使用不同的测试数据来运行一个测试用例,并将其展示为多个测试用例。
安装:pip3 install ddt
Parameterized是Python的一个参数化库,同时支持unittest、nose和pytest单元测试框架。
安装:pip3 install parameterized