我将这个答案分为两部分。首先,我将分享我对Brian答案的看法,然后我将分享一些有关如何有效测试的提示。
布赖恩答案的解释Brian暗示了两个关键思想。我将分别针对每个人。
理念1:生产代码不应依赖于测试您的代码应以与测试无关的方式编写。
生产的代码应该 不 依赖于测试。应该是相反的。
原因有很多:
- 更改测试 不会更改 代码 的行为 。
- 您的生产代码可以 独立 于测试代码进行编译和 部署 。
- 更新测试时, 无需重新编译 您的代码。
- 由于未运行测试代码而产生了意外的副作用,因此您的生产代码 可能不会失败 。
注意: 任何体面的编译器都会删除测试代码。尽管我认为这不是设计/测试系统不佳的借口。
想法2:您应该测试抽象而不是实现无论您在什么环境中进行测试,都应尽可能接近真实世界。
这 听起来 像布莱恩可能在他的回答中这种想法在暗示。与最后一个想法不同,这个想法尚未得到普遍认可,因此请带上一粒盐。
通过测试抽象,您可以提高对测试单元的尊重程度。您同意 不会 与它的内部混为一谈并监视其内部状态。
为什么在测试期间我不应该监视对象的状态?
通过监视对象的内部,将导致以下问题:
- 您的测试将使 您与 单元 的特定实现联系在一起 。
例如,
是否要将类更改为使用其他排序算法?太糟糕了,因为您断言 必须 调用该
quicksort函数,所以测试将失败。 __
- 您将 破坏封装 。
通过测试对象的内部状态,您将很容易放松该对象所具有的某些隐私。这将意味着您的更多 生产 代码也将提高对对象的可见性。
通过放松对象的封装,您正在诱使其他生产代码也依赖它。这不仅可以将您的 测试 绑定到特定的实现,而且还可以绑定整个系统本身。您 不 希望这种情况发生。
那我怎么知道这个班上课了?
测试所调用方法的前提条件和条件前提/结果。如果您需要更复杂的测试,请看我写的关于 模拟 和依赖注入的最后一节。
迷你笔记只要* 您的生产代码与测试无关,我认为if (TEST_MODE)
在main方法中添加一个并不一定很糟糕。 *
例如:
public class Startup { private static final boolean TEST_MODE = false; public static void main(String[] args) { if (TEST_MODE) { TestSuite testSuite = new TestSuite(); testSuite.execute(); } else { Main main = new Main(); main.execute(); } }}
但是,如果您的其他类 知道 它们正在测试模式下运行,则将成为一个问题。如果您拥有
if(TEST_MODE)所有生产代码,那么您就可以迎接上面提到的问题。
显然,在Java中,您可以使用诸如JUnit或TestNG之类的东西来代替它,但是我只是想分享我对该
if (TEST_MODE)想法的看法。如何有效测试
这是一个非常大的主题,因此我将在答案的这一部分中简短介绍。
- 与其监视内部状态, 不如使用模拟和依赖注入 。
使用模拟,您可以断言您已注入的模拟方法已被调用。更好的是,依赖项注入将使您的类对所注入内容的实现的依赖关系反转。这意味着您可以交换事物的不同实现,而不必担心。
这完全消除了在类内部闲逛的需要。
如果我强烈推荐阅读一本书,那就是 Jeff Langr 撰写的《 具有测试驱动开发 的 现代C ++编程》 。这可能是我用过的最好的TDD资源。
__
尽管标题中有C ++,但它的主要重点肯定是TDD。本书的开头讨论了这些示例应如何应用于所有(相似)语言。鲍勃叔叔甚至在前言中指出:
您需要成为C 程序员才能理解吗?当然不会。C
代码非常简洁,编写得井井有条,概念非常清晰,任何Java,C#,C甚至Ruby程序员都不会遇到麻烦。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)