如何使用Python进行单元测试(pycharm单元测试)
itomcoil 2025-07-23 15:16 4 浏览
前言
在我的日常工作中,我是一名专业程序员。我使用c++、c#和Javascript。我是一个开发团队的一员,他们使用单元测试来验证我们的代码是否按照它应该的方式工作。
在本文中,我将通过讨论以下主题来研究如何使用Python创建单元测试。
- 单元测试基础
- 可用的Python测试框架
- 测试设计原则
- 代码覆盖率
单元测试基础
我使用FizzBuzz编码方式创建了单元测试示例。编码类型是程序员的练习。在这个练习中,程序员试图解决一个特定的问题。但主要目标不是解决问题,而是练习编程。FizzBuz是一个简单的代码类型,非常适合解释和展示Python中的单元测试。
单元测试
单元测试是程序员为测试程序的一小部分而编写的自动化测试。单元测试应该运行得很快。与文件系统、数据库或网络交互的测试不是单元测试。
为了在Python中创建第一个FizzBuzz单元测试,我定义了一个继承自unittest.TestCase的类。这个unittest模块可以在Python的标准安装中获得。
import unittest
class FizzBuzzTest(unittest.TestCase):
def test_one_should_return_one(self):
fizzbuzz = FizzBuzz()
result = fizzbuzz.filter(1)
self.assertEqual('1', result)
def test_two_should_return_two(self):
fizzbuzz = FizzBuzz()
result = fizzbuzz.filter(2)
self.assertEqual('2', result)
第一个测试用例验证数字1是否通过了FizzBuzz过滤器,它将返回字符串' 1 '。使用self验证结果。assertEqual方法。方法的第一个参数是预期的结果,第二个参数是实际的结果。
测试用例
我们在测试用例FizzBuzzTest类中调用
test_one_should_return_one()方法。测试用例是测试程序特定部分的实际测试代码。
第一个测试用例验证数字1是否通过了FizzBuzz过滤器,它将返回字符串' 1 '。使用self验证结果。assertEqual方法。方法的第一个参数是预期的结果,第二个参数是实际的结果。
如果您查看这两个测试用例,您会看到它们都创建了FizzBuzz类的一个实例。第一个在第6行,另一个在第11行。
我们可以从这两个方法中重构FizzBuzz实例的创建,从而改进代码。
import unittest
class FizzBuzzTest(unittest.TestCase):
def setUp(self):
self.fizzbuzz = FizzBuzz()
def tearDown(self):
pass
def test_one_should_return_one(self):
result = self.fizzbuzz.filter(1)
self.assertEqual('1', result)
def test_two_should_return_two(self):
result = self.fizzbuzz.filter(2)
self.assertEqual('2', result)
我们使用setUp方法创建FizzBuzz类的实例。TestCase基类的设置在每个测试用例之前执行。
另一个方法tearDown是在每个单元测试执行之后调用的。你可以用它来清理或关闭资源。
测试夹具
方法的设置和拆卸是测试夹具的一部分。测试夹具用于配置和构建被测试单元。每个测试用例都可以使用这些通用条件。在本例中,我使用它创建FizzBuzz类的实例。
要运行单元测试,我们需要一个测试运行器。
测试运行器
测试运行程序是执行所有单元测试并报告结果的程序。Python的标准测试运行器可以使用以下命令在终端上运行。
python -m unittest test_fizzbuzz.py
测试套件
单元测试词汇表的最后一个术语是测试套件。测试套件是测试用例或测试套件的集合。通常一个测试套件包含应该一起运行的测试用例。
单元测试设计
测试用例应该被很好地设计。考试的名称和结构是最重要的。
测试用例名称
测试的名称非常重要。它就像一个总结考试内容的标题。如果测试失败,你首先看到的就是它。因此,名称应该清楚地表明哪些功能不起作用。
测试用例名称的列表应该读起来像摘要或场景列表。这有助于读者理解被测单元的行为。
构造测试用例方法体
一个设计良好的测试用例由三部分组成。第一部分,安排、设置要测试的对象。第二部分,Act,练习被测单元。最后,第三部分,断言,对应该发生的事情提出主张。
有时,我在单元测试中添加这三个部分作为注释,以使其更清楚。
import unittest
class FizzBuzzTest(unittest.TestCase):
def test_one_should_return_one(self):
# Arrange
fizzbuzz = FizzBuzz()
# Act
result = fizzbuzz.filter(1)
# Assert
self.assertEqual('1', result)
每个测试用例的单个断言
尽管在一个测试用例中可能有很多断言。我总是尝试使用单个断言。
原因是,当断言失败时,测试用例的执行就会停止。因此,您永远不会知道测试用例中的下一个断言是否成功。
使用pytest进行单元测试
在上一节中,我们使用了unittest模块。Python的默认安装安装这个模块。unittest模块于2001年首次引入。基于Kent Beck和Eric Gamma开发的流行的Java单元测试框架JUnit。
另一个模块pytest是目前最流行的Python单元测试框架。与unittest框架相比,它更具有python风格。您可以将测试用例定义为函数,而不是从基类派生。
因为pytest不在默认的Python安装中,所以我们使用Python的包安装程序PIP来安装它。通过在终端中执行以下命令,可以安装pytest。
pip install pytest
下面我将第一个FizzBuzz测试用例转换为pytest。
def test_one_should_return_one():
fizzbuzz = FizzBuzz()
result = fizzbuzz.filter(1)
assert '1' == result
有三个不同点。首先,您不需要导入任何模块。其次,您不需要实现一个类并从基类派生。最后,您可以使用标准的Python assert方法来代替自定义的方法。
测试装置
您还记得,单元测试模块使用setUp和tearDown来配置和构建测试中的单元。相反,pytest使用@pytest.fixture属性。在您的测试用例中,您可以使用用该属性装饰的方法的名称作为参数。
pytest框架在运行时将它们连接起来,并将fizzBuzz实例注入测试用例中。
@pytest.fixture
def fizzBuzz():
return FizzBuzz()
def test_one_should_return_one(fizzBuzz):
result = fizzBuzz.filter(1)
assert result == '1'
def test_two_should_return_two(fizzBuzz):
result = fizzBuzz.filter(2)
assert result == '2'
如果您想要模拟单元测试tearDown()方法的行为,可以使用相同的方法来实现。不使用return,而是使用yield关键字。然后,您可以将清理代码放在yield之后。
@pytest.fixture
def fizzBuzz():
yield FizzBuzz()
# put your clean up code here
pytest标记
标记是可以在测试各种函数时使用的属性。例如,如果您将跳过标记添加到您的测试用例中,测试运行器将跳过测试。
@pytest.mark.skip(reason="WIP")
def test_three_should_return_fizz(fizzBuzz):
result = fizzBuzz.filter(3)
assert result == 'Fizz'
pytest插件生态系统
pytest有很多插件可以添加额外的功能。到我写这篇文章的时候,已经有将近900个插件了。例如,pytest-html和pytest-sugar。
pytest-html
pytest- HTML是pytest的插件,它为测试结果生成HTML报告。当您在构建服务器上运行单元测试时,这非常有用。
pytest-sugar
pytest-sugar改变pytest的默认外观和感觉。它会添加一个进度条,并立即显示失败的测试。
创建代码覆盖率报告
有一些工具可以创建代码覆盖率报告。这个代码覆盖率报告显示了您的单元测试执行了哪些代码。
我使用Coverage和pytest-cov来创建代码覆盖率报告。覆盖率是度量代码覆盖率的通用包。模块pytest-cov是pytest的一个插件,用于连接到Coverage。
都可以使用pip安装。
pip install coverage
pip install pytest-cov
在您安装了这两个命令之后,您可以使用这两个命令生成覆盖率报告。在终端或命令中运行它们。
coverage run -m pytest
coverage html
第一个生成覆盖率数据。第二个命令将数据转换为HTML报告。Coverage将报告存储在文件系统的htmlcov文件夹中。
如果你在浏览器中打开index.html,它会显示每个文件覆盖率的概览。
如果您选择一个文件,它将显示下面的屏幕。覆盖率向源代码添加了一个指示,显示单元测试覆盖了哪一行。
下面我们看到我们的单元测试并没有涵盖第12行和第16行。
分支覆盖度量
覆盖率还支持分支覆盖率度量。有了分支覆盖率,如果您的程序中有一行可以跳转到下一行以上,覆盖率跟踪是否访问了这些目的地。
您可以通过执行以下命令来创建带有分支覆盖率的覆盖率报告。
pytest——cov-report html:htmlcov——cov-branch——cov=alarm
我指示pytest生成一个带有分支覆盖的HTML覆盖报告。它应该将结果存储在htmlcov中。而不是为所有文件生成覆盖率报告,我告诉覆盖率只使用alarm.py。
相关推荐
- Python自动化——pytest常用插件详解
-
前言Pytest是Python的一种单元测试框架,与unittest相比,使用起来更简洁、效率更高,也是目前大部分使用python编写测试用例的小伙伴们的第一选择了。除了框架本身提供的功能外,Pyte...
- 全网最全pytest大型攻略,单元测试学这就够了
-
pytest是一款以python为开发语言的第三方测试,主要特点如下:比自带的unittest更简洁高效,兼容unittest框架支持参数化可以更精确的控制要测试的测试用例丰富的插件,已有30...
- Python Logging 最佳实践(python logging配置)
-
Pythonlogging的“最佳实践”可以概括为一句话:让日志既能在开发时帮你排错,也能在生产里帮你定位问题,同时不给运维埋坑。下面给出一份可直接落地的checklist,分场景逐条说明。1....
- Python单元测试框架对比(python中unittest框架)
-
一、核心框架对比特性unittest(标准库)pytest(主流第三方)nose2(unittest扩展)doctest(文档测试)安装Python标准库pipinstallpytestp...
- 如何使用Python进行单元测试(pycharm单元测试)
-
前言在我的日常工作中,我是一名专业程序员。我使用c++、c#和Javascript。我是一个开发团队的一员,他们使用单元测试来验证我们的代码是否按照它应该的方式工作。在本文中,我将通过讨论以下主题来研...
- Python单元测试(pycharm单元测试)
-
1.单元测试概述1.1什么是单元测试单元测试(UnitTesting)是指对软件中的最小可测试单元进行检查和验证的过程。在Python中,最小单元通常指函数、方法或类。1.2单元测试的特性独立...
- pytest框架之fixture测试夹具详解
-
前言大家晚上好呀,今天呢来和大家唠唠pytest中的fixtures夹具的详解,废话就不多说了咱们直接进入主题哈。一、fixture的优势pytest框架的fixture测试夹具就相当于unitte...
- Pytest精髓Fixture功能实例!测试效率暴涨!
-
前言大家好!我们今天来学习Python测试框架中的最具特色的功能之一:Fixture。可以说,掌握了Fixture,你就掌握了Pytest的精髓。它不仅能让你的测试代码更简洁、更优雅、更易于...
- Python最常见的170道面试题全解析答案(二)
-
60.请写一个Python逻辑,计算一个文件中的大写字母数量答:withopen(‘A.txt’)asfs:count=0foriinfs.read():ifi.isupper...
- 为什么python高手都爱用闭包?这个实时函数技巧绝了
-
杂谈我想很多人都玩过python的闭包,其中最有趣的部分应该就是装饰器了。但我想很多人应该没运用上闭包的特性——外部局部变量的存储。什么意思呢?其实就是当闭包引用外部的局部变量将会被存储起来,而不会随...
- 春节停车难?用Python找空车位(用python编写停车场停车收费)
-
【导语】今天这篇文章的选题非常贴近生活。营长生活在北京,深知开车出门最怕的就是堵车和找不到停车位。记得冬至那个周末,几个小伙伴滑雪回来找了一家饺子馆吃饺子,结果七拐八拐,好不容易才找到一个停车位。看到...
- PYTHON数据分析必备知识(2)(python数据分析范例)
-
1.二分钟快速给项目添加日志信息"""给项目添加日志信息"""#导Python内置包importloggingimporttime...
- 春节回家!车位难求啊!看我用Python自动寻找空车位!
-
作者通过相机结合深度学习算法,基于Python语言建立一个高精度的停车位的通知系统,每当有新停车位时就会发短信提醒我。听起来好像很复杂,真的方便实用吗?但实际上所使用的工具都是现成的,只要将这些工...
- “==”和“is”有什么区别?一个问题就能暴露你的Python水平
-
可能在网上你经常能看到关于这个问题的答案和解析,但是依然有很多刚开始学习Python的人,不了解这个问题,也不知道为什么问这个问题时会暴露自己是“菜鸟”,这个问题就是:“==”和“is”之间有什么...
- Python条件语句怎么用(python中条件语句的用法)
-
if条件判断语句python语句是按固定顺序执行的,先执行前面的语句,再执行后面的语句。如果你像要程序按照你自己定制的流程执行,就需要用到流程控制的语句,最主要用到的是条件语句和循环语句。条件语句...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)