有谁知道在哪里可以找到单元测试指南和建议?我想要一些可以解决以下类型主题的东西(例如):
- 测试是否应该与应用程序逻辑在同一个项目中?
- 我应该有测试类来反映我的逻辑类,还是应该只拥有我认为需要的那么多的测试类?
- 我应该如何命名我的测试类、方法和项目(如果它们在不同的项目中)
- 应该测试私有的、受保护的和内部的方法,还是只测试那些可公开访问的方法?
- 单元测试和集成测试应该分开吗?
- 是否有充分的理由不拥有 100% 的测试覆盖率?
我不是在问我应该是什么?
最好有在线资源。
有谁知道在哪里可以找到单元测试指南和建议?我想要一些可以解决以下类型主题的东西(例如):
我不是在问我应该是什么?
最好有在线资源。
我会推荐Kent Beck关于 TDD 的书。
此外,您需要访问Martin Fowler 的网站。他也有很多关于测试的好信息。
我们非常重视 TDD,所以我会从这个角度回答问题。
测试是否应该与应用程序逻辑在同一个项目中?
通常,我们将测试保存在同一个解决方案中,但我们将测试分解为单独的 DLL/项目,这些 DLL/项目镜像它们正在测试的 DLL/项目,但维护名称空间,测试位于子名称空间中。示例:Common / Common.Tests
我应该有测试类来反映我的逻辑类,还是应该只拥有我认为需要的那么多的测试类?
是的,您的测试应该在创建任何类之前创建,并且根据定义,您应该只单独测试一个单元。因此,您的解决方案中的每个类都应该有一个测试类。
我应该如何命名我的测试类、方法和项目(如果它们在不同的项目中)
我想强调的是行为是被测试的,所以我通常在 SUT 之后命名测试类。例如,如果我有一个 User 类,我会这样命名测试类:
public class UserBehavior
应该命名方法来描述您期望的行为。
public void ShouldBeAbleToSetUserFirstName()
项目可以随意命名,但通常您希望它正在测试哪个项目相当明显。请参阅有关项目组织的先前答案。
应该测试私有的、受保护的和内部的方法,还是只测试那些可公开访问的方法?
同样,您希望测试断言预期的行为,就好像您是被测试对象的第 3 方消费者一样。如果您测试内部实现细节,那么您的测试将很脆弱。您希望您的测试能够让您自由地进行重构,而不必担心破坏现有功能。如果您的测试知道实现细节,那么如果这些细节发生变化,您将不得不更改您的测试。
单元测试和集成测试应该分开吗?
是的,单元测试需要与验收和集成测试相隔离。关注点分离也适用于测试。
是否有充分的理由不拥有 100% 的测试覆盖率?
我不会挂断 100% 代码覆盖率的事情。100% 的代码覆盖率往往意味着测试中有一定程度的质量,但这是一个神话。您可以进行糟糕的测试,但仍然获得 100% 的覆盖率。相反,我会依靠良好的测试优先心态。如果您总是在编写一行代码之前编写测试,那么您将确保 100% 的覆盖率,因此它成为一个有争议的问题。
一般来说,如果您专注于描述课程的全部行为范围,那么您将无需担心。如果您将代码覆盖率作为衡量标准,那么懒惰的程序员只会做足以满足该标准的工作,而您仍然会有糟糕的测试。取而代之的是严重依赖同行评审,其中也对测试进行评审。
这是个好问题。我们自己有机地种植,我怀疑最好的方法就是这样。里面有一点“这取决于……”。
我们在同一个项目中的一个名为“UnitTes”的子命名空间中进行测试
我们的测试类反映了逻辑类,以简化跟踪测试与测试内容相关的位置
类的命名与它们正在测试的逻辑类一样,方法的命名是根据它们正在测试的场景来命名的。
我们只为公共和内部方法编写测试(测试在同一个项目中),目标是 95% 的类覆盖率。
我不想区分“单元”和“综合”。将花费大量时间试图找出哪个是哪个...包!一个测试就是一个测试。
100% 很难一直做到。我们的目标是 95%。获得最后 5% 所需的时间以及实际捕获的内容的回报也在递减。
这就是我们,适合环境和节奏。你的里程可能会有所不同。想想你的环境和所涉及的个性。
我期待看到其他人对此有什么看法!
乔希的回答是正确的 - 只是澄清一点:
我将单元测试与集成和验收测试分开的原因是速度。我使用 TDD。我需要关于我刚刚创建/修改的代码行的即时反馈。如果我正在运行全套集成和/或验收测试,我无法做到这一点——这些测试涉及真实磁盘、真实网络以及非常缓慢且不可预测的外部系统。
不要越过横梁。如果你这样做,坏事就会发生。
我强烈建议您阅读测试驱动开发:示例和测试驱动开发:实用指南单个主题的问题太多了
为了:
关于您的最后一个问题,根据我的经验,不坚持 100% 测试覆盖率的“好”理由是,要获得最后几个百分点需要付出不成比例的努力,尤其是在更大的代码库中。因此,一旦达到收益递减点,就要决定是否值得花时间。
测试是否应该与应用程序逻辑在同一个项目中?
这取决于。无论哪种方式都需要权衡取舍。
将其保留在一个项目中需要额外的带宽来分发您的项目、额外的构建时间并增加安装占用空间,并且更容易犯下依赖于测试代码的生产逻辑的错误。
另一方面,保持独立的项目可能会使编写涉及私有方法/类的测试变得更加困难(取决于编程语言),并且会导致一些管理上的小麻烦,例如设置新的开发环境(例如,当新开发人员加入项目)更难。
这些不同成本的重要性因项目而异,因此没有统一的答案。
我应该有测试类来反映我的逻辑类,还是应该只拥有我认为需要的那么多的测试类?
不。
你应该有测试类,允许良好的测试代码(即最小的重复,明确的意图等)。
直接在测试类中镜像逻辑类的明显优势是它可以很容易地找到对应于特定代码段的测试。在不限制测试代码灵活性的情况下,还有其他方法可以解决这个问题。测试模块和类的简单命名约定通常就足够了。
我应该如何命名我的测试类、方法和项目(如果它们在不同的项目中)
您应该命名它们,以便:
应该测试私有的、受保护的和内部的方法,还是只测试那些可公开访问的方法?
通常应该测试非公共方法。这取决于您是否从仅测试公共接口中获得足够的信心,或者您真正想要测试的单元是否不可公开访问。
单元测试和集成测试应该分开吗?
这取决于您选择的测试框架。选择最适合您的测试框架的方法,并使其:
是否有充分的理由不拥有 100% 的测试覆盖率?
是的,这是有充分理由的。严格来说,“100% 的测试覆盖率”意味着你的代码中所有可能的情况都经过了练习和测试。这对于几乎任何项目来说都是不切实际的。
如果你简单地认为“100% 测试覆盖率”意味着每一行源代码都在某个时候被测试套件执行,那么这是一个很好的目标,但有时在尴尬的地方只有几行代码很难达到自动化测试。如果定期手动验证该功能的成本低于通过扭曲到达最后五行的成本,那么这就是不具有 100% 线路覆盖率的好理由。
Rather than a simple rule that you should have 100% line coverage, encourage your developers to discover any gaps in your testing, and find ways to fix those gaps, whether or the number of lines “covered” improves. In other words, if you measure lines covered, then you will improve your line coverge — but what you actually want is improved quality. So don't forget that line coverage is just a very crude approximation of quality.