Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен
Недавно я начал модульное тестирование своего приложения. Этот проект (в Xcode4) был создан без единого тестового пакета, поэтому мне пришлось его настроить. Я выполнил следующие шаги: http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html И он хорошо работал для простых classов, но теперь я пытаюсь проверить class, который зависит на другом, а на другом и т. д.
Сначала у меня появилась ошибка компоновщика, поэтому я добавил файлы *.m
в целевой тестовый пример, но теперь я получаю предупреждение для каждого classа, который я пытаюсь проверить:
Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен.
- Содержимое HTML соответствует UIWebview без масштабирования
- Получить процентное использование процессора
- Что мне нужно сделать, чтобы заставить Core Data автоматически переносить модели?
- applicationWillEnterForeground против applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground
- Ссылка с UITableViewCell на родительский UITableView?
Интересно, почему? Как я могу это решить? Может быть, я что-то пропустил, установив цель тестирования?
Изменить – решение
-
Установите «Bundle Loader» правильно на
$(BUILT_PRODUCTS_DIR)/AppName.app/AppName
-
Установите «Символы, скрытые по умолчанию», на « НЕТ» (в настройках сборки целевого приложения). Здесь возникают ошибки компоновщика, поскольку по умолчанию это ДА !. Я так долго боролся с этим!
Источник: ошибка связи для модульного тестирования с XCode 4?
- Как использовать CaptiveNetwork для получения текущего имени точки доступа Wi-Fi
- @synthesize vs @dynamic, каковы различия?
- Можно ли показать изображение в UIAlertView?
- Проблема UITableView при использовании отдельного делегата / источника данных
- Проблема с кодом: строка формата не является строковым литералом
- Преимущества, проблемы, примеры добавления другого UIWindow в приложение iOS?
- Как добавить userInfo в UIAlertView?
- Ошибка UIActivityViewController на iOS 8 iPads
Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен.
Интересно, почему?
потому что оба изображения (приложение и единичный тестовый комплект) определяют реализацию classа. class динамически загружается в среду выполнения objc. во время выполнения objc используется плоское пространство имен. как это работает:
- бинарный файл загружается, начиная с его зависимостей
- поскольку каждый двоичный файл загружается, classы objc регистрируются в среде выполнения objc
- если class с определенным именем загружается дважды, поведение не определено. одна реализация classа (с идентичными именами) может быть загружена в среду выполнения objc.
типичная проблема здесь в том, что вам будет возвращена одна реализация – ваше приложение, скорее всего, сработает, когда конфликт типа (когда class не приходит из одного и того же исходного файла).
вы обычно избегаете этого, переименовывая class или экспортируя class в одно изображение. переименование classа, очевидно, не относится к вашему делу. у вас есть один файл Foo.m
который компилируется, экспортируется и загружается двумя изображениями, когда он должен быть в одном.
это должно интерпретироваться вами как ошибка дубликата символьного символа. хотя реализация является одним и тем же исходным файлом (и реализация такая же) – это проблема, которую вы должны исправить.
Как я могу это решить?
если Foo.m
является classом приложения, вы должны удалить (не компилировать и не связывать) Foo.m
из модульного теста. если это часть модульного теста, то не компилируйте и не связывайте его с целевой тестовой единицей.
затем следуйте инструкциям в сообщении для связывания / загрузки вашего модульного теста в приложение. он находится в этой общей области сообщения: где «WhereIsMyMac» – это название приложения, которое вы тестируете на модуле. Это позволит целевой целевой среде тестировать приложение (поэтому при компиляции вы не получите ошибок компоновщика). важная часть заключается в том, что ваши тестовые файлы скомпилированы в целевой тестовой единице (только), а classы вашего приложения скомпилированы и связаны в приложении. вы не можете просто добавить их – они связываются и загружаются динамически.
Может быть, я что-то пропустил, установив цель тестирования?
Из статьи, которую вы указали:
Примечание. objective тестирования – отдельная цель. Это означает, что вам нужно быть осторожным с целевым членством. Все исходные файлы приложений должны быть добавлены только к целевой программе. Файлы тестового кода должны быть добавлены только к цели тестирования.
часть, в которой вы ошибаетесь, вероятно, является фазой связи и нагрузки модульного тестового комплекта.
Если вы используете Cocoapods, ваш файл подкачки нуждается только в зависимостях в разделе главной цели, а не в тестовых целях. Если вы добавляете повторяющиеся зависимости для целевых объектов, вы получите сообщение об ошибке OP.
target 'MyProject' do pod 'Parse' end target 'MyProjectTests' do end target 'MyProjectUITests' do end
Для меня все, что мне нужно было сделать, это снять флажок, который делает class Foo членом целевой тестовой единицы. Он не должен быть членом обеих целей и должен выглядеть следующим образом:
Если вы не видите изображение, это снимок экрана панели «Целевое членство» Xcode. Есть две цели: одна с иконкой приложения «А» и именем теста. Другая – целевая единица измерения единицы измерения и имеет идентификатор тестовой единицы:
Target Membership [X] Foo [ ] FooTests
Для меня это произошло потому, что я развернулся к устройству, а затем к симулятору, так как у меня есть NSZombies. Решение состояло в том, чтобы переключиться на конфигурацию тренажера и выполнить Product -> Clean, затем переключиться на конфигурацию устройства и сделать то же самое. Ошибка исчезла. Это связано с построением кеша.
Причина в том, что вы переопределяете RUNPATH_SEARCH_PATHS
настройки RUNPATH_SEARCH_PATHS
App Target, определенной в другой целевой.
Решение:
Перейдите в свою App Target и найдите настройку
RUNPATH_SEARCH_PATHS
и используйте там флаг$(inherited)
для обоих: Debug и Release
Перейдем к тем же проблемам. Моей ситуацией является class NSNotification реализуется как в /System/Library/Frameworks/Foundation.framework/Foundation, есть ли какие-либо чуваки, сталкивающиеся с одной и той же проблемой, будут направлены какие-либо направления или рекомендации.