Почему Travis не находит мой файл заголовка? (когда одна и та же инструкция выполняется нормально в моем локальном Xcode)

#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 Я обновил ответ, надеюсь, это немного прояснит.