重复代码在单元测试中更能容忍吗? [英] Is duplicated code more tolerable in unit tests?

查看:24
本文介绍了重复代码在单元测试中更能容忍吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前段时间,当我完成并重构它们以使它们更加DRY时,我毁掉了几个单元测试--每次测试的意图不再清晰.测试的可读性和可维护性之间似乎存在权衡.如果我在单元测试中留下重复的代码,它们会更具可读性,但是如果我更改 SUT,我将不得不追踪并更改重复代码的每个副本.

I ruined several unit tests some time ago when I went through and refactored them to make them more DRY--the intent of each test was no longer clear. It seems there is a trade-off between tests' readability and maintainability. If I leave duplicated code in unit tests, they're more readable, but then if I change the SUT, I'll have to track down and change each copy of the duplicated code.

您是否同意这种权衡存在?如果是这样,您更喜欢测试可读性还是可维护性?

Do you agree that this trade-off exists? If so, do you prefer your tests to be readable, or maintainable?

推荐答案

重复代码在单元测试代码中就像在其他代码中一样有异味.如果测试中有重复的代码,那么重构实现代码就会变得更加困难,因为要更新的测试数量不成比例.测试应该帮助您自信地进行重构,而不是成为阻碍您在被测试代码上工作的巨大负担.

Duplicated code is a smell in unit test code just as much as in other code. If you have duplicated code in tests, it makes it harder to refactor the implementation code because you have a disproportionate number of tests to update. Tests should help you refactor with confidence, rather than be a large burden that impedes your work on the code being tested.

如果在夹具设置中重复,请考虑更多地使用 setUp 方法或提供更多(或更灵活)创建方法.

If the duplication is in fixture set up, consider making more use of the setUp method or providing more (or more flexible) Creation Methods.

如果重复出现在操作 SUT 的代码中,那么问问自己为什么多个所谓的单元"测试执行完全相同的功能.

If the duplication is in the code manipulating the SUT, then ask yourself why multiple so-called "unit" tests are exercising the exact same functionality.

如果断言中有重复,那么您可能需要一些自定义断言.例如,如果多个测试具有一串断言,例如:

If the duplication is in the assertions, then perhaps you need some Custom Assertions. For example, if multiple tests have a string of assertions like:

assertEqual('Joe', person.getFirstName())
assertEqual('Bloggs', person.getLastName())
assertEqual(23, person.getAge())

那么也许您需要一个 assertPersonEqual 方法,以便您可以编写 assertPersonEqual(Person('Joe', 'Bloggs', 23), person).(或者,您可能只需要在 Person 上重载相等运算符.)

Then perhaps you need a single assertPersonEqual method, so that you can write assertPersonEqual(Person('Joe', 'Bloggs', 23), person). (Or perhaps you simply need to overload the equality operator on Person.)

正如您所提到的,测试代码的可读性很重要.尤其重要的是,测试的意图很明确.我发现如果许多测试看起来基本相同(例如,四分之三的线相同或几乎相同),如果不仔细阅读和比较它们,就很难发现和识别显着差异.所以我发现重构以消除重复有助于可读性,因为每个测试方法的每一行都与测试的目的直接相关.这比直接相关的行和只是样板的行的随机组合对读者更有帮助.

As you mention, it is important for test code to be readable. In particular, it is important that the intent of a test is clear. I find that if many tests look mostly the same, (e.g. three-quarters of the lines the same or virtually the same) it is hard to spot and recognise the significant differences without carefully reading and comparing them. So I find that refactoring to remove duplication helps readability, because every line of every test method is directly relevant to the purpose of the test. That's much more helpful for the reader than a random combination of lines that are directly relevant, and lines that are just boilerplate.

也就是说,有时测试会执行相似但仍显着不同的复杂情况,并且很难找到减少重复的好方法.使用常识:如果您觉得测试是可读的并且它们的意图很清楚,并且您对在重构测试调用的代码时可能需要更新超过理论上最少数量的测试感到满意,那么接受不完美并采取行动到更有成效的事情上.当灵感来临时,您可以随时回来重构测试!

That said, sometimes tests are exercising complex situations that are similiar but still significantly different, and it is hard to find a good way to reduce the duplication. Use common sense: if you feel the tests are readable and make their intent clear, and you're comfortable with perhaps needing to update more than a theoretically minimal number of tests when refactoring the code invoked by the tests, then accept the imperfection and move on to something more productive. You can always come back and refactor the tests later, when inspiration strikes!

这篇关于重复代码在单元测试中更能容忍吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆