什么是Python代码测试,为什么它很重要?
在软件开发的生命周期中,测试你的代码是必不可少的。因此,选择--和使用--正确的Python测试工具也应该是编写高质量代码的一个重要部分。
编写测试代码并并行运行,现在被认为是一种良好的做法(这常常被初学者跳过)。通过明智地实施,测试将有助于更精确地定义你的代码的意图,并有一个更解耦的架构。如果你不在你的Python代码到达你的最终用户之前对其进行检查,那么如果程序中有Bug,你就有可能失去他们的好感,或者更糟糕的是,完全破坏了你的应用程序的声誉,所以首先就没有人愿意使用它。
软件开发生命周期的测试阶段帮助企业在实施阶段之前确定软件中的所有错误和瑕疵。
软件开发生命周期的测试阶段有助于企业在实施阶段之前确定软件中的所有错误和误差。如果软件的错误在部署前没有得到解决,它们会对客户的业务产生不利影响。
此外,试图在后期阶段解决这些问题会导致大量成本。你推迟检测这些问题的时间越长,你可能面临的成本就越大。
以下是你应该进行的不同类型的测试,通常以金字塔的形式表示。
图片来源:Albin Larsson(@Abbe98,维基百科)。
你在金字塔上走得越低,被测试的代码单元就越小,你应该有更多的测试。例如,一个UI(E2E)测试阶段可能会测试创建、编辑、然后保存文档的流程。这个流程是由许多不同的功能组成的,每一个都应该有自己的单元测试。
在这篇文章中,我们将把范围限制在Python的内置单元测试框架上。
如果你正在寻找关于Python剖析工具的文章,请阅读这里。
Python 是否有一个内置的单元测试库?
Python标准库提供了unittest作为一个内置的单元测试框架。unittest 框架受到了 Java 中 JUnit 的启发,与其他编程语言中的主要单元测试框架有相似的味道。
它允许测试自动化,共享测试设置和关闭的代码,将测试分组为集合,以及测试与报告框架的独立性。
下面是以面向对象的方式介绍unittest的一些重要概念。
| 测试夹具 | 代表执行一个或多个测试所需的准备,以及任何相关的清理动作。这可能包括制作临时或代理数据库、目录或启动服务器进程等内容。 |
| 测试案例 | 单独的测试单元。它寻找对一组特定输入的特定响应。 unittest 包括一个称为 TestCase 的基类,可用于创建新的测试用例。 |
| 测试套件 | 一个测试用例、测试套件或两者的集合。它用于对应该一起运行的测试进行分组。 |
| 测试运行器 | 一个协调测试执行并向用户报告结果的组件。为了表示运行测试的结果,运行器可以使用一个图形界面,一个文本界面,或返回一个特殊值。 |
我如何获得 unittest 库?
由于 unittest 是一个内置的 Python 单元测试库,不需要进一步安装。
如何用 unittest Python 测试工具进行单元测试?
下面是一个测试三串方法的简短脚本 (来源:docs.python.org)。
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
创建测试用例是通过子类化 unittest.TestCase 完成的。上面的代码有三个单独的测试,它们是。
- **test_upper。**测试我们是否能够成功地将字符串的大小写改为大写。
- **test_isupper。**验证给定字符串的条件是否为大写。
- test_split:检 查预期的结果,即我们是否成功地分割了给定的字符串输入。
执行测试的命名惯例是为了告知测试运行器哪些方法代表测试。
每个测试的核心是调用assertEqual(),检查一个预期的结果;assertTrue()或assertFalse(),验证一个条件;或assertRaises(),验证一个特定的异常被提出。这些方法被用来代替assert语句,使测试运行器能够编译所有的测试结果并生成报告。
下面是PyScripter IDE上的输出。
将上面的脚本保存为01_testThreeStringMethods.py,让我们在下一节尝试从命令提示符下进行单元测试。
如何在运行时进行Python单元测试?
下面是运行Python unittest的命令。
python -m unittest 01_testThreeStringMethods.py
或者你可以像这样专门调用你的测试类。
python -m unittest 01_testThreeStringMethods.TestStringMethods
如果想得到更详细的结果(更高的粗略性),可以通过这个-v标志。
python -m unittest -v 01_testThreeStringMethods.py
或者你也可以使用这个命令。
python -m unittest -v 01_testThreeStringMethods.TestStringMethods
一个失败的Python单元测试是什么样子的?
试试下面的代码,看看 unittest 的失败会是什么样子 (来源:realpython.com)。
import unittest
class TestSum(unittest.TestCase):
def test_sum(self):
self.assertEqual(sum([1, 2, 3]), 6, "Should be 6")
def test_sum_tuple(self):
self.assertEqual(sum((1, 2, 2)), 6, "Should be 6")
if __name__ == '__main__':
unittest.main()
如果你执行上面的代码,你会看到一个成功(用 . 表示)和一个失败(用 F 表示)。下面是PyScripter IDE上的输出。
如何用unittest进行测试跳过和期待失败?
Unittest允许你跳过单个测试方法以及整个测试类。此外,它还支持将一个测试标记为 "预期失败",这是一个会失败的破损测试,但不应该被算作TestResult的失败。
试试下面的代码,看看 unittest 中的跳过测试和预期失败的输出是什么样子的(下面的代码是从 docs.python.org 修改的,向你展示一系列测试中的不同测试输出)。
import unittest
import tensorflow
import sys
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(tensorflow.__version__ == "3.0.0", "not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# Windows specific testing code
pass
@unittest.expectedFailure
def test_maybe_skipped(self):
if not external_resource_available():
# Test code that depends on the external resource,
# and expecting failure due to external resource not available
pass
这是在verbose模式下运行上述例子的输出。
python -m unittest -v 03_skippingTestsAndExpectedFailures.py
我们得到了2个OK,1个跳过的测试,和1个预期失败。
unittest提供的命令行选项有哪些?
unittest支持这些命令行选项。
-h, -help
要访问所有命令行选项的列表。下面是要做的命令。
python -m unittest -h
-b, -buffer
在测试运行期间,标准输出和标准错误流被缓冲。测试通过时的输出被丢弃。在测试失败或出错时,输出被正常回显,并被添加到失败信息中。
-c, -catch
在测试运行期间,Control-C等待当前的测试完成,然后报告到目前为止的所有结果。
第二个Control-C会引发正常的KeyboardInterrupt异常
-f, -failfast
在第一次出错或失败时,测试被终止。
-k
只有符合模式或子串的测试方法和类才会被执行。这个选项可以多次使用,在这种情况下,所有匹配任何给定模式的测试案例都被包括在内。
包含通配符(*)的模式使用fnmatch.fnmatchcase()与测试名称匹配;否则使用简单的大小写子串匹配。
模式与测试加载器导入的完全合格的测试方法名称相匹配。
例如,-k foo 匹配 foo_tests.SomeTest.test_something、bar_tests.SomeTest.test_foo,但不匹配 bar_tests.FooTest.test_something。
-局部变量
在回溯中显示局部变量。
很神奇,不是吗?现在你可以使用 unittest 轻松地测试你的 Python 代码了。
恭喜你,现在你已经了解了内置的Python测试工具!现在你可以实现它,写出更专业的代码,在交付给用户之前进行很好的测试!
点击这里开始使用 PyScripter这是一个免费的、功能丰富的、轻量级的Python开发者IDE。
下载RAD Studio 来构建更强大的Python GUI Windows应用程序,以更少的代码加快5倍的速度。
查看 Python4Delphi 它可以让你轻松地使用Delphi为Windows构建Python GUI。
另外,请查看 DelphiVCL 它可以让你轻松地使用Python为Windows建立GUI。
The post TheComprehensive Guide To Built-in Python Testing Toolsfirst appeared onPython GUI.