我对单元测试不是很熟悉,我只是从学习如何做到这一步开始。也许我还没有真正理解单元测试和TDD的原理,这也是我感到困难的原因。
要测试的代码如下所示:
class DevelopingMyClass:
def __init__(self):
self.firstAttribute = None
def openGivenFile(self, filename):
f = open(filename, 'r')
return f
def transformInput(self, filename):
res = self.openGivenFile(filename)
for line in res.readlines():
newLine = line.replace('a', 'z')
print(newLine)
# start
myClass = DevelopingMyClass()
myClass.transformInput('testfile.txt')
当然,这个程序没有任何意义。我只想弄明白:
答案 0 :(得分:0)
单元测试在开发过程中提供帮助的原因之一是它们可以揭示您的接口是否设计正确。将单元测试视为想要使用您设计的功能的其他人的程序。
在您的情况下,我可以看到在print
方法中使用transformInput
时遇到的问题。此外,DevelopingMyClass
是一个误导性的标识符。我不想挑剔。它只是让你的思维不那么清晰。
在进入单元测试之前,您应该选择一个不错的例子。对废话没有好的单元测试。
首先,如果您想要读取文件,修改内容并将文件写回,那么您应该从普通函数开始。这堂课不会帮到你。您可能习惯于从Java中首先创建一些对象。但它实际上并不自然。如果你需要保留一些实例变量(某些状态),对象就很好。
如果功能更通用,则不应使用print
等副作用。
说,你从来没有听说过TDD,你写的代码是这样的:
#!python3
def copy_and_filter(fname_from, fname_to):
with open(fname_from) as fin, open(fname_to, 'w') as fout:
for line in fin:
fout.write(line.replace('a', 'z'))
copy_and_filter('from.txt', 'to.txt')
(这实际上是您的解决方案。)对于更复杂的代码,您会发现TDD更合理。无论如何。你应该开始思考:
所以你写道:
#!python3
def copy_and_filter(fname_from, fname_to):
pass
copy_and_filter('from.txt', 'to.txt')
通过这种方式,您可以定义应该如何调用它。现在是编写单元测试的时候了。您想测试特殊情况:
稍后,您可能会发现源文件不存在时存在错误(实现应该反映出来),因此您添加一些测试然后修复实现。
可能出现的其他问题: - 源文件不是源文件(比如说是目录) - 目标不能开放写作 - 目标文件已存在,您不想覆盖它
当测试更多文件时,您会发现很难模拟文件,并且您可能决定更改内部结构,以便核心功能与文件类对象一起使用。