是重复代码的更多容忍的单位测试?
-
02-07-2019 - |
解决方案
重复代码是单元测试代码中的气味,就像在其他代码中一样。如果您在测试中有重复的代码,则会使重构实现代码变得更加困难,因为您需要更新不成比例的测试。测试应该可以帮助您充满信心地进行重构,而不是阻碍您对所测试代码进行工作的巨大负担。
如果复制在夹具设置中,请考虑更多地使用 setUp
方法或提供更多(或更灵活)创作方法。
如果重复是在操纵SUT的代码中,那么问问自己为什么多个所谓的“单位”测试正在运用完全相同的功能。
如果复制在断言中,那么您可能需要一些自定义断言。例如,如果多个测试有一串断言,如:
assertEqual('Joe', person.getFirstName())
assertEqual('Bloggs', person.getLastName())
assertEqual(23, person.getAge())
然后你可能需要一个 assertPersonEqual
方法,这样你就可以编写 assertPersonEqual(Person('Joe','Bloggs',23),person)
。 (或者您可能只需要在 Person
上重载相等运算符。)
正如您所提到的,测试代码的可读性非常重要。特别是,测试的 intent 非常重要。我发现,如果许多测试看起来大致相同(例如四分之三的线条相同或几乎相同),则很难发现并识别出显着的差异而不仔细阅读和比较它们。所以我发现重构删除重复有助于可读性,因为每个测试方法的每一行都与测试的目的直接相关。对于读者而言,这比直接相关的随机组合线和仅仅是样板的线条更有帮助。
尽管如此,有时测试正在进行类似但仍然存在显着差异的复杂情况,并且很难找到减少重复的好方法。使用常识:如果您觉得测试是可读的并且使他们的意图清楚,并且您对在重构测试调用的代码时需要更新理论上最少数量的测试感到满意,那么接受不完美和移动更有成效的事情。当灵感来袭时,你总能回来重构测试!
其他提示
可读性对于测试更重要。如果测试失败,您希望问题显而易见。开发人员不应该花费大量重要的测试代码来确定失败的确切内容。您不希望您的测试代码变得如此复杂,以至于您需要编写单元测试测试。
然而,消除重复通常是一件好事,只要它不会掩盖任何内容,并且消除测试中的重复可能会导致更好的API。只要确保你没有超过收益递减点。
执行代码和测试都是不同的动物和保规则适用不同的方式给他们。
重复代码或结构是总是一味在执行代码。当你开始有的样板,在实施,需要修改你的抽象概念。
另一方面,测试代码必须保持一定程度的重复。重复试验的代码实现两个目标:
- 保持试验去耦合。过测试的联接可以使难以改变一个失败的测试需要更新,因为合同已经改变。
- 保持试验有意义的隔离。当一个单一的测试失败,就必须相当简单找出它到底是什么测试。
我倾向于忽略琐碎的工作重复试验的代码如,只要每个试验方法保持短于约20线。我喜欢当的安装运行验证的节奏显而易见的是,在测试方法。
当重复爬起来"验证"的一部分的测试,它常常是有益的定义定义的论断的方法。当然,这些方法仍然必须测试一个明确的关系,可以作出显而易见的方法的名称: assertPegFitsInHole
->好, assertPegIsGood
->坏。
当测试方法增长和重复的我有时发现很有用的定义填写的空白试验模板,采取一些参数。然后,实际测试方法是降低到一个叫来的模板的方法与适当的参数。
作为一个很大的东西,在编程和测试,没有明确的答案。你需要发展一种味道,最好的方式这样做是犯错误。
您可以使用几种不同的测试实用程序方法来减少重复。
我对测试代码中的重复比对生产代码的重复更宽容,但我有时会对它感到沮丧。当你改变一个类的设计时,你必须回过头来调整10个不同的测试方法,这些方法都做相同的设置步骤,这很令人沮丧。
我同意。权衡存在但在不同的地方有所不同。
我更有可能重构重复代码来设置状态。但不太可能重构实际运行代码的测试部分。也就是说,如果执行代码总是需要几行代码,那么我可能会认为这是一种气味并重构了测试中的实际代码。这将提高代码和测试的可读性和可维护性。
我喜欢最高反射率,因为这样的:
它有2件事要帮助
共享的例子团体进行测试的共同行为。
你可以定义为一套测试,则'包括',设在你的真实测试。嵌套的情况。
你基本上可以有一个'安装'和'拆卸'方法的特定子集试验,不仅仅是每一个在类。
越早。NET/Java/其他测试框架采用这些方法,更好地(或者你可以使用如何从语言特性或继续写你的考试,这是我个人认为是更好的选择)
我认为更多重复和可读代码之间没有关系。我认为您的测试代码应该与其他代码一样好。如果做得好,非重复代码比重复代码更易读。
理想情况下,单元测试一旦写完就不应该改变太多,所以我倾向于可读性。
让单元测试尽可能离散也有助于使测试专注于他们所针对的特定功能。
话虽如此,我确实倾向于重复使用我反复使用的某些代码片段,例如在一组测试中完全相同的设置代码。
我觉得测试代码需要通常应用于生产代码的类似工程级别。当然可以提出支持可读性的论据,我同意这一点很重要。
但是,根据我的经验,我发现经过充分考虑的测试更容易阅读和理解。如果有5个测试,每个测试看起来都是相同的,除了一个变化的变量和最后的断言,很难找到单个不同项目的内容。类似地,如果考虑到只有变化的变量是可见的和断言,那么很容易弄清楚测试在做什么。
在测试时找到合适的抽象级别可能很困难,我觉得值得这样做。
“重构它们以使它们更干燥 - 每个测试的意图都不再明确”
听起来你在重构方面遇到了麻烦。我只是猜测,但是如果它不那么清楚,那是不是意味着你还有更多的工作要做,以便你有相当优雅的测试,这些测试非常清楚?
这就是测试是UnitTest的子类的原因 - 因此您可以设计出正确,易于验证和清晰的优秀测试套件。
在过去,我们有使用不同编程语言的测试工具。很难(或不可能)设计出令人愉快,易于操作的测试。
你有充分的力量 - 无论你使用什么语言 - Python,Java,C# - 所以要好好利用这种语言。您可以获得清晰且不太冗余的漂亮的测试代码。没有权衡。