Unittest框架

Unittest框架

单元测试概述

定义:单元测试是指开发者写的一小段代码,再为集成到一起的时候。进行的测试

什么时间段测试:极限测试,越早越好,因为越早介入发现问题的就越早;边开发边测试

**谁发起:**一般多是开发发起
**单元测试规则:**案例中的预期结果要根据实际开发的逻辑与需求来写;不能按照开发实现的预期进行设计案例

单元测试目前现状

  • Unittest:python的标准库,和java的Unit类似(常用于单元测试)

  • Pytest:第三方库,更加灵活,可议结合allure生成测试报告

  • Nose:是对Unittest的扩展

  • Mock:标准库,用俩测试python的库
    单元测试覆盖率

  • 代码覆盖率用来度量测试是否全面的指标之一,应用覆盖率的思想增强测试用例的设计

  • 单元测试覆盖类型

    • 语句覆盖
    • 条件覆盖
    • 判断覆盖
    • 路径覆盖
复制代码
def demo_method(a,b,x):
	if (a>1 and b==0):
		x=x/a
	if (a==2 or x>1):
		x=x+1
	return x

语句覆盖

  • 语句覆盖定义

    • 通过设计一定量的测试用例,保证测试方法每一行代码都会被执行一遍
    • 运行测试用例的时候被击中的代码行即称为被覆盖的语句
  • 测试用例

    • 仅需要一条case,即可实现覆盖
    • a=3,b=0,x=3
  • 漏洞

    • and ->or
  • 行覆盖是一个最基础的覆盖方式,但也是最薄弱的,如果完全依赖行覆盖,会出现很严重的问题
    判断覆盖

  • 判断覆盖定义

    • 运行测试用例的过程被击中的判定语句
  • 测试用例

Test Case a b c (a>1)&&(b==0) a==2or x>1 ExcutaPath
Case1 2 0 3 T T 135
Case2 1 0 1 F F 124
Case3 3 0 3 T F 134
Case4 231 F T 125
  • 漏洞

    • 大部分的判定语句是由多个逻辑条件组成的,若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径
    • a2 or x>1 -> a2 or x<1
      t条件覆盖:
  • 定义

    • 条件覆盖和判定覆盖类似,不过判定覆盖关注整个判定语句,而条件覆盖则关注某个判断条件
  • 测试用例: if (a<1 and b==0)

TestCase a>1 b==0
Case1 T F
Case2 T F
Case3 F T
Case4 F F
  • 缺陷

    • 测试用例指数级增加(2**conditio0ns)
      路径覆盖
  • 定义

    • 覆盖所有可能执行的路经
  • 测试用例

    TestCase a b x ExcultPath
    Case1 2 0 3 1 3 5
    Case2 1 0 1 1 2 4
    Case3 3 0 3 1 3 4
    Case4 2 1 1 1 2 5
  • 应用这些方法设计测试用例

unittest框架介绍

  • python自带的单元测试框架,常用在单元测试
  • 在自动化的测试中提供用例组织与执行
  • 提供丰富的的断言方法-验证函数等功能
  • 加上HTMLTestRunner可以生成html的报告

Unittest编写与规范

  • unittest提供了testcase、testsuites、test fixtures、test runner的相关组件
  • 编写规范
    • 测试模块首先inport unittest
    • 测试类必须继承unittest.TestCase
    • 测试方法必须以"test_"开头
    • 模块名字,类名字没有特殊要求

测试框架结构

  • 总结:
    • setup用来为测试准备环境,teardown用来清理环境
    • 如果想要在所有case执行之前准备一次环境,并非所有case执行结束之后再清理环境,我们可以用setupclass()与teardown();比如数据库连接及销毁
    • 如果有些方法不在本次执行使用@unittest.skip
    • 测试方法的命名以test开头
    • 各种执行-单一用力,全部

unittest实战

###案例一

python 复制代码
import unittest


class demo(unittest.TestCase):
    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        self.assertEqual(1, 2, "判断相等")


if __name__ == '__main__':
    unittest.main()
执行后代码

案例二

python 复制代码
import unittest


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


if __name__ == '__main__':
    unittest.main()

执行后代码

案例三

python 复制代码
import unittest


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    @unittest.skipIf(1 + 1 == 2, "跳过这个版本")
    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


if __name__ == '__main__':
    unittest.main()

执行后代码

Unittest断言

Unittest执行测试用例

  • 多个测试用例的集合就是测试套件,通过测试套件来管理多个测试用例
  • 执行方法一:
    • unittest.main()
  • 执行方法二:加入容器中执行
    • suite=unittest.TestSuite()
    • suite.addTest(TestMethod("test_01"))
    • suite.addTest(TestMethod("test_02"))
    • unittest.TextTestRunner().run(suite)
  • 执行方法三:此用法可以同时测试多个类
    • suite1=unittest.TestLoader().loadTestsFromTestCase(TestCase1)
    • suite1=unittest.TestLoader().loadTestsFromTestCase(TestCase2)
    • suite=unittest.TestSuite([suite1,suite2])
    • unittest.TextTestRunner(verbosity=2).run(suite)
  • 执行方法四:匹配某个目录下所有以test开头的py文件,执行这些文件下的所有测试用例
    • test_dir="./test_case"
    • discover=unittest.defaultTestLoader.discover(test_dir,pattern="test*.py")
      • discover 可以一次调用多个脚本
      • test_dir 被测试脚本的路径
      • pattern 脚本名称匹配规则

测试用例执行过程

测试报告

  • unittest结合htmltestrunner生成带日志的测试报告
python 复制代码
import unittest

# from HTMLTestRunner.HTMLTestRunner import HTMLTestRunner
from HTMLTestRunner.HTMLTestRunner import HTMLTestRunner


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    @unittest.skipIf(1 + 1 == 2, "跳过这个版本")
    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


class demo1(unittest.TestCase):
    def test_01(self):
        print("test01")

    def test_02(self):
        print("test02")


if __name__ == '__main__':
    # 方法一
    # unittest.main()
    # 方法二
    # suite = unittest.TestSuite()
    # suite.addTest(demo("test_case02"))
    # suite.addTest(demo1("test_02"))
    # unittest.TextTestRunner().run(suite)
    # # 方法三
    # suite = unittest.TestLoader().loadTestsFromTestCase(demo)
    # suite1 = unittest.TestLoader().loadTestsFromTestCase(demo1)
    # suite2 = unittest.TestSuite([suite, suite1])
    # unittest.TextTestRunner().run(suite2)
    # # 方法四
    # discover = unittest.defaultTestLoader.discover(".", "test*.py")
    # unittest.TextTestRunner().run(discover)
    # 方法五   ,encoding="utf-8"
    suiteall = unittest.TestSuite()
    suiteall.addTest(unittest.TestLoader().loadTestsFromTestCase(demo))
    suiteall.addTest(unittest.TestLoader().loadTestsFromTestCase(demo1))

    report_title = "Example用例执行报告"
    desc = "用于展示修改样式后的HTMLTestRunner"
    report_file = "./Examplereport.html"
    with open(report_file, "w",encoding="utf-8") as report:
        runner = HTMLTestRunner(stream=report, title=report_title
                                , description=desc)
        runner.run(suiteall)

实战一

python 复制代码
import unittest


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    @unittest.skipIf(1 + 1 == 2, "跳过这个版本")
    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


class demo1(unittest.TestCase):
    def test_01(self):
        print("test01")

    def test_02(self):
        print("test02")


if __name__ == '__main__':
    # 方法一
    # unittest.main()
    # 方法二
    suite=unittest.TestSuite()
    suite.addTest(demo("test_case02"))
    suite.addTest(demo1("test_02"))
    unittest.TextTestRunner().run(suite)

执行后代码

实战二

python 复制代码
import unittest


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    @unittest.skipIf(1 + 1 == 2, "跳过这个版本")
    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


class demo1(unittest.TestCase):
    def test_01(self):
        print("test01")

    def test_02(self):
        print("test02")


if __name__ == '__main__':
    # 方法一
    # unittest.main()
    # 方法二
    # suite = unittest.TestSuite()
    # suite.addTest(demo("test_case02"))
    # suite.addTest(demo1("test_02"))
    # unittest.TextTestRunner().run(suite)
    # 方法三
    suite = unittest.TestLoader().loadTestsFromTestCase(demo)
    suite1 = unittest.TestLoader().loadTestsFromTestCase(demo1)
    suite2 = unittest.TestSuite([suite, suite1])
    unittest.TextTestRunner().run(suite2)

执行后代码

实战三

python 复制代码
import unittest


class demo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setupclass")

    @classmethod
    def tearDownClass(cls) -> None:
        print("teardowmclass")

    def setUp(self) -> None:
        print("setup")

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

    def test_case01(self):
        print("testcase01")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    def test_case02(self):
        print("testcase02")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")

    @unittest.skipIf(1 + 1 == 2, "跳过这个版本")
    def test_case03(self):
        print("testcase03")
        # self.assertEqual(1, 2, "判断相等")
        self.assertIn("h", "this", "判断是否包含")


class demo1(unittest.TestCase):
    def test_01(self):
        print("test01")

    def test_02(self):
        print("test02")


if __name__ == '__main__':
    # 方法一
    # unittest.main()
    # 方法二
    # suite = unittest.TestSuite()
    # suite.addTest(demo("test_case02"))
    # suite.addTest(demo1("test_02"))
    # unittest.TextTestRunner().run(suite)
    # # 方法三
    # suite = unittest.TestLoader().loadTestsFromTestCase(demo)
    # suite1 = unittest.TestLoader().loadTestsFromTestCase(demo1)
    # suite2 = unittest.TestSuite([suite, suite1])
    # unittest.TextTestRunner().run(suite2)
    # 方法四
    discover=unittest.defaultTestLoader.discover(".","test*.py")
    unittest.TextTestRunner().run(discover)

执行后代码

te()

suite.addTest(demo("test_case02"))

suite.addTest(demo1("test_02"))

unittest.TextTestRunner().run(suite)

# 方法三

suite = unittest.TestLoader().loadTestsFromTestCase(demo)

suite1 = unittest.TestLoader().loadTestsFromTestCase(demo1)

suite2 = unittest.TestSuite([suite, suite1])

unittest.TextTestRunner().run(suite2)

方法四

discover=unittest.defaultTestLoader.discover(".","test*.py")

unittest.TextTestRunner().run(discover)

复制代码
### 执行后代码

[外链图片转存中...(img-7LmCyZRF-1725267749916)]
相关推荐
ACGkaka_1 天前
Spring Boot实战(三十六)编写单元测试
spring boot·单元测试·log4j
forestsea12 天前
分布式日志治理:Log4j2自定义Appender写日志到RocketMQ
java·log4j·java-rocketmq
遥不可及~~斌15 天前
Spring Boot 项目日志系统全攻略:Logback、Log4j2、Log4j与SLF4J整合指南
spring boot·log4j·logback
weixin_4383354015 天前
SpringBoot依赖冲突引发的 log4j 日志打印问题及解决方法
spring boot·单元测试·log4j
我是坑货16 天前
maven的项目管理和构建生命周期
java·log4j·maven
凭君语未可24 天前
详解Maven的主要生命周期
java·log4j·maven
WIN赢25 天前
单元测试的编写
单元测试·log4j
zerohawk1 个月前
【log4j】配置Slf4j
junit·单元测试·log4j
熬了夜的程序员1 个月前
Go 语言封装邮件发送功能
开发语言·后端·golang·log4j
故事与他6451 个月前
Apache中间件漏洞攻略
java·服务器·安全·网络安全·中间件·log4j·apache