gpt4 book ai didi

Python 单元测试模块化与可读性

转载 作者:太空狗 更新时间:2023-10-29 21:44:19 25 4
gpt4 key购买 nike

我有一个 Python 单元测试,其中一些测试具有相同类型的对象。一个测试类的基本大纲是:

class TestClass(unittest.TestCase):
def setup(self):
...

def checkObjects(self, obj):
for i in [...values...]:
self.assertEqual(starttags(i,obj), endtags(i,obj))

def testOne(self):
#Get object one.
checkObjects(objone)

def testAnother(self):
#Access another object.
checkObjects(another)

... various tests for similar objects.

虽然它是模块化的,但我注意到任何失败都会给出类似 AssertionError: number != anothernumber 的错误,以及生成错误的代码行 self.assertEqual(starttags(i,obj), endtags(i ,obj))。如果我列出了测试而不是放在 for 循环中,我会得到类似的东西:

self.assertEqual(starttags(value1,obj), endtags(value1,obj))
self.assertEqual(starttags(value2,obj), endtags(value2,obj))

它准确地显示了导致错误的情况,但是是复制粘贴代码,我认为通常不推荐这样做。我最近注意到这个问题,当时一位贡献者重新设计了一个更干净 的单元测试,不幸的是,它几乎不会提供关于断言失败的调试信息。那么,在这些情况下,最佳做法是什么?像元组列表这样的东西,用 assertEquals 送入 for 循环是“更干净的”,但是在不同行上复制粘贴不同的值会提供有用的堆栈跟踪。

最佳答案

如果更干净是指更少的代码,那么这种更干净的代码并不总是更可读的代码。事实上,它通常可读性较差(尤其是当您回头看时)。你总是可以进行花哨的重构,但你需要知道何时停止。从长远来看,使用更明显、更简单的代码总是比试图压缩少一行代码以获得人为 yield 更好——不仅仅是在单元测试方面。

单元测试有自己的规则。例如,它们通常允许与您的常规代码标准所说的不同的命名约定,您几乎从不记录它——它们是您代码库的特殊部分。此外,重复代码并不少见。实际上,进行许多外观相似的小型测试是很典型的。

设计测试(代码)时要牢记简单性

目前,即使在编写测试的阶段,您的测试也令人困惑 - 想象一下从现在起 3 个月后回到该代码。想象一下,由于其他人其他地方 进行了一些更改,其中一个测试失败了。它不会变得更好。

以这样一种方式设计您的测试,当其中一个失败时,您立即知道它为什么会这样以及在哪里。不仅如此 - 以这样一种方式设计它们,您可以在眨眼间分辨出它们在做什么。在测试代​​码中使用 for 循环ifs 和基本上任何其他类型的控制流 机制(或过于广泛的重构)通常会导致一个问题突然想到 - 我们在这里做什么? 这是您不希望自己问的那种问题。

用比我聪明的人的话来总结这篇长篇文章:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999

帮自己一个忙,坚持这条规则。

关于Python 单元测试模块化与可读性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9271925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com