Python- unittest 单元测试 (测试框架)和pytest 的区别
Posted 软件测试自动化测试
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python- unittest 单元测试 (测试框架)和pytest 的区别相关的知识,希望对你有一定的参考价值。
unittest(官网)是python内置的用于测试代码的模块,无需安装, 使用简单方便。
unittest 简介
unittest case的运行流程:
- 写好一个完整的TestCase
- 多个TestCase 由TestLoder被加载到TestSuite里面, TestSuite也可以嵌套TestSuite
- 由TextTestRunner来执行TestSuite,测试的结果保存在TextTestResult中
- TestFixture指的是环境准备和恢复
unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunner
Test Fixture
用于测试环境的准备和恢复还原, 一般用到下面几个函数。
- setUp():准备环境,执行每个测试用例的前置条件
- tearDown():环境还原,执行每个测试用例的后置条件
- setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只运行一次
- tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次
Test Case
- 参数verbosity可以控制错误报告的详细程度:
默认为1
。0,表示不输出每一个用例的执行结果;2表示详细的执行报告结果。 - Verbosity=1情况下
成功是 .
,失败是 F,出错是 E,跳过是 S - 测试的执行跟方法的顺序没有关系, 默认按字母顺序
- 每个测试方法均
以 test 开头
- Verbosity=2情况下会打印测试的注释
被测代码,demo.py文件
#!/usr/bin/python
# -*- coding: utf-8 -*-
def add(a, b):
return a+b
def minus(a, b):
return a-b
测试case, test_demo_class.py文件
#!/usr/bin/python
# -*- coding: utf-8 -*-
import unittest
from demo import add, minus
class TestDemo(unittest.TestCase):
"""Test mathfuc.py"""
@classmethod
def setUpClass(cls):
print ("this setupclass() method only called once.\\n")
@classmethod
def tearDownClass(cls):
print ("this teardownclass() method only called once too.\\n")
def setUp(self):
print ("do something before test : prepare environment.\\n")
def tearDown(self):
print ("do something after test : clean up.\\n")
def test_add(self):
"""Test method add(a, b)"""
self.assertEqual(3, add(1, 2))
self.assertNotEqual(3, add(2, 2))
def test_minus(self):
"""Test method minus(a, b)"""
self.assertEqual(1, minus(3, 2))
self.assertNotEqual(1, minus(3, 2))
@unittest.skip("do't run as not ready")
def test_minus_with_skip(self):
"""Test method minus(a, b)"""
self.assertEqual(1, minus(3, 2))
self.assertNotEqual(1, minus(3, 2))
if __name__ == '__main__':
# verbosity=*:默认是1;设为0,则不输出每一个用例的执行结果;2-输出详细的执行结果
unittest.main(verbosity=1)
Test Suite
-
一般通过
addTest()
或者addTests()
向suite中添加。case的执行顺序与添加到Suite中的顺序是一致的 -
@unittest.skip()装饰器跳过某个case
(1)skip():无条件跳过
@unittest.skip("i don't want to run this case. ")
(2)skipIf(condition,reason):如果condition为true,则 skip
@unittest.skipIf(condition,reason)
(3)skipUnless(condition,reason):如果condition为False,则skip
@unittest.skipUnless(condition,reason)
Test Loder
TestLoadder
用来加载TestCase到TestSuite中。loadTestsFrom*()
方法从各个地方寻找testcase,创建实例,然后addTestSuite,再返回一个TestSuite实例- defaultTestLoader() 与 TestLoader()功能差不多,复用原有实例
unittest.TestLoader().loadTestsFromTestCase(testCaseClass)
unittest.TestLoader().loadTestsFromModule(module)
unittest.TestLoader().loadTestsFromName(name,module=None)
unittest.TestLoader().loadTestsFromNames(names,module=None)
unittest.TestLoader().discover()
实例如下, test_demo_module.py文件
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import htmlReport
import unittest
import test_demo_class
from test_demo_class import TestDemo
if __name__ == '__main__':
paras = sys.argv[1:]
args = paras[0]
report = paras[1]
suite = unittest.TestSuite()
if args == 'test':
tests = [TestDemo("test_minus"), TestDemo("test_add"), TestDemo("test_minus_with_skip")]
suite.addTests(tests)
elif args == 'tests':
suite.addTest(TestDemo("test_minus"))
suite.addTest(TestDemo("test_add"))
suite.addTest(TestDemo("test_minus_with_skip"))
elif args == 'class':
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestDemo))
elif args == 'module':
suite.addTests(unittest.TestLoader().loadTestsFromModule(test_demo_class))
elif args == 'mix':
suite.addTests(unittest.TestLoader().loadTestsFromName('test_demo_class.TestDemo.test_minus'))
elif args == 'mixs':
suite.addTests(unittest.TestLoader().loadTestsFromNames(['test_demo_class.TestDemo.test_minus', 'test_demo_class.TestDemo', 'test_demo_class']))
elif args == 'discover':
suite.addTests(unittest.TestLoader().discover('.', 'test_*.py', top_level_dir=None))
if report == 'terminal':
runner = unittest.TextTestRunner(verbosity=1)
runner.run(suite)
elif report == 'txt':
with open('ut_log.txt', 'a') as fp:
runner = unittest.TextTestRunner(stream=fp, verbosity=1)
runner.run(suite)
elif report == 'html':
runner = HTMLReport.TestRunner(report_file_name='test',
output_path='report',
title='测试报告',
description='测试描述',
sequential_execution=True
)
runner.run(suite)
Testing Report
- 终端报告: 如上
terminal
分支 - TXT报告: 如上
txt
分支,当前目录会生成ut_log.txt文件 - HTML 报告:如上
html
分支,终端上打印运行信息
同时会在当前目录生成report文件夹, 文件夹下有test.html
和test.log
文件
感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
上图的资料 在我的QQ技术交流群里(技术交流和资源共享,广告进来腿给你打断)
可以自助拿走,群号953306497(备注“csdn111”)群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。
以上是关于Python- unittest 单元测试 (测试框架)和pytest 的区别的主要内容,如果未能解决你的问题,请参考以下文章