IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> unittest框架基础和报告输出 -> 正文阅读

[开发测试]unittest框架基础和报告输出

  • unittest是python标准库中的模块
  • unittest中的几个重要概念
    • testcase:测试用例,所有测试用例都要继承unittest.TestCase类
    • testfixture:测试开始的准备工作和测试结束后的清理工作
    • testsuite:测试套件,一系列的测试用例或者测试套件
    • testruuner:用于执行和输出测试结果的组件

textfixture

setUp:测试用例的前置操作,运行时每个测试用例均会执行,如果setUp运行发生异常,测试方法不会运行
tearDown : 只要setUp成功运行无论测试方法是否成功,都会运行tearDown
setUpClass :测试类的前置操作,@classmethod修饰,和setUp类似
tearDownClass:和tearDown类似
setUpModule: 测试模块的前置操作
tearDownModule:和tearDown类似

例子1

  • textfixture的执行顺序

测试代码

import unittest
class testCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupClass")
    def setUp(self) -> None:
        print("setUp")
    @classmethod
    def tearDownClass(cls) -> None:
        print("teardownClass")

    def tearDown(self) -> None:
        print("teardown")

    def testCaseTwo(self):
        print("testCaseTwo")
        self.assertTrue(True)
    def testCaseOne(self):
        print("testCaseOne")
        self.assertTrue(True)
class testTwo(unittest.TestCase):
    def testcase2(self):
        print("testcase2")
        self.assertTrue(True)

def setUpModule():
    print("setUpmodule")
def tearDownModule():
    print("tearDownmodule")
if __name__=="__main__":
    unittest.main()

运行结果

D:\Python\program\practic_unittest>python -m unittest test_case.py -v
setUpmodule
setupClass
testCaseOne (mylib.testCase) ... setUp
testCaseOne
teardown
ok
testCaseTwo (mylib.testCase) ... setUp
testCaseTwo
teardown
ok
teardownClass
testcase2 (mylib.testTwo) ... testcase2
ok
tearDownmodule

----------------------------------------------------------------------
Ran 3 tests in 0.012s

OK

例子2

  • 修改setUp,让setUp运行失败,可看到测试用例抛出AssertionError:setUp fail的异常

测试代码

    def setUp(self) -> None:
        self.fail("setUp fail")
        print("setUp")

执行结果

  • 测试用例未执行:
D:\Python\program\practic_unittest>python -m unittest test_case.py -v
setupClass
testCaseOne (test_case.testCase) ... FAIL
testCaseTwo (test_case.testCase) ... FAIL
teardownClass

======================================================================
FAIL: testCaseOne (test_case.testCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Python\program\practic_unittest\test_case.py", line 8, in setUp
    self.fail("setUp fail")
AssertionError: setUp fail

======================================================================
FAIL: testCaseTwo (test_case.testCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Python\program\practic_unittest\test_case.py", line 8, in setUp
    self.fail("setUp fail")
AssertionError: setUp fail

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=2)

testcase

断言

常见的有以下断言,更多的断言详见https://docs.python.org/3.8/library/unittest.html#assert-methods
assertEqual(a, b, msg=None) 检查a的值是否等于b的值
assertNotEqual(a, b, msg=None)
assertTrue(x, msg=None)检查bool(x)是否为True
assertFalse(x, msg=None)检查bool(x)是否为False
assertIs(a, b, msg=None) 检查a和b是否是同一个对象(存储地址是否一样),是则断言通过
assertIsNot(a, b, msg=None)检查a和b是否是同一个对象,不是则断言通过
assertIsNone(x, msg=None) 检查x是否是None
assertIsNotNone(x, msg=None)检查x是否不是None
assertIn(a, b, msg=None) 检查b是否包含a,是则断言通过
assertNotIn(a, b, msg=None)检查b是否包含a,否则断言通过
assertIsInstance(a, b, msg=None)检查a是否是b的实例,是则通过
assertNotIsInstance(a, b, msg=None)检查a是否是b的实例,不是则通过

跳过测试

  • 可对测试方法或者测试类添加装饰器,以实现跳过测试
  • 亦可对setup添加跳过测试
  • 包含以下装饰器:
    @unittest.skip(reason) 被装饰的用例跳过执行
    @unittest.skipIf(condition, reason) 只有满足条件了才会跳过,不满足条件则执行用例
    @unittest.skipUnless(condition, reason) 满足条件不跳过,执行用例,不满足条件则跳过

例子

  • test_unittest.py文件
import unittest
class testStringMethodone(unittest.TestCase):
    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    @unittest.skipUnless(sys.platform.startswith("win"), "requires windows")
    def test_isupper(self):
        self.assertTrue('FOO'.isupper())

    @unittest.skip("decorate skip")
    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
if __name__ == "__main__":
    unittest.main()
  • mylib.py文件
__version__=(1,2)
  • 执行结果
PS D:\Python\program\practic_unittest> python  -m unittest test_unittest.py -v
True
test_isupper (test_unittest.testStringMethodone) ... ok
test_split (test_unittest.testStringMethodone) ... skipped 'decorate skip'
test_upper (test_unittest.testStringMethodone) ... skipped 'not supported  this library version'

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK (skipped=2)

预计的失败

  • @unittest.expectedFailure 标记测试用例失败.如果运行有异常,则运行成功,如果运行通过,则运行失败

例子

  • test_unittest.py文件
import unittest
class testStringMethodone(unittest.TestCase):
    ......
    @unittest.expectedFailure
    def test_capitalize(self):
        self.assertEqual("test".capitalize(), "Test1")
  • 运行结果
PS D:\Python\program\practic_unittest> python  -m unittest test_unittest.py -v
True
test_capitalize (test_unittest.testStringMethodone) ... expected failure
.....

subtest

  • subTest( msg=None , **params ),msg和params是可选值,当运行失败时会回显这些值
  • subtest返回一个上下文管理器,其下的代码作为子测试,运行失败时,后续测试还会继续,如果不使用subtest,第一次遇到执行失败时就停止了
  • 有运行失败的测试用例才会有提示,如果没有直接显示通过
class testStringMethodone(unittest.TestCase):
    def test_notuse_subtest(self):
        for i in ['str1', "test",'str3']:
            self.assertIn("test",i)
    def test_use_subtest(self):
        for i in ['str1', "test",'str3']:
            with self.subTest(i):
                self.assertIn("test",i)

运行结果:
subtest运行结果

testsuite& 测试执行

  • 方法一:使用unittest.main(),收集模块中的所有测试用例并执行
if __name__=="__main__":
    unittest.main()
  • 方法二:通过testsuite收集测试用例
  1. 添加test_case.py:测试用例文件
import unittest

class testclassOne(unittest.TestCase):
    def testCaseTwo(self):
        print("testCaseTwo")
        self.assertTrue(True)
    def testCaseOne(self):
        print("testCaseOne")
        assert False
class testclassTwo(unittest.TestCase):
    def test1(self):
        self.assertTrue(False)
  1. run_testcase.py:执行文件
# coding:utf-8
import unittest
import test_case
import os

def load_by_testcase(): #加载指定的testcase
    suite = unittest.TestSuite()
    suite.addTest(test_case.testclassOne('testCaseTwo'))
    suite.addTest(test_case.testclassTwo('test1'))
    return suite

def load_by_calss():   #通过测试类来添加
    suite = unittest.TestSuite()
    loader=unittest.TestLoader()
    load_suite=loader.loadTestsFromTestCase(test_case.testclassOne)
    suite.addTests(load_suite)
    return suite
def load_by_pattern(pattern):   #通过匹配的文件执行用例
    this_dir = os.path.dirname(__file__)
    suite = unittest.TestSuite()
    loader=unittest.TestLoader()
    package_tests = loader.discover(this_dir,pattern=pattern)
    suite.addTests(package_tests)
    return suite
if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    #test_suite = load_by_testcase()
    #test_suite=load_by_calss()
    test_suite=load_by_pattern("*case.py")
    runner.run(test_suite)
  1. 执行结果
PS D:\Python\program\practic_unittest> python run_testcase.py
testCaseOne
FtestCaseTwo
.F
======================================================================
FAIL: testCaseOne (test_case.testclassOne)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Python\program\practic_unittest\test_case.py", line 9, in testCaseOne
    assert False
AssertionError

======================================================================
FAIL: test1 (test_case.testclassTwo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Python\program\practic_unittest\test_case.py", line 12, in test1
    self.assertTrue(False)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=2)

输出报告

HTMLTestRunner

  • 安装HTMLTestRunner:pip install HTMLTestRunner-Python3
  • 添加和修改如下代码
from HTMLTestRunner import HTMLTestRunner
if __name__ == '__main__':
    testsuite = load_by_pattern("*case.py")
    report_name = 'result_{}.html'.format(time.strftime("%Y.%m.%d_%H_%M_"))
    f=open(report_name,'w',encoding='utf-8')  #最好添加encoding='utf-8'这个参数,避免输出的报告出现中文乱码的情况
    runner = HTMLTestRunner.HTMLTestRunner(stream=f,title='测试报告',description='详情')
    runner.run(testsuite)
  • 输出结果
    HTMLTestRunner输出报告

BeautifulReport

  • 安装BeautifulReport:pip install BeautifulReport
  • 添加和修改如下代码
from BeautifulReport import BeautifulReport
if __name__ == '__main__':
    testsuite = load_by_pattern("*case.py")
    run = BeautifulReport(testsuite)
    report_name ='result_{}.html'.format( time.strftime("%Y.%m.%d_%H_%M_"))
    run.report(description='beautifulreport', filename=report_name)
  • 输出报告
    BeautifulReport 报告

命令行执行

python -m unittest 执行可找到的所有testcase,等价python -m unittest discover
python -m unittest test_module/test_module.TestClass/test_module.TestCalss.test_method 指定运行的模块/类/测试方法
python -m unittest tests/test_something.py 测试模块亦可通过测试文件路径指定
-v:输出详细结果
-f:第一个错误或者失败时就停止测试
-k:只运行匹配的testcase,eg:-k name,只匹配模式或测试方法和类,并且大小写敏感

探索性测试

python -m unittest discover:只会匹配test*.py文件
参数:
-v, --verbose:更详细地输出结果。

-s, --start-directory directory:开始进行搜索的目录(默认值为当前目录 . )。

-p, --pattern pattern:用于匹配测试文件的模式(默认为 test*.py )。

-t, --top-level-directory directory:指定项目的最上层目录(通常为开始时所在目录)

学习文档:https://docs.python.org/3.8/library/unittest.html#

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:47:30  更:2021-07-13 17:48:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 19:31:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码