Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 如何在Xcode中编写GUI的自动单元测试?_Cocoa_Unit Testing_Xcode - Fatal编程技术网

Cocoa 如何在Xcode中编写GUI的自动单元测试?

Cocoa 如何在Xcode中编写GUI的自动单元测试?,cocoa,unit-testing,xcode,Cocoa,Unit Testing,Xcode,我只想为Cocoa应用程序的GUI部分编写一个单元测试 在教科书单元测试中,有一个测试框架和测试用例调用被测单元。该单元下面的所有代码都是模拟出来的。因此,输入和输出都受到控制和监控;仅测试被测单元中的代码 当被测单元是我的GUI时,我想做同样的事情: 1) 设置某种框架,我可以在其中编写操作和检查GUI控件的代码。 2) 将GUI控件连接到实际代码的模拟,而不是实际实例。 3) 运行测试,该测试操作控件,然后检查模拟对象,查看是否使用正确的参数调用了正确的方法,并检查GUI,查看来自模拟对象的

我只想为Cocoa应用程序的GUI部分编写一个单元测试

在教科书单元测试中,有一个测试框架和测试用例调用被测单元。该单元下面的所有代码都是模拟出来的。因此,输入和输出都受到控制和监控;仅测试被测单元中的代码

当被测单元是我的GUI时,我想做同样的事情:
1) 设置某种框架,我可以在其中编写操作和检查GUI控件的代码。
2) 将GUI控件连接到实际代码的模拟,而不是实际实例。
3) 运行测试,该测试操作控件,然后检查模拟对象,查看是否使用正确的参数调用了正确的方法,并检查GUI,查看来自模拟对象的响应是否导致小部件中的正确更改

有人这样做吗?如果是,怎么做?有什么办法可以帮你吗

谢谢

(编辑)为了给出一个非常具体的例子,我想:
1) 编写一个将选择菜单项“MyMenu”->“MyItem”的测试用例。在这个测试用例中,我想检查方法[AppDelegate-doMyItem]是否被精确调用一次,并且AppDelegate中没有其他方法被调用。
2) 生成AppDelegate的模拟对象。(我知道怎么做)
3) 以某种方式(此处手动保存)链接我的应用程序,以便链接AppDelegate的模拟实例而不是真实实例。
4) 运行测试。看着它失败,因为1)我还没有创建我的菜单。2) 我还没有创建我的项目。3) 我还没有完成将MyItem连接到[AppDelegate-doMyItem]或[4]的IB工作,因为我还没有编写'doMyItem'方法。
5) 解决上述四个问题(如果那天我觉得自己很学究,一次解决一个问题)。
6) 再次运行测试并观察它是否成功


这是否清楚地说明了问题?

以下是几种常用的方法(如果不是所有兼容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>

调用了doMyItem()

如果从事件处理程序生成的响应不同,则测试用例失败。您可以打印出实际响应以帮助调试。

两个原则,两个链接:

  • 使用模式使视图尽可能哑:这使GUI更易于测试
  • :信任按钮、菜单等的实现。。。但请验证是否正确连接,以及是否符合预期

您研究过可访问性框架吗?它应该让一个应用程序检查另一个应用程序的UI,并生成类似用户的交互事件


Hi Patros,关于你的第二个问题,我不太明白“生成类似用户的输入”意味着什么。你能给我举个例子吗?谢谢,PatIt只是指生成您想要查看的键盘和鼠标事件。您可以通过包装本机UI类并劫持它们的事件(可能通过访问API或编写自定义驱动程序)来实现这一点。