If you’ve been kind enough to check out my previous testing blogs, and you’ve looked at the Github project for them, you’ll noticed that there are fancy “pod install” commands you have to run to get the project up and running. While you can install Cedar globally, the demo project I put up on Github uses CocoaPods to install the Cedar test framework. Since I will continue to use this Github project in future blog posts, let’s get Cedar up and running using CocoaPods.
CocoaPods is an awesome dependency manager. I would recommend checking out cocoapods.org to see what it is all about, as it’s pretty much the “de-facto” iOS/OSX dependency manager. If you’ve used ruby gems before, most of this will be familiar. Put it this way, Cocoapods ≈ Gems. In ruby gems, you have gems, in CocoaPods you have pods.
If you open the Github project from the previous two BDD posts (Easy stuff - Part I and Part 2), you will notice that there are some “setup” steps that must be followed in order to run the specs. Like the README states, in order to follow along with this post, please setup your environment with these prerequisites:
- Install a Ruby version manager. The two major managers are rbenv and rvm. I recommend rbenv personally as it has less “hacks” on the bash terminal and is easy to uninstall if you choose to ever get rid of it.
- Install Ruby Gems. I will use ruby gems to to add the CocoaPod gem to our environment.
- Install Bundler. While installing gems globally in the entire system (and again the choice is yours) is OK, I prefer to use a Gemfile and bundler for the project itself. This way the versions of your gems can be different across different projects. It also makes it easy to “freeze” your project setup for easy usage if you post your project on github for others to use.
- Install Cedar. Even though I will be using the Cedar CocoaPod for the blog post, the Cedar templates and snippets are required.
Setting up CuckooForCedar project
To follow along with the project, let’s create a Xcode empty project called “CuckooForCedar” on the desktop:
Now that we have a basic project, and we want to use Cedar for our tests, we need to delete the default test target, test group, tests and remove test target from the CuckooForCedar target scheme:
Next, we create the Specs target using the Cedar test bundle template:
After we create the Specs target, we need to set it to “CuckooForCedar” under the “General” tab for “Specs” in the “Targets” section of the project settings:
Since we are going to be using Cedar as a CocoaPod, we need to delete the Cedar.framework that was added to the Specs target (let’s also delete the Rakefile while we are at it as we will create our own in the next blog post):
With the Cedar.framework gone, the Specs target will no longer build. Let’s go ahead and add it as a CocoaPod in the next section.
Installing Cocoapods in our project
Using the terminal, navigate to the CuckooForCedar Xcode project directory. Once we are here, let’s create a Gemfile using bundler:
1 2 3
Now that we have a Gemfile, let’s edit it (feel free to use the text editor of your choice).
1 2 3
Once we’ve added the CocoaPods gem in our Gemfile, we run bundler (bundle) to install it locally to our project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
As you can see above, bundler installs all the dependencies needed to get us up and running. Since CocoaPods is up and ready to go, let’s add a Podfile locally using bundler (hence the bundle exec part of the command):
Now that we have a Podfile, let’s add Cedar version 0.9.5 to the Specs target we created:
1 2 3
Now that we’ve specified the cedar dependency, let’s install it locally using bundler:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
As you can see, CocoaPods installs the dependencies we need just like Bundler did previously. If you look at the output, you will see three “[!]”. The first one is pretty straight forward. When using CocoaPods in a project, you will use the .xcworkspace files instead of the .xcodeproj ones. The last two require a little bit more setup in the Xcode project itself, as we need to add “$(inherited)” to debug/release for OTHER_LDFLAGS in the build settings for Specs:
Since the $(inherited) includes the setting “-ObjC”, remove it from the list, and add $(inherited) in it’s place like the screenshot above.
Since we still have the ExampleSpec.mm included in our Specs group, let’s run the tests and get our first green test build!
As stated in the previous Cedar blog posts, you can checkout the CuckooForCedar Repo project for an example of everything up and running.
What is the point in using CocoaPods for Cedar? Couldn’t we have just used the framework that was included when we created the Specs target using the Cedar test bundle template?
While Cedar can be used with the Cedar.framework by itself, I will give you 4 good reasons to use the CocoaPod instead:
- Your git repo will be lighter. Since the CocoaPods are obtained using “bundle exec pod install” locally, you can add the pods directory to the .gitignore file and not push up the framework at all.
- If you have your project on Github, it will show as an Objective-C project instead of a C++ project. Since Cedar is written in C++, if you include the framework and you have a smaller project, it will show up as C++.
- You have a “locked” version of Cedar attached to your project. If you are using a CocoaPod, it’s easy to lookup the tag of the version of Cedar being used and figure out which commit SHA is being used. This is difficult if you just have the framework installed and upgrade the Cedar project here and there.
- The continous integration service travis-ci seems to like CocoaPods better. I’m going to be honest, travis-ci is NOT the easiest thing to setup, and trying to debug environment issues on their end is nearly impossible. I had various build issues using the framework, but after switching to the Cedar CocoaPod, all the build problems went away.
CocoaPods is pretty impressive. Like Bundler, it gives us an easy way to keep our software dependencies in check and provide a great workflow for 3rd party versioning. I’m glad that the developers of CocoaPods decided to keep the name of the manager light hearted and fun like bundler. It’s a bummer that the node.js people did the opposite and called their dependency manager NPM.