我想编写一个单独测试我的Cocoa应用程序的GUI部分。
在教科书单元测试中,有一个测试框架和测试用例调用被测单元。该单元下面的所有代码都被模拟了。因此,输入和输出都受到控制和监控;只测试被测单元中的代码。
我想做同样的事情,被测单位是我的GUI:
1)设置某种框架,我可以编写代码来操作和检查GUI控件
2)将我的GUI控件连接到我的实际代码的模拟,而不是实际的实例
3)运行测试,操作控件然后检查模拟对象以查看是否使用正确的参数调用了正确的方法,并检查GUI以查看模拟对象的响应是否导致窗口小部件中的正确更改。 / p>
有人这样做吗?如果是这样,怎么样?关于我如何做到这一点的任何想法?
谢谢,
专利
(编辑)举一个非常具体的例子,我想:
1)编写一个测试用例,选择菜单项'MyMenu' - > 'MyItem'。在这个测试用例中,我想检查方法[AppDelegate doMyItem]是否被精确调用一次,并且AppDelegate中没有其他方法被调用。
2)生成AppDelegate的模拟对象。 (我知道怎么做)
3)以某种方式(在这里handwaving)链接我的应用程序,以便AppDelegate的模拟实例链接而不是真实的。
4)运行测试。看它失败因为1)我还没有创建MyMenu。 2)我还没有创建MyItem。 3)我没有完成将MyItem连接到[AppDelegate doMyItem]的IB工作,或4)因为我还没有编写'doMyItem'方法。
5)修正上述四个问题(如果那天我感觉真的很迂腐的话,一次一个)
6)再次运行测试并观察它是否成功。
这会使问题清楚吗?
答案 0 :(得分:3)
两个原则,两个链接:
答案 1 :(得分:1)
以下是一些常用的方法(应该与大多数(如果不是所有的)cocoa兼容的语言一起使用。)
1 - 创建一个回调接口。创建GUI元素时的一个输入是此接口的实现。当存在用户交互时,GUI元素在该接口上调用更新功能。有一个真正的实现和测试实现。
2 - 使用事件处理程序。使用一个或多个事件处理程序注册所有GUI元素,并让GUI生成有关用户交互的事件。有一个带有两个实现的事件处理程序接口,一个用于实际使用,另一个用于测试。
编辑:哎呀,错过了要求#1。从未使用OSX特定控件完成此操作,但通常有两种方法。
1 - 创建一个生成类似用户输入的脚本或应用程序。具有不容易实际检查GUI的缺点。相反,您需要生成良好的测试用例以确保应该存在的所有内容,并且没有任何额外的内容。
2 - 使用替换渲染和界面层的测试实现创建一个接口。使用SDL或directFB这样的库更容易,而使用OSX API,win32 API等等则更容易。
编辑:回复有问题的编辑。
对于您的示例,使用单独的测试应用程序和事件处理程序,这是它的外观:
您的测试应用程序是一个简单的应用程序或脚本,用于启动GUI,然后根据输入文件生成鼠标/键盘事件。正如我所说,从未在OSX(仅限QNX)中完成此操作。运气好的话,你将能够使用API生成鼠标和键盘事件,但你必须问别人是否可能。
因此,为您的测试用例创建一个输入。测试应用程序将解析它以了解该做什么。这可能是简单的XML:
<testcase name="blah"><mouseevent x="120" y="175" type="click"/></testcase>
或实际上可能存在的任何小鼠序列。
当您的脚本执行该命令时,它将单击该按钮上的鼠标。您的事件处理程序将接受此操作。但是现在你应该使用--test标志运行你的应用程序,或者某些东西,以便它实际上使用测试事件处理程序。测试事件处理程序可以执行一些自定义操作,而不是执行应用程序通常执行的操作。例如,它可以执行一些正常操作(您仍然需要GUI来响应),然后向您的测试应用程序发送消息(通过套接字,管道等)。
您的测试应用会收到此消息,并将其与预期的内容进行比较。所以现在也许你的测试用例XML看起来像这样:
<testcase name="blah">
<mouseevent x="120" y="175" type="click"/>
<response>doMyItem() called</response>
</testcase>
如果从事件处理程序生成的响应不同,则测试用例失败。您可以打印出实际响应以帮助调试。
答案 2 :(得分:1)
您是否研究过辅助功能框架?它应该让一个应用程序检查另一个应用程序的UI并生成类似用户的交互事件。