我强烈主张正确的测试驱动设计或行为驱动的设计,我喜欢编写测试。但是,我一直将自己编码到一个角落,在这个角落里,我需要在单个类的特定测试用例中使用3-5模拟。无论从哪种方式开始,自上而下还是自下而上,我最终都会得到一个至少需要三个来自最高抽象级别的协作者的设计。
有人能就如何避免这一陷阱给出好的建议吗?
这是一个典型的场景。我设计了一个Widget,它从给定的文本值生成Midget。在我进入细节之前,它总是很简单的。我的Widget必须与一些难以测试的东西进行交互,如文件系统、数据库和网络。
所以,与其把所有这些设计成我的Widget,我还做了一个Bridget协作者。Bridget负责一半的复杂性,数据库和网络,允许我关注另一半,也就是多媒体演示。然后,我制作了一个Gidget来执行多媒体片段。整个事情需要发生在后台,所以现在我包括一个Thridget来实现这一点。当所有的话和做完,我结束了一个Widget,它的手工作的Thridget,谈判的布里奇特,把它的结果给一个吉吉特。
因为我在CocoaTouch中工作,并且试图避免模拟对象,所以我使用了自分流模式,在这种模式中,对协作者的抽象变成了我的测试所采用的协议。与3+合作,我的测试气球和变得太复杂。即使使用类似于OCMock的模拟对象,也给我留下了一个我宁愿避免的复杂顺序。我试着把我的大脑围绕在雏菊链上(A代表B,代表C等等),但我无法想象。
下面的例子是编辑,假设我们有一个对象,它必须从套接字读取/写入,并显示返回的电影数据。
//Assume myRequest is a String param...
InputStream aIn = aSocket.getInputStram();
OutputStream aOut = aSocket.getOutputStram();
DataProcessor aProcessor = ...;
// This gets broken into a "Network" collaborator.
for(stuff in myRequest.charArray()) aOut.write(stuff);
Object Data = aIn.read(); // Simplified read
//This is our second collaborator
aProcessor.process(Data);显然,上面提到的是网络延迟,所以它必须是线程化的。这引入了线程抽象,以使我们摆脱线程单元测试的实践。我们现在有
AsynchronousWorker myworker = getWorker(); //here's our third collaborator
worker.doThisWork( new WorkRequest() {
//Assume myRequest is a String param...
DataProcessor aProcessor = ...;
// Use our "Network" collaborator.
NetworkHandler networkHandler = getNetworkHandler();
Object Data = networkHandler.retrieveData(); // Simplified read
//This is our multimedia collaborator
aProcessor.process(Data);
})请原谅我做了逆向测试,但我要带我女儿出去,我正在匆忙学习这个例子。这里的想法是,我在一个简单的界面后面编排几个协作者的协作,这个界面将绑定到UI按钮单击事件。因此,最外面的测试反映了一个Sprint任务,上面有一个“播放电影”按钮,当它被点击时,电影就会播放。编辑让我们讨论一下。
发布于 2009-10-20 16:57:36
我做了一些相当完整的测试,但是它是自动化的集成测试,而不是单元测试,所以我没有模拟(除了用户:我嘲笑最终用户,模拟用户输入事件,测试/断言任何输出给用户的东西):应该测试内部实现,还是只测试公共行为?
我正在寻找的是使用TDD.的最佳实践。
维基百科描述 as
一种软件开发技术,它依赖于非常短的开发周期的重复:首先,开发人员编写一个失败的自动测试用例,该测试用例定义了所需的改进或新功能,然后生成通过测试的代码,最后将新代码重新组合到可接受的标准。
然后,它继续规定:
我做的第一个,即“非常短的开发周期”,在我的情况下的区别是,我测试后,它是写的。
我之所以在编写之后进行测试,是因为我根本不需要“编写”任何测试,甚至是集成测试。
我的周期大概是:
我认为这给了我TDD的好处:
我避免了一些成本/缺点:
发布于 2009-10-20 17:22:36
我的解决方案(不是CocoaTouch)是继续模拟对象,而是将模拟重新设置为一个通用的测试方法。这降低了测试本身的复杂性,同时保留了模拟基础结构,以便隔离地测试我的类。
发布于 2016-05-07 22:13:12
为了摆脱过度的嘲弄,您可以遵循试验金字塔,这意味着有大量的单元+组件测试和较少数量的缓慢和脆弱的系统测试。它归结为几个简单的规则:
有了这种心态,你几乎可以消除所有的嘲弄。
https://stackoverflow.com/questions/1595952
复制相似问题