Как использовать макет MOC в моем контроллере просмотра с помощью Xcode 7 UITests?

Итак, я обнаружил, что при написании XCTests или тестов пользовательского интерфейса я не могу получить доступ к MOC делегата моего приложения. Я получил какую-то ошибку, в которой говорилось: «Я MyAppUITests, и я не могу получить доступ к материалам MyApp».

Круто, нет проблем, я написал весь свой код, чтобы принять любой MOC, а затем сделал фиктивный MOC в setup(), чтобы у каждого XCTest был свежий планшет, который не касался моих реальных данных. Импортируйте мое приложение как тестируемое. Бум, все работает, мне не нужно менять цели или писать какой-либо код в моих объектах, чтобы «заставить его работать для тестирования!»

Проблема в том, что я не уверен, как это сделать для тестов пользовательского интерфейса и раскадровок. Большинство моих контроллеров представления получают мой MOC от appdelegate в viewdidload. Я не могу понять, как сказать ему использовать фиктивный макет, чтобы каждый тест мог начинаться с чистого листа и чтобы он не использовал мое фактическое основное хранилище данных, а затем мог нормально работать, когда не тестировался. Цель здесь состоит в том, чтобы основной код приложения не имел никаких ссылок на него, зная, что он тестируется.

Должен быть чистый способ сделать это без уродства, смены целей и т. д. Что-то, что будет работать так же, как мои XCTests, но для пользовательского интерфейса. Я нашел это: Как начать с пустых основных данных для каждого утверждения теста пользовательского интерфейса в Swift?, но никто не ответил. Этот пользователь задает аналогичный вопрос, но, я думаю, у него неправильный подход (очистка основных данных вместо использования имитации MOC).

Идеи?

Что бы это ни стоило, я создаю приложение для Mac.


person user5503635    schedule 29.10.2015    source источник


Ответы (1)


Проблема в том, что я не уверен, как это сделать для тестов пользовательского интерфейса и раскадровок. Большинство моих контроллеров представления получают мой MOC от appdelegate в viewdidload.

Одна из многих причин, по которой вам никогда не следует использовать делегат приложения для продажи основного стека данных.

Не вдаваясь во все детали того, что вы должны делать вместо этого, ясно одно: вы должны предоставить MOC своим контроллерам представления.

Один простой способ (хотя и с некоторыми недостатками) — дать вашим контроллерам представления свойство MOC.

@property (strong) NSManagedObjectContext *managedObjectContext;

Затем вы должны установить это свойство при инициализации вашего контроллера представления.

Один «быстрый, но грязный» способ заставить это работать для ваших тестов - добавить свойство te, а затем в вашем viewDidLoad сделать что-то вроде этого.

if (!self.managedObjectContext) {
    self.managedObjectContext = appDelegate.managedObjectContext;
}

Это не рекомендация по этому поводу. Вы должны полностью избавиться от основного стека данных из делегата приложения и передать его, как и любую модель, контроллеру представления.

Тем не менее, это позволит вашему приложению продолжать работать, как сейчас, а также предоставит вам способ создавать экземпляры ваших контроллеров представления в ваших тестах пользовательского интерфейса и предоставлять им «фиктивный» MOC.

Кроме того, если вы этого не делаете, в общем случае вам следует использовать для своих тестов постоянное хранилище в памяти.

person Jody Hagins    schedule 29.10.2015
comment
В настоящее время у меня есть только один контроллер представления, поэтому мне не требуется промежуточная реализация. Мой вопрос уточняется: используя функцию UITest и раскадровки, как я могу предоставить контроллеру представления MOC? Это легко сделать в методе подготовки к переходу, но, поскольку тесты находятся вне приложения, я не уверен, как дать ему фиктивный MOC при первом запуске при тестировании. UITests не создает экземпляры контроллеров представления, он нажимает кнопки на экране. - person user5503635; 30.10.2015