在编写单元测试时,是否值得花费额外的时间使代码具有良好的质量和可读性?
在编写测试时,我经常会违反Demeter定律,以加快编写速度并避免使用太多变量。从技术上讲,单元测试不能直接重用-它们严格地与代码绑定,因此我看不出有什么理由要花很多时间在它们上面;他们只需要功能。
在编写单元测试时,是否值得花费额外的时间使代码具有良好的质量和可读性?
在编写测试时,我经常会违反Demeter定律,以加快编写速度并避免使用太多变量。从技术上讲,单元测试不能直接重用-它们严格地与代码绑定,因此我看不出有什么理由要花很多时间在它们上面;他们只需要功能。
Answers:
就质量和可读性而言,您绝对应该比生产代码更好地照顾单元测试。尝试掌握某些代码的功能时,通常会先看单元测试,而读者在查看测试时应迅速了解所涉及的问题。单元测试也往往会发生很大变化,并且如果它们的设计不可靠,将会破坏很多,这使进行测试的好处无效。
出于这个原因,违反Demeter定律绝对是您的单元测试中的一个问题,还有另外2个我无法想到的问题:
如果您的测试在其“ 安排”或“行为”部分违反了Demeter的定律,则可能表明您的生产代码也这样做了,因为您的单元测试只是代码的另一个使用者,并且可能会在同一代码中调用和操作被测类。任何其他生产代码将执行的方式。
如果您的测试在其断言部分违反了Demeter法则(即,验证了深深嵌套在被测对象的依赖关系图中的某些东西的值),则可能是那些实际上是集成测试而不是单元测试。换句话说,如果您在TestA中断言ABCD等于某物,则可能是您实际上是在测试D和A,而不仅仅是A。
顺便说一句,当你说
为了提高编写速度并且不使用太多变量,我经常打破Demeter定律。
你应该知道写作
var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;
very.Deep();
实际上没有比德墨特尔更好
myDependency.Grab.Something.Very.Deep();
如果那是你的意思。
花时间编写高质量的单元测试代码绝对是值得的:
支持临时方法的一个因素是,您的单元测试永远不会成为公共API,因此您不必担心什么接口/等。你正在暴露。
是的,这很重要。单元测试应遵循与其他代码相当的标准有多个原因:
每个单元测试还充当测试对象的文档。当测试是全面的并且涵盖尽可能多的极端情况和错误情况时,它们通常可以代替类或函数的注释文档。他们还可以作为新手入门。
单元测试也可能有问题。如果代码编写得当,错误将更加明显。
如果由于某种原因以后您需要拆分一个模块,则可能还需要拆分其单元测试。如果编写的测试具有容易辨别的依存关系,则这样做会更容易。
也就是说,始终存在实用性问题。根据代码的语言和性质,如果不花大量的时间在测试上而不是花在要测试的代码上,就很难编写“干净的”单元测试。在那种情况下,我通常不去测试简单,快速的内容和最关键的功能,而不必担心完整的覆盖范围。每当以后出现错误时,我都会为它编写一个测试,并检查是否可以重构新测试和现有测试以使它们更好。