HTMLTestRunnerNew下载地址:
链接: https://pan.baidu.com/s/1p33EkYp73n2RcZlhXnnZsw 提取码: 7prr 复制这段内容后打开百度网盘手机App,操作更方便哦
前言
学习了好久的Python基础语法,今天,我们的学习内容终于要和测试挂钩了。学习自动化测试的第一步,我们首先接触的就是unittest。接下来,就让我们开始今天的学习内容。
首先,我们要知道的是,"unittest"是Python中一个自带的单元测试框架,使用的时候直接import导入就可以,而不需要去pip install。它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作。
定义
在学习写代码之前,让我们学习一些有关的关键词定义。
TestCase
TestCase指的是一个测试用例,比如说,我们登陆中的“输入正确用户名和密码,登陆成功”,“输入正确用户名不输入密码,提示密码为空”,这些都是一个测试用例。
TestSuite
TestSuite 是一个测试用例的集合,就是将多个TestCase集合在一起就叫做TestSuit。在实战中,我们可以将所有一个模块的测试用例集合在一起,组成一个TestSuit。
TestLoader
TestLoader是用来加载TestCase到TestSuite中的,可以说是一种媒介吧。
TestRunner
TestRunner是来执行测试用例的,测试的结果会保存到TestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息
unittest代码解析
了解完各种定义,我们来看一下unittest的使用,看如下代码:
"""登陆模块代码"""
class Login:
def __init__(self):
self.name = None
self.password = None
def login(self, name, password):
"""
登陆功能,当用户名和密码相等时登陆成功,否则登陆失败
:param name: 用户名
:param password: 密码
"""
self.name = name
self.password = password
if self.name == self.password:
print("登陆成功")
return True
else:
print("登陆失败")
return False
以上为我们的第一段代码,我们创建了一个Login类,Login类种有一个login函数,当输入的用户名和密码相等时,登陆成功,否则登陆失败。在此基础上,我们写一段测试代码如下:
import unittest
class UnitTestDemo(unittest.TestCase):
@classmethod
def setUpClass(cls):
# 必须使用@classmethod 装饰器,所有test运行前运行一次
super().setUpClass()
print("setUpClass")
@classmethod
def tearDownClass(cls):
# 必须使用@classmethod, 所有test运行完后运行一次
super().tearDownClass()
print("tearDownClass")
def setUp(self):
# 每个测试用例执行之后做操作
self.login = Login()
super().setUp()
print("setUp")
def tearDown(self):
# 每个测试用例执行之前做操作
super().tearDown()
print("tearDown")
def test_login_success(self):
print("test_login_success")
self.assertEqual(self.login.login("yoyo", "yoyo"), True)
def test_login_fail(self):
print("test_login_fail")
self.assertEqual(self.login.login("youyou", "fail"), False)
我们一起来看一下UnitTestDemo这个自定义的单元测试类,首先我们在一开头就通过import导入了单元测试unittest模块,然后在定义UnitTestDemo类的时候,继承了unittest.TestCase,使得我们定义的类是一个单元测试类。这就是unittest最基本的用法,然后我们在UnitTestDemo类中,重写了四个方法,分别为“setUpClass”,“tearDownClass”,“setUp”和“tearDown”。
接下来,让我们来看一下两个用例方法test_login_success和test_login_fail,在结果图中我们可以看出,虽然我们先定义了test_login_success方法,但是在执行的时候,却是test_login_fail方法先执行。这是为啥呢?原来,测试用例的执行顺序是根据ascii编码来定义先后的,这两个方法命名中,test_login_都一样但是fail中的f比success中的s在ascii编码中的顺序在前,所以先执行了test_login_fail方法,如果我们想要固定测试用例的执行顺序,我们可以在命名时加数字区分,如:
如上图中的命名,中间添加数字,执行顺序就正过来了。这边还有一点需要注意的是,用例方法命名
都要以test开头!这一点很重要很重要,切记!!!
断言
在测试用例中,执行完测试用例后,最后一步是判断测试结果是pass还是fail,自动化测试脚本里面一般把这种生成测试结果的方法称为断言(assert)。下面,我就举例一些常用的断言
序号 | 断言方法 | 断言描述 |
---|---|---|
1 | assertEqual(arg1, arg2, msg=None) | 验证arg1=arg2,不等则fail |
2 | assertNotEqual(arg1, arg2, msg=None) | 验证arg1 != arg2, 相等则fail |
3 | assertTrue(expr, msg=None) | 验证expr是true,如果为false,则fail |
4 | assertFalse(expr,msg=None) | 验证expr是false,如果为true,则fail |
5 | assertIs(arg1, arg2, msg=None) | 验证arg1、arg2是同一个对象,不是则fail |
6 | assertIsNot(arg1, arg2, msg=None) | 验证arg1、arg2不是同一个对象,是则fail |
7 | assertIsNone(expr, msg=None) | 验证expr是None,不是则fail |
8 | assertIsNotNone(expr, msg=None) | 验证expr不是None,是则fail |
9 | assertIn(arg1, arg2, msg=None) | 验证arg1是arg2的子串,不是则fail |
10 | assertNotIn(arg1, arg2, msg=None) | 验证arg1不是arg2的子串,是则fail |
11 | assertIsInstance(obj, cls, msg=None) | 验证obj是cls的实例,不是则fail |
12 | assertNotIsInstance(obj, cls, msg=None) | 验证obj不是cls的实例,是则fail |
在刚刚的代码中,我在登陆判断的时候用了assertEqual(),去判定结果是否和预期结果相等,这边不进行多余阐述,我们可以根据不同情况来调用上面不同的断言方法。
TestSuite三种用法
# 1.第一种suit方法
my_suit = unittest.TestSuite([UnitTestDemo("test_1_login_success"), UnitTestDemo("test_2_login_fail")])
# 2.第二种suit方法
my_suit = unittest.TestSuite()
my_suit.addTests([UnitTestDemo("test_1_login_success"), UnitTestDemo("test_2_login_fail")])
# 3.第三种suit方法
my_suit = unittest.TestSuite()
my_suit.addTest(UnitTestDemo("test_1_login_success"))
my_suit.addTest(UnitTestDemo("test_2_login_fail"))
以上这三种TestSuit的调用方法其实大同小异,都是将测试用例集合放入到TestSuit中,只是在写法中稍微不同,我们获取到my_suit之后,就可以进行调用了
with open(r"D:\\pycharmProject\\python_self_study\\files\\test15_report.txt", "w", encoding="utf-8") as f:
runner = unittest.TextTestRunner(f)
runner.run(my_suit)
我们获取到mySuit之后,首先新建并打开一个报告文件,这里就是test15_report.txt,然后创建一个TextTestRunner对象,并且run之前的my_suit,就可以执行我们放入到my_suit中的每一个测试用例啦。
那么,同学们难免有疑问,如果我有很多很多的测试用例要执行,难道我要一个个添加吗?哈哈!当然不是!!!,请看下面代码:
# 4.loader添加
loader = unittest.TestLoader()
tests = loader.loadTestsFromTestCase(UnitTestOne)
my_suit = unittest.TestSuite(tests)
我们的TestLoader作用更大,我们在实例中,可以将一个测试模块写成一个类并且继承unittest.TestCase,然后通过TestLoader的loadTestsFromTestCase方法一股脑添加,这样就不用一个一个手动添加了哈哈。是不是很带劲!!
HTMLTestRunner
写到这边,我们关于unittest模块的基础知识基本上就学完了,但是别慌,我们看一下,上面执行完之后的test15_report.txt中是啥东西。
啊偶,尴尬,这个生成的测试报告也太简单了吧,简直没啥用。那么怎么生成好看易懂的测试报告呢?当然是要靠我们的HTMLTestRunner啦。这边我们先导入一个HTMLTestRunnerNew.py文件,此文件在文章最后给出,然后我们修改生成测试报告的代码如下:
with open(r"D:\\pycharmProject\\python_self_study\\files\\test15_report.html", "wb") as f:
runner = HTMLTestRunnerNew.HTMLTestRunner(f, title=u'测试报告', description=u'用例执行情况:',tester="YoYo")
runner.run(my_suit)
运行后生成一个类型为html的测试报告,我们打开看一下。如下图所示:
是不是详细很多呀?嘿嘿!
总结
到这里,我们unittest的基础知识就学习的差不多了,每个知识点都涉及到了,这里,我们要总结一下unittest编写测试用例的步骤:
1.编写测试用例TestCase
2.将测试用例塞入到TestSuit测试套件中
3.通过TestRunner运行测试套件中的所有测试用例
4.将执行完的结果放入到测试报告中‘
好啦,今天要讲的就这么多,打完收工!