9
votes

I have some open source code hosted on github for adding a block based category to UITextField. I have added a .travis.yml file to get travis CI to build and run the code on every push. Link to The Travis CI warning . It successfully builds the project. The warning i get when running the .travis.yml script is:

WARNING: Using Objective-C testing without specifying a scheme and either
a workspace or a project is deprecated.

The example project that i want to run is located in the folder /UITextView Blocks Example/ How can i add to the .travis.yml file to run this project? My travis.yml file now consists of

language: objective-c
2

2 Answers

17
votes

Update 2017

skypecakes mentions in the comments:

For anyone using XCode 8 and higher: xctool is no longer supported, and does not work.
Use xcodebuild instead.


Original answer (2013)

You can check this tutorial, which explains:

xctool is an excellent choice for running your tests under a continuous integration server such as Travis CI or Jenkins.
In order to your run your tests within a continuous integration environment, you must create Shared Schemes for your application target and ensure that all dependencies (such as CocoaPods) are added explicitly to the Scheme.
To do so:

  1. Open up the Manage Schemes sheet by selecting the Product menu > Schemes > Manage Schemes...
  2. Locate your application target in the list. Ensure that the Shared checkbox in far right hand column of the sheet is checked.
  3. If your application or test targets include cross-project dependencies such as CocoaPods, then you will need to ensure that they have been configured as explicit dependencies. To do so:
    • Highlight your application target and hit the Edit... button to open the Scheme editing sheet.
    • Click the Build tab in the left-hand panel of the Scheme editor.
    • Click the + button and add each dependency to the project. CocoaPods will appears as static library named Pods.
    • Drag the dependency above your application target so that it is built first.

You will now have a new file in the xcshareddata/xcschemes directory underneath your Xcode project.
This is the shared Scheme that you just configured.
Check this file into your repository and xctool will be able to find and execute your tests on the next CI build.

For more flexibility, you can also control how Travis installs and invokes xctool:

language: objective-c
before_install:
    - brew update
    - brew install xctool
script: xctool -workspace MyApp.xcworkspace -scheme MyApp test

That last configuration is similar to the approach illustrated in this other tutorial:

Once you have linked your repo the next step would be to add a .travis.yml file to the root of the repo.

  language: objective-c

  before_script: travis/before_script.sh
  script: travis/script.sh
  • First I’m telling Travis that this is an objective-c project.
  • Next I tell Travis how I’d like it to do CI against this repo by giving it instructions on what scripts it should run in order to actually perform a build.

I also give some extra instructions on what to do just prior to running a build.
It’s quite common to put all the build steps inline right in the .travis.yml file, but I prefer to actually create bash scripts in my repo inside a travis directory in my git repo and then just refer to those scripts from my .travis.yml.
This keeps the .yml file nice and small, and also makes it easy for me to test the travis build scripts locally.

We gave Travis a before_script in the .yml file above. This is intended to be used by the Travis agent to download tools needed as part of the build. Here’s what it looks like:

travis/before_script.sh

#!/bin/sh
set -e

brew update
brew install xctool

Very simple. We just use homebrew to install xctool on the build agent.
All travis build agents come with homebrew pre-installed, but sometimes the formula aren’t up to date, so it’s best to run a brew update before attempting a brew install.
That’s all we need to do to prepare our agent for the build.

Next let’s look at the build script itself:

travis/script.sh

#!/bin/sh
set -e

xctool -workspace MyWorkspace -scheme MyScheme build test

Again, this is really simple.
We first do a basic sanity check by asking xctool to build our app, specifying a workspace and scheme.
This just checks that we don’t have any compilation errors.
Assuming that succeeds xctool will then build and run the unit testing target for our app, launching the Simulator on the Travis agent if needed.

3
votes

When you specify the language is Objective-C in the .travis.yml file, the CI server will by default use their adapted version of osx-cibuild.sh. This will look for any workspaces in the current directory, and build all default targets.

Since your repo doesn't have any workspaces in the root (they are under Examples), it can't find what to build, and so won't build anything.

You can either move your project file from under Examples to the root, or specify what to build by setting XCWORKSPACE in your Travis CI config, or you could specify a custom script to run and then invoke xcodebuild yourself. Setting the workspace config is probably the preferred option; don't customise it if you don't need to.

Add something like the following to your .travis.yml:

env:
  - XCWORKSPACE="Examples/UITextField-Blocks Example.xcodeproj"

(The quotes are there due to the filename having an internal space.)

It's worth examining the osx-cibuild.sh script to see just how it works, and how you can customise its behaviour by setting various environment variables.

Useful references: