#ios #objective-c #cocoapods #travis-ci #xcode8
#iOS #цель-c #cocoapods #travis-ci #xcode8 #objective-c
Вопрос:
Проект библиотеки моего Cocoapod не проходит тесты на Travis, потому что цель тестирования, похоже, не может найти один из источников модуля:
'XYZMyClass.h' file not found
В моей среде разработки я могу запустить ту же команду, которую успешно выполняет Travis, и среды настроены одинаково:
- Изображение предназначено
osx_image: xcode8
для Трэвиса, и я также использую Xcode 8.0 локально -
Инструкция, которая не выполняется на Travis, но успешно выполняется локально, выглядит следующим образом:
set -o pipefail amp;amp; xcodebuild -workspace Example/XYZMyPod.xcworkspace -scheme XYZMyPod-Example -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6s,OS=9.3' test | xcpretty
Что еще более странно, ‘XYZMyClass.h’ является 2-м импортом в моем исходном файле imports. Почему 1-й работает нормально? Они принадлежат одной и той же цели, с одинаковой видимостью ( Public
).
PS: исходный код доступен на GitHub здесь, а сборка Travis находится здесь.
Спасибо!
Ответ №1:
Корень проблемы заключается в вашем BSGMetrics.podspec
При установке pod эти заголовки становятся общедоступными:
s.public_header_files = [
'BSGMetrics/Classes/BSGMetrics.h',
'BSGMetrics/Classes/BSGMetricsConfiguration.h',
'BSGMetrics/Classes/BSGMetricsEvent.h'
]
Вот почему в вашем тестовом классе вы можете видеть первый импорт и не можете видеть второй импорт.
#import "BSGMetricsEvent.h"
#import "BSGMetricsService.h"
Если сервис предназначен для частного заголовка, вы не сможете протестировать его при такой установке — с помощью примера проекта с целью тестирования и вашего модуля, установленного как pod.
Вместо этого вам нужно добавить ваши pod-файлы в основную или тестовую цель проекта (и я предлагаю test, а не main).).
В любом случае, простейший обходной путь здесь — выставить BSGMetricService
в s.public_header_files
РЕДАКТИРОВАТЬ (Описание подходов к тестированию):
Хитрость в том, как вы обрабатываете модульные тесты. Подумайте о BSGMetrics как о «модуле», черном ящике. У него есть некоторый «видимый» интерфейс и некоторые скрытые детали реализации. Это верно как для Objective-C, так и для Swift. Разница заключается в языковых инструментах, используемых для определения видимости объектов вашего модуля. В Objective-C это файлы заголовков. В Swift это public
private
internal
модификаторы , , (до Swift 3.0)
Итак, пока вы не обработаете свою BSGMetrics как модуль во время тестирования, вы не сможете получить доступ / протестировать детали своей реализации. Вы сможете протестировать его только через доступный интерфейс.
Это плохо или хорошо? На самом деле, все зависит от того, что вам нужно. Однако, если вы ожидаете [BSGMetrics openWithConfiguration:]
, что экземпляр BSGMetricsService
инициализирован, вы должны BSGMetricsService
быть видны в рамках вашего теста. И есть два подхода: сделать видимым (как вы использовали сейчас) или объединить области модуля и теста.
Я немного опишу, как я использую последний подход для тестирования одной из моих библиотек.
Во-первых, цель тестирования — это часть того же проекта, куда также добавляются все тестируемые файлы.
Во-вторых, тестирование выполняется только внутри test bundle, без хост-приложения.
В-третьих, тестируемые файлы также добавляются для компиляции в целевой объект тестирования.
Короче говоря, тесты и тестируемый код находятся в одном модуле.
Дополнительную информацию можно найти здесь
Комментарии:
1. Это обходной путь, но на самом деле не решает мою проблему. Насколько я понимаю, Swift обеспечивает лучший ответ на этот сценарий, поэтому я не буду слишком сильно бороться с этим и рассматривать это как еще один стимул для перехода на Swift как можно скорее. Спасибо. 🙂
2. Я рад, что ваша сборка теперь работает. Я почему-то не согласен с вами относительно «у Swift нет проблем». Я отредактирую свой вопрос, чтобы добавить некоторые мысли о подходе к тестированию в ближайшее время, чтобы дать некоторые дополнительные идеи
3. @DirtyHenry Я обновил ответ, надеюсь, это немного прояснит.