总结:
如何编写继承unittest.TestCase的类,以及如何编写测试方法,以核实函数和类的行为符合预期;
如何使用方法setUp()来根据类高效地创建实例并设置其属性,以便在类的所有测试方法中都可使用它们。
测试是很多初学者都不熟悉的主题。作为初学者,并非必须为你尝试的所有项目编写测试;但参与工作量较大的项目时,你应对自己编写的函数和类的重要行为进行测试。这样你就能够更加确定自己所做的工作不会破坏项目的其他部分,你就能够随心所欲地改进既有代码了。如果不小心破坏了原来的功能,你马上就会知道,从而能够轻松地修复问题。相比于等到不满意的用户报告bug后再采取措施,在测试未通过时采取措施要容易得多。
如果你在项目中包含了初步测试,其他程序员将更敬佩你,他们将能够更得心应手地尝试使用你编写的代码,也更愿意与你合作开发项目。如果你要跟其他程序员开发的项目共享代码,就必须证明你编写的代码通过了既有测试,通常还需要为你添加的新行为编写测试。
请通过多开展测试来熟悉代码测试过程。对于自己编写的函数和类,请编写针对其重要行为的测试,但在项目早期,不要试图去编写全覆盖的测试用例,除非有充分的理由这样做。
动手试一试
下面这些不是我亲手码的代码,是书本自带的。
11-1 城市和人家
city_functions.py:
"""A collection of functions for working with cities."""
def city_country(city, country):
"""Return a string like 'Santiago, Chile'."""
return(city.title() + ", " + country.title())
Note: This is the function we wrote in Exercise 8-6.
test_cities.py:
import unittest
from city_functions import city_country
class CitiesTestCase(unittest.TestCase):
"""Tests for 'city_functions.py'."""
def test_city_country(self):
"""Does a simple city and country pair work?"""
santiago_chile = city_country('santiago', 'chile')
self.assertEqual(santiago_chile, 'Santiago, Chile')
unittest.main()
Output:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
11-2人口数量
Modified city_functions.py, with required population parameter:
"""A collection of functions for working with cities."""
def city_country(city, country, population):
"""Return a string like 'Santiago, Chile - population 5000000'."""
output_string = city.title() + ", " + country.title()
output_string += ' - population ' + str(population)
return output_string
Output from running test_cities.py:
E
======================================================================
ERROR: test_city_country (__main__.CitiesTestCase)
Does a simple city and country pair work?
----------------------------------------------------------------------
Traceback (most recent call last):
File "pcc\solutions\test_cities.py", line 10, in test_city_country
santiago_chile = city_country('santiago', 'chile')
TypeError: city_country() missing 1 required positional argument: 'population'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Modified city_functions.py, with optional population parameter:
"""A collection of functions for working with cities."""
def city_country(city, country, population=0):
"""Return a string representing a city-country pair."""
output_string = city.title() + ", " + country.title()
if population:
output_string += ' - population ' + str(population)
return output_string
Output of running test_cities.py:
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Modified test_cities.py:
import unittest
from city_functions import city_country
class CitiesTestCase(unittest.TestCase):
"""Tests for 'city_functions.py'."""
def test_city_country(self):
"""Does a simple city and country pair work?"""
santiago_chile = city_country('santiago', 'chile')
self.assertEqual(santiago_chile, 'Santiago, Chile')
def test_city_country_population(self):
"""Can I include a population argument?"""
santiago_chile = city_country('santiago', 'chile', population=5000000)
self.assertEqual(santiago_chile, 'Santiago, Chile - population 5000000')
unittest.main()
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
11-3雇员
employee.py:
class Employee():
"""A class to represent an employee."""
def __init__(self, f_name, l_name, salary):
"""Initialize the employee."""
self.first = f_name.title()
self.last = l_name.title()
self.salary = salary
def give_raise(self, amount=5000):
"""Give the employee a raise."""
self.salary += amount
test_employee.py:
import unittest
from employee import Employee
class TestEmployee(unittest.TestCase):
"""Tests for the module employee."""
def setUp(self):
"""Make an employee to use in tests."""
self.eric = Employee('eric', 'matthes', 65000)
def test_give_default_raise(self):
"""Test that a default raise works correctly."""
self.eric.give_raise()
self.assertEqual(self.eric.salary, 70000)
def test_give_custom_raise(self):
"""Test that a custom raise works correctly."""
self.eric.give_raise(10000)
self.assertEqual(self.eric.salary,
75000)
unittest.main()
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK