Why can't Travis find my header file? (when the same command works fine on my local Xcode)

My Cocoapod lib project does not run its tests on Travis, because the test object does not seem to be able to find one of the Pod sources:

'XYZMyClass.h' file not found 

In my development environment, I can run the same command that Travis works successfully and the environments are installed the same way:

  • Image osx_image: xcode8 for Travis and I use Xcode 8.0 locally as well
  • An instruction that fails in Travis but succeeds locally is as follows:

     set -o pipefail && xcodebuild -workspace Example/XYZMyPod.xcworkspace -scheme XYZMyPod-Example -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6s,OS=9.3' test | xcpretty 

Even stranger, "XYZMyClass.h" is the second import in my import of the source file. Why does the first one work fine? They belong to the same goal with the same visibility ( Public ).

PS: the source is available on GitHub here , and the Travis build is here .

Thanks!

+5
source share
1 answer

The root of the problem lies in your BSGMetrics.podspec

After installing pod, these headers become public:

  s.public_header_files = [ 'BSGMetrics/Classes/BSGMetrics.h', 'BSGMetrics/Classes/BSGMetricsConfiguration.h', 'BSGMetrics/Classes/BSGMetricsEvent.h' ] 

That is why in your test class you can see the first import and you cannot see the second import.

 #import "BSGMetricsEvent.h" #import "BSGMetricsService.h" 

If the service is intended for a private header, you cannot test it with such an installation - through a sample project with a test target and your module installed as pod.

Instead, you need to add swap files to the main or test goal of the project (and I suggest a test, not the main one).

In any case, the easiest workaround here is to excerpt BSGMetricService in s.public_header_files

EDIT (Description during testing):

The trick is how you handle unit tests. Think of BSGMetrics as a β€œmodule”, a black box. It has some β€œvisible” interface and some hidden implementation details. This is true for both Objective-C and Swift. Different language tools used to determine the visibility of your modules. In Objective-C, these are header files. In Swift, these are modifiers public , private , internal (before Swift 3.0)

Thus, until you process BSGMetrics as a module during testing, you will not be able to access / verify your implementation details. You can only test it through the accessible interface.

Is it bad or good? Not really, it all depends on what you need. However, if you expect an instance of BSGMetricsService be created on [BSGMetrics openWithConfiguration:] , you need the BSGMetricsService be visible for your test area. And there are two approaches: make is visible (as you have used so far) or the merge module and testing areas.

I will describe a little how I use the latter approach to test one of my libraries.

Firstly, the test target is part of the same project, where all the tested files are also added.

Secondly, testing is performed only inside the test package, without a host application. enter image description here

Thirdly, the files under testing are added for compilation to the test target.

In short, tests and code in tests are in the same module.

Detailed reading can be found here.

+1
source

Source: https://habr.com/ru/post/1257983/


All Articles