目录
1.测试工具
在程序中,我们需要编写大量的测试来确保每个细节都没有问题,此时我们可以借助于一些测试模块。目前有两个杰出的模块可以替我们自动完成测试过程:unittest和doctest。相比于doctest,unittest更加灵活强大,因此我们在实践中大部分使用unittest。
1.1 unittest
假设我们有一个名为my_math的模块,其中包含一个计算乘积的函数product。我们使用模块unittest中的TestCase类编写一个测试:
import unittest, my_math
class ProductTestCase(unittest.TestCase):
def test_integers(self):
for x in range(-10, 10):
for y in range(-10, 10):
p = my_math.product(x, y)
self.assertEqual(p, x * y, 'Fail!')
def test_floats(self):
for x in range(-10, 10):
for y in range(-10, 10):
x = x / 10
y = y / 10
p = my_math.product(x, y)
self.assertEqual(p, x * y, 'Fail!')
if __name__ == '__main__':
unittest.main()
函数unittest.main负责实例化所有的TestCase子类,并运行所有名称以test打头的方法。如果定义了方法setUp和tearDown,它们将分别在每个测试方法之前和之后进行执行。我们可以使用这些方法来执行适用于所有测试的初始化代码和清理代码,这些代码称为测试夹具。
2.常量配置
所谓常量,指的是内置的字面量值,如数、字符串和列表。对于这些值,可以将其存储在全局变量中,而不在程序中反复输入它们。常量遵循特殊的命名约定:只在变量名中使用大写字母并用下划线分隔单词。
我们可以将配置常量放到独立的文件中,为此最简单的方式是专门为配置创建一个模块。例如,如果PI是在模块文件config.py中设置的,就可以在主程序中像下面这样做:
from config import PI
另外一种方式是使用标准库模块configparser,从而可在配置文件中使用标准格式。这样既可使用Python标准赋值语法,如:
greeting = 'Hello'
也可使用另外一种配置格式:
greeting:Hello
我们必须使用标题将配置文件分成几部分,标题的名称可随便指定,但必须将他们用方括号括起。一个简单的配置文件如下:
[numbers]
pi: 3.1415926535897931
[messages]
greeting: Welcome to the area calculation program!
question: Please enter the radius:
result_message: The area is
一个使用ConfigParser的程序:
from configparser import ConfigParser
CONFIGFILE = "area.ini"
config = ConfigParser()
# 读取配置文件:
config.read(CONFIGFILE)
# 打印默认问候语( greeting):
# 在messages部分查找问候语:
print(config['messages'].get('greeting'))
# 使用配置文件中的提示( question)让用户输入半径:
radius = float(input(config['messages'].get('question') + ' '))
# 打印配置文件中的结果消息( result_message);
# 以空格结束以便接着在当前行打印:
print(config['messages'].get('result_message'), end=' ')
# getfloat()将获取的值转换为浮点数:
print(config['numbers'].getfloat('pi') * radius**2)
3. 日志
日志主要用于收集与程序运行相关的数据,供我们进行研究或积累。我们可以使用标准库中的模块logging。实例代码如下:
import logging
logging.basicConfig(level=logging.INFO, filename='mylog.log')
logging.info('Starting program')
logging.info('Trying to divide 1 by 0')
print(1 / 0)
logging.info('The division succeeded')
logging.info('Ending program')
运行该程序以后,将生成下面的日志文件(mylog.log):
INFO:root:Starting program
INFO:root:Trying to divide 1 by 0
通过合理地配置模块logging,可让日志以你希望的方式运行。下面是几个这样的示例。
- 记录不同类型的条目(信息、调试信息、警告、自定义类型等)。默认情况下,只记录警告。
- 只记录与程序特定部分相关的条目。
- 记录有关时间、日期等方面的信息。
- 记录到其他位置,如套接字。
- 配置日志器,将一些或大部分日志过滤掉,这样无需重写程序就能获得所需的日志信息