Вот несколько популярных способов сделать это в целом (должно работать с большинством, если не со всеми совместимыми с какао языками).
1 - создать интерфейс обратного вызова. Одним из входных данных при создании элементов GUI является реализация этого интерфейса. При взаимодействии с пользователем элемент GUI вызывает функцию обновления для этого интерфейса. Реальная реализация и тестовая реализация.
2 - Использовать обработчики событий. Зарегистрируйте все элементы GUI с помощью одного или нескольких обработчиков событий, и пусть GUI генерирует события при взаимодействии с пользователем. Имейте интерфейс обработчика событий с двумя реализациями, снова один для реального использования и один для тестирования.
Редактировать: упс, пропущено требование № 1. Никогда не делали этого с особыми элементами управления OSX, но в целом есть два подхода.
1 - создать скрипт или приложение, которое генерирует пользовательский ввод. Недостатком является то, что на самом деле не так просто проверить графический интерфейс. Вместо этого вам нужно сгенерировать хорошие контрольные примеры, чтобы убедиться, что все, что должно быть, есть и ничего лишнего.
2 - создать интерфейс с тестовой реализацией, заменяющий уровень рендеринга и интерфейса. Это проще с библиотеками, такими как SDL или directFB, и меньше с такими вещами, как OSX API, win32 API и т. Д.
Редактировать: ответ на редактирование в вопросе.
В случае вашего примера, используя отдельное приложение для тестирования и обработчики событий, вот как это будет выглядеть:
Ваше тестовое приложение - это простое приложение или скрипт, который запускает ваш графический интерфейс, а затем генерирует события мыши / клавиатуры на основе входных файлов. Как я уже сказал, никогда не делал этого в OSX (только QNX). Если вам повезет, вы сможете генерировать события мыши и клавиатуры с помощью API, но вам придется спросить кого-то еще, если это возможно.
Итак, создайте вход для вашего теста. Тестовое приложение проанализирует это, чтобы узнать, что делать. Это может быть простой XML, подобный этому:
<testcase name="blah"><mouseevent x="120" y="175" type="click"/></testcase>
или любой другой последовательности мыши.
Когда ваш скрипт выполняет эту команду, он щелкает мышью по этой кнопке. Ваш обработчик событий поймет это. Но теперь вы должны запустить ваше приложение с флагом --test или что-то подобное, чтобы оно на самом деле использовало обработчик тестовых событий. Вместо того, чтобы делать то, что обычно делает ваше приложение, обработчик тестовых событий может выполнять некоторые пользовательские действия. Например, он может выполнять некоторые из обычных действий (вам все еще нужен графический интерфейс для ответа), а затем отправлять сообщение (через сокет, по каналу и т. Д.) В ваше тестовое приложение.
Ваше тестовое приложение получит это сообщение и сравнит его с тем, что оно ожидает увидеть. Так что теперь, возможно, ваш тестовый XML выглядит так:
<testcase name="blah">
<mouseevent x="120" y="175" type="click"/>
<response>doMyItem() called</response>
</testcase>
Если ответ, сгенерированный из обработчика событий, отличается, тестовый пример не пройден. Вы можете распечатать фактический ответ, чтобы помочь в отладке.