Подтвердить что ты не робот

Модульное тестирование Swift 2.0, @testable import и проблемы с таргетингом схемы

Недавно я преобразовал свое приложение и модульные тесты в Swift 2.0. Я использую @testable import AppName в своих файлах Tests.swift.

Из-за проблемы с невозможностью выполнения подклассов в нескольких целях (см. здесь для проблемы) мой класс EntityName может иметь только целевое членство AppName и NOT AppNameTests.

Проблема заключается в том, что после переключения на схему AppNameTests для запуска модульных тестов код в модуле AppName не может найти класс EntityName, и я получаю

Использование необъявленного типа "EntityName"

Как мне получить AppName для компиляции при выполнении тестов из схемы AppNameTests без этого класса сущности, не являющегося членом схемы?

4b9b3361

Ответ 1

Из-за проблемы с невозможностью выполнения подклассов в нескольких целях

При компиляции одного и того же кода Swift как части разных целей компилятор фактически генерирует разные классы. Таким образом, это ведет себя так, как было разработано, но почти наверняка не то, что вы хотите при запуске тестов модулей приложения.

Есть два способа, по которым я бы рекомендовал вам настроить свои модели для тестирования:

1. Публичные модели (рекомендуется)

В целевом приложении:

import RealmSwift
public class MyModel: Object {}

Этот код следует компилировать только как часть целевого приложения, и ваши модульные тесты могут быть настроены следующим образом:

import MyApp
// should be able to access `MyModel`

Достаточно легко?

2. @Testable (только для Swift 2)

Этот подход основан на ключевом слове @testable, введенном в Swift 2.

В целевом приложении:

import RealmSwift
internal class MyModel: Object {} // ACL cannot be `private`

Опять же, этот код следует компилировать только как часть целевого объекта приложения, и ваши модульные тесты могут быть настроены следующим образом:

@testable import MyApp
// should be able to access `MyModel`

Убедитесь, что для параметров сборки MyApp установлено Enable Testability значение YES.

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

В Realm есть выделенный раздел их документации, в котором подробно описаны эти общие подходы к тестированию, которые вы можете прочитать здесь: https://realm.io/docs/swift/latest/#avoid-linking-realm-and-tested-code-in-test-targets

Ответ 2

Мне пришлось прекратить таргетинг на все мои файлы .swift, чтобы иметь членство в MyAppTests, и полагаться только на @testable import MyApp

Ответ 3

Я также получил эту ошибку недавно, и ни один из вышеупомянутых шагов не устранила проблему, что же это исправить удаляло, не быстрый файл из <сильного > Compile источники построить фазу в Target вы хотите запустить тесты на. Это терпело неудачу

введите описание изображения здесь

Ответ 4

Сначала убедитесь, что @testable import MyApp включен в каждый тестовый файл. Затем на этапах создания тестовых целевых объектов удалите все нетестовые файлы в разделах "Ресурсы копирования". Файлы приложений, которые находятся в вашей тестовой цели, указывающие на файлы приложений, которые не входят в тестовую цель, нарушают ваши модульные тесты. Удалите все файлы приложений из тестовой цели и добавьте флаг @testable, и все должно работать!

Ответ 5

У меня была аналогичная проблема, и проблема заключалась в том, что все исходные файлы приложения были связаны с целевым объектом unit test и поэтому скомпилированы дважды!

Кроме того, я установил Realm через Carthage и должен был включать обе цели (основной и тестовый) для фреймворков "Realm.framework" и "RealmSwift.framework", потому что это не сработало бы иначе.

Вот ссылка на проблему

https://github.com/realm/realm-cocoa/issues/3627