Xcode 5: Unit Testing Changes

September 30th, 2013

Filed under: Xcode | 6 comments

One of the biggest areas of change in Xcode 5 involves unit testing. This post details those changes.

Test Navigator

Xcode 5 adds a test navigator to the available navigators on the left side of the project window. You can see an example of the test navigator in the following screenshot:

Xcode 5 Test Navigator

The test navigator has one listing for each unit test class in your test target. Click the disclosure triangle next to a test class to see the tests for that class. Selecting a test class opens that class in Xcode’s editor. Selecting a test takes you to the selected test in Xcode’s editor.

The test navigator lets you control what tests are run. Selecting the unit testing target, a test class, or an individual test makes a Play button appear next to the selected item in the project navigator (where the green checkmarks are in the screenshot). Click the Play button to run tests. Clicking the Play button for the unit testing target runs all the tests. Clicking the Play button for a test class runs all the tests for that class. Clicking the Play button for an individual test runs one test. If a test passes, it has a green checkmark next to it. Failing tests have a red X next to them.

Xcode 5 also allows you to run tests from the editor. Look at the following screenshot for the start of a unit test:

Xcode 5 Test From Editor

Notice the diamond next to line 52 in the screenshot. Click the diamond to run the test. Running unit tests from the editor helps when you have a failing test. Click the diamond to rerun the failing test without having to run the whole test suite.

New Projects Include a Unit Testing Target

If you create a new Cocoa or iOS application project in Xcode 5, you will notice there is no checkbox to include a unit testing target. New Cocoa and iOS application projects automatically include a unit testing target.

If you don’t unit test your code, you can delete the unit testing target. Select the project from the project navigator to open the project editor. Select the unit testing target from the target list on the left side of the project editor. Right-click and choose Delete.

XCTest

Xcode 5 introduces a new unit testing framework for Cocoa and Cocoa Touch applications, XCTest. If you used OCUnit in Xcode 4, you should have little trouble using XCTest because OCUnit and XCTest are very similar. The biggest difference is that XCTest assertions start with XCTAssert instead of STAssert. Another change I noticed is that XCTest has no equivalent to the assertions STAssertTrueNoThrow and STAssertFalseNoThrow. If you haven’t used OCUnit, you can read my Introduction to Unit Testing with OCUnit post to learn more about OCUnit. When reading that post, keep in mind that XCTest test classes do not have a header file.

Xcode 5 supports both XCTest and OCUnit, but XCTest is the future of Objective-C unit testing for Mac OS X and iOS. New projects use XCTest. If you are adding a unit testing target to an existing project, I recommend using XCTest unless you need to run unit tests in Xcode 4.

If you get a linker error when running your tests that looks similar to the following message:

Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_YourClass"
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Where YourClass is one of the application classes you’re testing, you’ll need to make the application class a member of the unit testing target. Select the .m file from the project navigator. Go to the file inspector. Select the checkbox for the unit testing target in the Target Membership section.

XCTest Refactoring Tool

Xcode 5 includes a refactoring tool to convert your OCUnit unit tests to XCTest. Choose Edit > Refactor > Convert to XCTest. The refactoring tool converts your OCUnit test target to XCTest and converts your test classes and tests to XCTest.

I recommend backing up your project before running the refactoring tool. I had a problem with the beta versions of Xcode 5 where the test navigator showed zero tests after running the refactoring tool, and my tests didn’t run. The problem was fixed in the release version, but I still had the problem in one project. My workaround was to perform the following steps:

  1. Restore the backup.
  2. Delete the old unit testing target from the project.
  3. Remove the unit test classes from the project. Remove the file references from the project. Don’t move the files to the Trash.
  4. Add a new XCTest target to the project.
  5. Add the unit test classes back to the project.
  6. Run the refactoring tool.

Assistant Editor

The assistant editor in Xcode 5 places your tests and the application code being tested side by side. I haven’t been able to verify this feature, but it is mentioned in the What’s New in Xcode document (In Xcode choose Help > What’s New In Xcode) in the Testing section.

Why haven’t I been able to verify this feature? Xcode 5 crashes a lot when I switch to the assistant editor. When Xcode doesn’t crash, selecting a test from the test navigator doesn’t update the assistant editor with the code being tested. Hopefully you’ll have more success with the assistant editor than I have.

Test After Build

Xcode 4 had a Test After Build build setting that ran your unit tests after building your projects. Xcode 5 does not support this build setting. If your project sets Test After Build to YES, you should set it to NO, or you will get errors when running tests or running the XCTest refactoring tool.

Tags: ,


6 thoughts on “Xcode 5: Unit Testing Changes

  1. Tim Macfarlane says:

    For linker errors looking for a class in your app, you suggested that you add the *.m file to the test target. A better way seems to be to set the “Symbols Hidden by Default” build setting to “NO” in your app target. This makes all your app classes available to your test target automatically, so there’s no need to add them to your test target.

    See this: Adding Unit Tests to an existing iOS project with Xcode 4. Although aimed at Xcode 4 and OCTest, the information is still largely correct.

    • Mark Szymczyk says:

      Tim,

      Thanks for the suggestion. Setting the Symbols Hidden by Default build setting to NO sounds like an easier workaround.

  2. Tim Macfarlane says:

    Hi again Mark,

    Turns out the “Symbols Hidden by Default” = “NO” setting only works for Functional Testing, as in, for tests that have a “Test Host” and are hosted inside your app. Otherwise, for Logic Tests, you have to include the classes in the target as you suggest.

  3. Thank you for including the “linker error” fix.

  4. Ryan Mathews says:

    I agree with Samuel. Thank you very much for adding information about the linker error. I wish I found this a couple hours ago. Now just to figure out how to make it recognize my cocoapod files.

  5. Jay Mayu says:

    The linker error completely consuming me. 🙂

    I added the missing VC as you suggested then it suggesting me to include all the header files I have referred in the VC. Man that is alot 🙁

Leave a Reply

Your email address will not be published. Required fields are marked *