您的单元测试的详细程度 [英] Level of detail of your unit tests

查看:91
本文介绍了您的单元测试的详细程度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开始讨论您在单元测试中涵盖的细节.

I wanted to start a discussion about the details that you cover in your unit tests.

您是否测试主要功能,这些功能由几种方法组成,一次只能完成一项任务? 甚至您甚至可以测试自动属性?

Do you test major functionalities, that consist of several methods doing one task at once with one test? or maybe you even test automatic properties?

例如,因为我编写一个仅对此进行测试的测试的价值很小:

Because, for example, I see little value in writing a test that would test only this:

   public Email
   {
      set
      {
         if(Regex.Match(/*....*/))
             email = value;
      }
      get
      {
        return email;
      }
   }

很明显,这只是浪费时间. 通常,当我进行单元测试时,我会测试整个任务-如本例所示-整个注册过程.

As it's really clear and it's just a waste of time. Usually when I do unit tests I test a whole task - like on this example - a whole registration procedure.

我之所以这么问,是因为目前我正在阅读吉米·尼尔森(Jimmy Nilsson)撰写的《应用域驱动的设计和模式》一书,他指出他正在使用专门的测试来测试如此小的细节.

I'm asking this because, currently I'm reading the book "Applying Domain Driven Design and Patterns" authored by Jimmy Nilsson and there he points out that he's testing even such small details with a dedicated test.

这样的覆盖范围不是过度使用吗?

Isn't such level of coverage an overuse?

推荐答案

测试不仅仅是为了测试您编写的内容是否有效.还可以通过测试来测试您编写的STILL是否有效.就像,很多年以后,还有许多开发人员.您认为简单的一门简单的课将来可能会变得更加复杂.

Tests are not just there to test that what you wrote works. Tests are also there to test that what you wrote STILL works. Like, many years and many developers later. What you think is a dead simple class might in the future become more complicated.

例如,假设它开始时没有过滤器.只是一个简单的获取/设置.为什么要测试?然后,其他一些开发人员添加了正则表达式过滤器,并且出现了故障.然后,该类突然中断,但是未经测试,所以没人知道.这揭示了自己的神秘之处,那就是调用栈进一步扩展了神秘的故障,这现在需要花费更多的时间进行调试.可能比编写一些测试所需的更多.

For example, lets say it started with no filter. Just a simple get/set. Why test that? Then later some other developer adds in the regex filter, and its faulty. Then suddenly the class is broken, but its untested so nobody knows. This reveals itself as mysterious failures further up the call stack which now take more time to debug. Probably more than it would have taken to write a few tests.

然后,在将来,有人会尝试变得更聪明并优化您的代码.或对其进行重新格式化,正则表达式倾向于不可读,并且经常可以进行一些清理.细微的破损已经成熟.小型目标单元测试将抓住这一点.

And then, in the future, somebody's going to try and get clever and optimize your code. Or reformat it, regexes have a tendency to be written unreadable and can often do with some cleanup. This is ripe for subtle breakage. Small targeted unit tests will catch this.

在上面的示例中,正则表达式大概用于过滤看起来像电子邮件地址的内容.这就需要检查正则表达式是否正常工作,否则您的Email类将停止接受电子邮件.否则它开始变得乱七八糟.也许您的正则表达式没有包含有效的电子邮件地址,一旦发现它就值得进行测试.最终,有人会用实际的解析器替换您的正则表达式.也许行得通,也许行不通.良好的测试将列出有效和无效电子邮件地址的简单列表,您可以在发现极端情况后轻松将其添加到该列表中.

In your example above, the regex is presumably there to filter for things that look like email addresses. That necessitates checking that regex is working, else your Email class stops accepting emails. Or it starts taking gibberish. Maybe your regex doesn't cover a valid email address, that's worth testing once you discover it. Eventually, somebody is going to replace your regex with an actual parser. Maybe it works, maybe it doesn't. A good test will have a simple list of valid and invalid email addresses which you can easily add to as corner cases are discovered.

测试还使您可以练习自己的界面并发现漏洞.如果您输入的不是电子邮件地址,会发生什么?没错,没事. Email.set会自动丢弃输入.垃圾进来,没有什么不是很有礼貌.也许应该抛出一个异常.当您尝试对其进行测试时,这很快就会变得很清楚,因为有必要测试该设备是否有效.

Tests also allow you to exercise your interface and discover holes. What happens when you put in something that isn't an email address? That's right, nothing. Email.set silently throws away the input. Garbage in, nothing out isn't very polite. Maybe it should throw an exception. This is something that would quickly become clear as you're trying to test it, because it would be necessary to test whether the set worked.

测试还可以显示灵活性和无法替代或定制的内容.在您的示例中,直接测试正则表达式过滤器将很方便,而不必每次都实例化一个对象.这是因为过滤器是最复杂的位,并且在经过尽可能少的层时更易于测试和调试.通过将其放入Email.is_email_address中,您现在可以直接对其进行测试.作为副作用,它也可以在子类中重写.这很方便,因为大多数人会得到错误电子邮件验证,因为电子邮件无法生存

Testing can also reveal inflexibilities and things which cannot be overriden or customized. In your example, it would be handy to test the regex filter directly rather than having to instantiate an object each time. This is because the filter is the most complicated bit, and its easier to test and debug while going through as few layers as possible. By putting it into Email.is_email_address you can now test it directly. As a side-effect it can also be overriden in a subclass. This is handy because most people get email validation WRONG because EMAIL HATES THE LIVING!

最后,您希望将测试分离.测试一件事,而不会受到其他复杂性的影响,因此您可以清楚地看到问题的根源.您的Email课程非常适合进行简单,分离的单元测试.

Finally, you want your tests to be decoupled. Test one thing without it being effected by additional complexities so you can clearly see the root of the problem. Your Email class is an excellent candidate for a simple, decoupled unit test.

这篇关于您的单元测试的详细程度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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