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)]
相关推荐
Flying_Fish_roe1 天前
Spring Boot-Bean注入问题
spring boot·后端·log4j
SelectDB技术团队2 天前
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
数据结构·数据仓库·elasticsearch·log4j·json
&木头人&6 天前
log4j 的参数配置
log4j
&木头人&7 天前
log4j 1.x 日志输出线程以唯一ID的形式配置
单元测试·log4j
惜.己7 天前
spring项目整合log4j2日志框架(含log4j无法打印出日志的情况,含解决办法)
java·spring·junit·单元测试·log4j·idea
清星QA8 天前
log4j靶场,反弹shell
log4j
&木头人&9 天前
Log4j 1.x如何升级到Log4j 2.x
单元测试·log4j
武昌库里写JAVA10 天前
人工智能,语音识别也算一种人工智能。
java·开发语言·算法·spring·log4j
Zhong-Xin10 天前
vulhub log4j2 CVE-2021-44228漏洞复现
log4j
CoderCodingNo10 天前
log4j 清除MDC上下文 MDC分类日志
log4j