关于单元测试的两个问题。
我一直在写单元测试 一段时间,但他们通常是 我已经写过的测试类。 最近我读了an article (记住你的一篇旧文章)说 你应该先写单元测试 你开始编写代码了。
有没有人真正遵循这一点 方法?这似乎很好 纸上的想法,但在实践中 它
答案 0 :(得分:8)
在课程之前编写单元测试的方法称为Test-Driven Development(TDD),并在2000年代早期由Kent Beck推广。我们的想法是编写一个描述所需功能的测试。最初,此测试将失败。当你上课时,测试通过了。您重构测试以添加更多所需的功能,然后重构该类以使此新测试通过。一旦测试通过,你的班级就达到了目标。当然,这也超出了课程范围。
关于要编写的测试类型,这取决于您是在测试公共API还是私有API。公共API应该编写更广泛的测试,以确保输入良好,特别是如果您不完全信任API的用户。私有API(仅由您的代码调用的方法)可能在没有这些测试的情况下逃脱 - 我怀疑您可以信任您自己的开发团队,而不是将错误的数据传递给他们。
答案 1 :(得分:2)
首先编写单元测试是一种常见的做法。一个很大的好处是,您不仅要编写代码将通过的测试,而且还要测试定义重要内容,您要实现的内容以及您希望确保不会发生的内容。它可以帮助你充实你的设计。此外,您可以在编码之前与外部利益相关者一起审查斑点。
至于要写什么测试,根据你的时间有点主观。我不会疯狂地审查它永远不会面对的场景的代码。也就是说,令人惊讶的是什么输入使得代码“永远不会看到它”。因此,更多的测试更好,但在某些时候肯定会有收益递减。
您编码的语言很重要。动态语言需要更多测试,因为编译器会捕获更少的问题,并且可能更难跟踪错误(因为它们可以从初始输入问题进一步传播)。至少,这是我的意见。
输入来自哪里也有所不同。一般公众应该被认为是积极恶意的(即网络),员工应该被认为是无能的,甚至同伴(和你自己!)也应该被认为至少是粗心的。但随着你越来越接近你的内心圈,危险就会降低。
答案 2 :(得分:2)
Test Driven Development是一个非常普遍的概念。基本思想是您只尝试编写满足软件某些要求所必需的代码。因此,您为需求编写了测试,然后编写了测试通过的代码。
我个人不使用TDD,但我知道有人这样做。我个人的想法是,如果您正在开发更多应用程序驱动的东西,比如数据库或用户界面,那么它非常有用。但是,对于那些算法更重的东西(比如物理模型),我发现它打破了我的思路并阻碍了它。
答案 3 :(得分:2)
有没有人真正遵循这种方法?
是
这似乎是纸上的好主意,但实际上是吗?
是
您是否应该编写单元测试以查看您的方法如何处理错误/恶意输入?
是
那些应该永远不会将这种类型的输入传递给它们的函数呢?你什么时候画线?
当它从软件转移到精神病时。
您可以 - 如果您愿意 - 为不可能的情况编写测试。但是,你以明显的方式浪费你的时间和雇主。
您为定义的用例编写测试。就是这样。
您不会根据自己的想象构成随机测试用例。
该怎么办?如果定义的用例不完整怎么办?游民。你为官方,合同,公共界面编写测试 - 仅此而已。
如果设计不充分并且您意识到给定的界面充满了不完整的规格,矛盾和安全漏洞,该怎么办?这与测试无关。这只是编程。糟糕的设计是糟糕的设计。
如果某些恶意的反社会人员以超出(或无法满足)规定的规范的方式使用您的代码并使用它,该怎么办?游民。反社会胜利。他们能够将您的代码置于您未测试的不可能的情况中。给他们买一杯如此聪明的啤酒。
答案 4 :(得分:1)
test-before和test-after之间的思维方式存在差异。之前编写测试是 design 的一种形式,因为您正在设计代码的接口并定义预期的行为。然后,当您编写通过测试的代码时,将验证您的设计。在开发结束时,您恰好已经有了一套测试!
使用test-after,您需要小心避免编写现有代码将要通过的测试的陷阱。这是一个不同的焦点,你不会像以前的测试版那样得到它。
答案 5 :(得分:0)
已经有很多答案,但我想再说一个问题2。
如果你使你的unittest代码“数据驱动”,那么代码是测试“坏”还是“好”输入并不重要。重要的是你有足够大的数据集来覆盖两者。