How to write automatic unit test GUI in Xcode?

I want to write unit test only part of the GUI of my Cocoa application.

The unit test tutorial has a test environment and a test script that invokes the device under test. All code below this device is mocking. Thus, both input and output are monitored and monitored; Only the code of the device under test is verified.

I want to do the same where the unit under test is my GUI:
1) Set up some kind of structure where I can write code that will manage and verify the GUI controls.
2) Connect my GUI controls to the bullying of my actual code, and not to real instances.
3) Run a test that controls the controls and then checks the layout object to see if the correct methods were called with the correct parameters and checks the graphical interface to see if the responses from the layout caused the correct changes in the widgets.

Does anyone do this? If so, how? Any ideas on how I can do this?

Thanks,

Pat

(Edit) To give a very concrete example, I want:
1) Write a test case that selects the menu item "MyMenu" β†’ "MyItem". In this test case, I want to verify that the [AppDelegate doMyItem] method is called exactly once and that no other methods are called in AppDelegate.
2) Create a mock AppDelegate object. (I know how to do this)
3) Somehow (manual work here), link my application so that a mock instance of AppDelegate is connected instead, and not the real one.
4) Run the test. Watch the failure because 1) I have not created MyMenu yet. 2) I have not created MyItem yet. 3) I did not do IB work to connect MyItem to [AppDelegate doMyItem] or 4) because I have not written the doMyItem method yet.
5) Correct the above four questions (one at a time if I feel really pedantic that day).
6) Repeat the test and see how it succeeds.

Does this mean a question?

+6
unit-testing xcode cocoa
source share
3 answers

Two principles, two links:

+3
source share

Here are some popular ways to do this in general (should work with most, if not all cocoa compatible languages).

1 - create a callback interface. One of the inputs to creating your GUI elements is the implementation of this interface. When the user interacts, the GUI element calls the update function on this interface. Have a real implementation and test implementation.

2 - Use event handlers. Register all of your GUI elements with one or more event handlers and create GUI events to interact with the user. Have an event handler interface with two implementations, again one for real use and one for testing.

Edit: screams, missing requirement # 1. Never do this with special OSX controls, but overall there are two approaches.

1 - create a script or application that generates user input. It has the disadvantage that it is not easy for you to check the GUI. Instead, you need to create good test cases to make sure that everything should be there and there is nothing superfluous.

2 - create an interface with a test implementation that replaces the rendering and interface layer. This is easier with libraries like SDL or directFB, and even more so with things like OSX API, win32 API, etc.

Edit: response to editable.

In the case of your example, using a separate test application and event handlers, this looks like this:

Your test application is a simple application or script that launches your GUI and then generates mouse / keyboard events based on input files. As I said, I have never done this in OSX (QNX only). With any luck, you can generate mouse and keyboard events using the API, but you will have to ask someone if possible.

So, create an input for your test case. The test application will analyze this to know what to do. This could be plain XML:

<testcase name="blah"><mouseevent x="120" y="175" type="click"/></testcase> 

or no matter what the mouse sequence may actually be.

When your script executes this command, it clicks on this button. Your event handler will pick this up. But now you have to run your application with the -test or somesuch flag in order to actually use the test event handler. Instead of doing what your application usually does, the test event handler can perform some user actions. For example, it can perform some ordinary actions (you still need a GUI to respond), and then send the message (via socket, pipe, whatever) to the test application.

Your test application will pick up this message and compare it with what it expects to see. So now, maybe your test XML file looks like this:

 <testcase name="blah"> <mouseevent x="120" y="175" type="click"/> <response>doMyItem() called</response> </testcase> 

If the response generated by the event handler is different, then the test case failed. You can print the actual answer to help with debugging.

+1
source share

Have you looked at accessibility? It should allow one application to check the user interface of another application and generate user interaction events.

Availability Overview

+1
source share

All Articles