Category Archives: Xcode 5

How is everybody liking XCTest?

Ok, Xcode 5 and XCTest have been out for awhile now. What has been your experience with it?

I’ve used it for some simple projects, doing TDD with it. I’ll have more to say about that in the near future. But I have to say that I really like the tighter integration of unit testing into Xcode.

One of my favorite things is the speed at which I can perform the TDD loop. This has been boosted by a couple things: the test classes assistant, and the ability now to rerun a single test by clicking on the symbol next to the line number (red “x” for a failing test, green checkmark for a passing test).

In the screen capture below, I’m using the test classes assistant to display the associated unit test case file on the right. I’ve just run tests, and the test at line 37 on the right failed, and is highlighted. Note that the other tests have a green checkmark next to them.

Although you can’t tell from this screen capture, I’m hovering the mouse over the red checkmark left of the line number at line 37, which has caused the checkmark to switch to a right arrow. Clicking on this reruns just that test. How cool is that!

Xcode test assistant
XCTest example of failing test

XCTest Assertions

XCTest supports the following assertions. This list is essentially the same as the list of assertions supported by SenTestingKit, but with the “ST” prefix changed to “XCT”.

  • XCTFail (format…)
  • XCTAssertNil (a1, format…)
  • XCTAssertNotNil (a1, format…)
  • XCTAssert (a1, format…)
  • XCTAssertTrue (a1, format…)
  • XCTAssertFalse (a1, format…)
  • XCTAssertEqualObjects (a1, a2, format…)
  • XCTAssertEquals (a1, a2, format…)
  • XCTAssertEqualsWithAccuracy (a1, a2, accuracy, format…)
  • XCTAssertThrows (expression, format…)
  • XCTAssertThrowsSpecific (expression, specificException, format…)
  • XCTAssertThrowsSpecificNamed (expression, specificException, exceptionName, format…)
  • XCTAssertNoThrow (expression, format…)
  • XCTAssertNoThrowSpecific (expression, specificException, format…)
  • XCTAssertNoThrowSpecificNamed (expression, specificExcepton, exceptionName, format…)

Refer to XCTestAssertions.h. The easiest way to locate this file is to Ctrl+Click on an assertion (such as “STFail”), and select “Jump to Definition”.


XCTest First Impressions

One of the big improvements in Xcode 5 is unit testing. Woohoo!!!

  • A Test Navigator has been added.
  • The Assistant Editor provides new test categories that place code and tests side by side.

SenTestingKit has been replaced with XCTest. This appears to be essentially just a renaming of SenTestingKit to XCTest, with assertions renamed from ST* to XCT*. For example, STAssertTrue is now XCTAssertTrue.

Also, the previous concept of “Logic” and “Application” tests is gone. By default, all tests are now “application tests”.

The Xcode 5 templates also do not provide an option to “Include unit tests”. Unit tests are always included. And there is an option in Xcode 5 to convert existing OCUnit (SenTesting) projects to use XCTest, making it easy to make the change.

I guess unit testing is finally a first class citizen in iOS development now.

Converting OCUnit to XCTest

My first attempt at converting a real project to XCTest in Xcode 5 went fairly well. The project was fairly simple, and had 582 OCUnit Application tests using OCHamcrest assertions. I performed this using Xcode 5 DP3, so the issues I encountered should have been fixed by the time you read this.
Xcode 5 supports both OCUnit and XCTest, so the app loaded and the tests ran ok. Interestingly, the Test Navigator displayed all of the OCUnit tests nicely. I had wondered whether or not the Test Navigator only worked with XCTests. It works with both though.
Once all the tests were passing, I then used the “Edit -> Refactor -> Convert to XCTest” menu option to convert the OCUnit test target to XCTest. I wasn’t sure what was going to happen, but had Git ready to undo any changes if/when things got messed up. It turned out that I didn’t need to do this.
The conversion worked almost perfectly. This isn’t a tough operation, basically just changing the #import from SenTestingKit to XCTest, and changing the test case class parent from SenTestCase to XCTestCase.
This conversion reused the same target, without renaming it. So things look pretty much the same in the Test Navigator before and after the conversion.
Then I tried to run the tests. I expected that the tests would fail, or maybe even fail to compile due to OCHamcrest. What happened though was that Xcode 5 crashed. However, upon restarting Xcode 5, I could then select to run the tests without crashing, but got a linker error.
The conversion operation did not add the XCTest framework to the converted target. It did remove the SenTestingKit framework though. So this is probably just a bug in DP3. I submitted radar 14470998 which is fixed in the latest code.
After adding XCTest to the test target’s link build step, all tests ran and passed!
I have wondered, and talked with other developers that I work with, about why Apple would simply rename SenTestingKit to XCTest. It doesn’t appear that much if anything is functionally different. I’ve come to the conclusion (and the hope) that this is just the beginning. Having a totally separate, new framework allows Apple to make changes and additions going forward, without worrying about breaking legacy SenTestingKit users. Let’s hope that this is a new start for unit testing support from Apple.