在该线程中,Brian(唯一的回答者)说:“您的代码应以与测试无关的方式编写”
一条评论说:“您的代码绝对不应在全局“我正在测试的标志”上分支。”。
但是,两者都没有给出原因,我 真的
很想听听对此事的一些理性思考。进入给定的应用程序类别并设置一个布尔值以表示“这是一个测试,而不是运行”,这将非常容易(尤其是考虑到许多测试具有对应用程序类的程序包私有访问权限的事实)。
我发现自己跳了圈(注入了嘲笑的私有字段等)来实现的各种各样的事情可能变得更容易实现。
同样显而易见的是,如果您走得太远,可能会造成灾难性的后果……但是作为软件测试工具库中众多工具之一,为什么这个概念会遇到这种麻烦?
回答米克助记符:
一个简单的例子可能会有所帮助,如果您实际上是在方法中间创建一个新的类实例并将其分配给私有字段:在这种情况下,私有字段模拟将无济于事,因为您要替换私有字段领域。但是实际上创建一个真实的对象可能会非常昂贵:您可能需要在测试时将其替换为轻量级版本。
昨天我实际上遇到了这种情况,我的解决方案是创建一个名为createXXX()的新程序包私有方法…这样我就可以模拟它。但这反过来违背了这样的格言:“您不能创建仅适合您的测试的方法”!
我将这个答案分为两部分。首先,我将分享我对Brian答案的看法,然后我将分享一些有关如何有效测试的提示。
Brian暗示了两个关键思想。我将分别针对每个人。
您的代码应以与测试无关的方式编写。
生产的代码应该 不 依赖于测试。应该是相反的。
原因有很多:
注意: 任何体面的编译器都会删除测试代码。尽管我认为这不是设计/测试系统不佳的借口。
无论您在什么环境中进行测试,都应尽可能接近真实世界。
这 听起来 像布莱恩可能在他的回答中这种想法在暗示。与最后一个想法不同,这个想法尚未得到普遍认可,因此请带上一粒盐。
通过测试抽象,您可以提高对测试单元的尊重程度。您同意 不会 与它的内部混为一谈并监视其内部状态。
为什么在测试期间我不应该监视对象的状态?
通过监视对象的内部,将导致以下问题:
例如,
是否要将类更改为使用其他排序算法?太糟糕了,因为您断言 必须 调用该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程序员都不会遇到麻烦。
在运行时导致错误的servlet中的代码。 JSONArray parent=new JSONArray();
我有一个JavaFX应用程序,它调用一些JNI代码,使用预加载程序jar,并使用JDK1.7编译。现在,当我使用JRE7在另一台计算机上运行jar时,通过: 双击jar:它启动,但无法加载包含库的JNI代码,因此被卡住。 有人能告诉我这三种情况有什么不同吗?
感谢您的帮助和道歉我的英语。 我有个问题。Android studio:当我尝试在连接到PC的手机上测试我的应用程序时,我运行应用程序并选择此错误: 错误:任务“:app:transformClassesWithDexForDebug”的执行失败。 com.android.build.api.transform.TransformException:com.android.ide.common.p
我希望测试类知道它们当前是否在套件中执行。我有一个测试套件,它使用外部资源(ExternalResource)在所有测试之前启动服务器,在所有测试之后关闭服务器。效果完美。在编写新测试时,我希望运行一个测试(或全部来自同一个测试类)来启动和停止服务器。所以我想让这些类知道它们当前是否在套件中执行,并相应地启动服务器。这似乎是不可能的。套件描述似乎永远不会传递给规则或类规则。我也无法获得运行当前测试
这是我的密码 这是我在编译完代码后尝试运行代码后得到的错误消息。 ----jgrast exec:Java--module-path C:\users\Isabelle Rose\download\openjfx-11.0.2_windows-x64_bin-sdk(1)\javafx-sdk-11.0.2\lib--add-modules=javafx.controls应用程序中的FinalPr
以下是logcat中显示的错误。