测试代码模块
编写函数或类时,还可为其编写测试。通过测试,可确定代码面对各种输入都能够按要求的那样工作。在程序中添加新代码时,你也可以对其进行测试,确认它们不会破坏程序既有的行为。 使用Python模块unittest 中的工具来测试代码 【注意】:测试代码所在的类,必须继承unittest.TestCase继承类
(1)单元测试与测试用例 Python标准库中的模块unittest提供了代码测试工具。 1、单元测试用于核实函数的某个方面没有问题; 2、测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。 良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试。 3、全覆盖式测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。 对于大型项目,要实现全覆盖可能很难。通常,最初只要针对代码的重要行为编写测试即可,等项目被广泛使用时再考虑全覆盖。(一般都做不到)
(2)可通过的测试 创建测试用例的语法需要一段时间才能习惯,但测试用例创建后,再添加针对函数的单元测试就很简单了。 【编写函数测试模块语法】: 要为函数编写测试用例,可先导入模块unittest 以及要测试的函数,再创建一个继承unittest.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试。
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
(3)断言方法 使用了unittest 类最有用的功能之一:一个断言方法。断言方法用来核实得到的结果是否与期望的结果一致,即检查你认为应该满足的条件是否确实满足。 例如:
self.assertEqual(formatted_name, ‘Janis Joplin’) 我们调用unittest 的方法assertEqual() ,并向它传递formatted_name 和’Janis Joplin’ 。代码行self.assertEqual(formatted_name, ‘Janis Joplin’) 的意思是 说:“将formatted_name 的值同字符串’Janis Joplin’ 进行比较。
(4)重复进行测试 修改自己的函数,既可实现重复测试
(5)运行测试文件 代码行unittest.main()让Python运行这个文件中的测试代码。
A、通过测试结果如下:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
B、不能通过的测试结果如下:
E
======================================================================
ERROR: test_first_last_name (__main__.NamesTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_name_function.py", line 8, in test_first_last_name
formatted_name = get_formatted_name('janis', 'joplin')
TypeError: get_formatted_name() missing 1 required positional argument: 'last'
-----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
(6)测试未通过则么办? 如果你检查的条件没错,测试通过了意味着函数的行为是对的,而测试未通过意味着你编写的新代码有错。因此,测试未通过时,不要修改测试,而应修复导致测试不能通过的代码:检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。
(7)添加新测试函数 可根据具体的项目开发需求,编写多个测试函数,进行方法测试
(8)类测试 前面主要介绍了针对单个函数的测试,下面来编写针对类的测试。很多程序中都会用到类,因此能够证明你的类能够正确地工作会大有裨益。如果针对类的测试通过 了,你就能确信对类所做的改进没有意外地破坏其原有的行为。
A、常见断言方法: 必须在unittest类中使用,所以必须继承 Python在unittest.TestCase 类中提供了很多断言方法。前面说过,断言方法检查你认为应该满足的条件是否确实满足。如果该条件确实满足,你对程序行为的假设就得到了 确认,你就可以确信其中没有错误。如果你认为应该满足的条件实际上并不满足,Python将引发异常。 上表中主要举例的方法,必须在unittest.TestCase类中使用
B、测试类的实现 类的测试与函数的测试相似——你所做的大部分工作都是测试类中方法的行为,但存在一些不同之处。
import unittest
from survey import AnonymousSurvey
class TestAnonmyousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""
def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.store_response('English')
self.assertIn('English', my_survey.responses)
unittest.main()
【小tips】: 类测试和函数测试主要过程是一样的,类测试是通过测试类中的每一个函数,进行类中每一个方法的测试,来实现最终的类测试。 在调用方法时,需先对类进行实例化,然后通过实例化的对象调用类中的方法,进行测试。
(9)方法setUp() unittest.TestCase 类包含方法setUp(),让我们只需创建这些对象一次,并在每个测试方法中使用它们。如果你在TestCase 类中包含了方法setUp() ,Python将先运行它,再运行各个以test_打头的方法。 重写unittest.TestCase类(父类)中的setUp() 函数,在该函数中创建对象。使用setup()函数,可以简化创建对象的步骤,在每次运行测试代码时,Python将最先运行setup()函数,然后再运行各个test_打头的方法。 【优势】: 测试自己编写的类时,方法setUp() 让测试方法编写起来更容易:可在setUp() 方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例。相比于在每个 测试方法中都创建实例并设置其属性,这要容易得多。
|