Streaming is available in most browsers,
and in the WWDC app.
-
Testing in Xcode
Unit testing is an essential tool to consistently verify your code works correctly. Learn about the built-in testing features in Xcode, using XCTest. Find out how to organize your tests and run them under different configurations using test plans, new in Xcode 11. Discover how to automate testing and efficiently work with the results.
Resources
Related Videos
WWDC 2020
WWDC 2019
- Creating Great Localized Experiences with Xcode 11
- Designing for Adverse Network and Temperature Conditions
- Getting Started with Xcode
- Improving Battery Life and Performance
- What's New in Xcode 11
WWDC 2018
-
Download
Good morning, and welcome to Testing in Xcode. My name is Ana Calinov and I'll be presenting along with my colleagues, Stuart Montgomery and Ethan Vaughan.
In today's session, we'll start with an introduction to testing in XCode with XCTest.
Then, Stuart will tell you about the test plans feature.
Finally, Ethan will show you applications of XCTest with continuous integration.
Let's get started with XCTest. XCTest is the automation testing framework provided in Xcode with built-in support to help you set up and execute your tests. Testing is an important step of developing any project which can help you find bugs in your source code.
You can also use test to codify requirements, meaning you make test for expected behaviors for your app, and further work by you and your team can be qualified against these expectations. We're going to start with a summary of how you should consider planning out the automation test suite of any project.
The pyramid model approach to testing helps to strike a balance between thoroughness, quality and execution speed.
Unit tests are the foundation of our pyramid. Unit tests help verify a single piece of code, generally a function.
This is done by inputting variables to the function and checking that they return the expected output.
Unit tests are short, simple, and run very quickly.
This is the foundation of all of our testing so you want to write many unit tests to cover all your functions.
Next, we have integration tests.
Integration tests are used to validate a larger section of your code.
These tests should target discrete subsystems or clusters of classes to make sure that different components behave correctly together. Integration tests sit on top of unit tests, because you want to make sure that the individual functions behave correctly before testing this larger piece of your code.
You generally also won't need as many integration tests as unit test.
They may take slightly longer to run but they do test more of your app at once. Lastly, user interface or UI tests observe the user-phasing behavior of your app.
This makes sure that your app truly does what you expect it to.
UI tests take the longest to run but they're vital to demonstrating that everything behaves correctly.
UI tests also require more maintenance because your app's UI may change more frequently.
The full pyramid of tests can therefore help you balance between these three different test types and ensures your test suite gives you the coverage that you need.
So we just went over how to balance your test suite, so now let's switch to the tools provided by XCTest to help you implement it.
Unit tests in XCTest are all of your tests targeting your source code.
This includes both your standard unit test and also your integration tests.
UI tests execute on top of your app's UI to provide end-to-end qualification of your app.
UI tests are also black box test because they won't rely on any knowledge of the functions or classes actually supporting your app.
UI tests will be able to make sure that everything behaves correctly at the very end.
Lastly, performance tests run multiple times over a given test to look at the average timing, memory usage or other metric given to it to make sure you don't introduce regressions in these areas.
Today, we'll be focusing on unit and UI tests.
The easiest way to get started with testing in your Xcode project is to choose to include both unit and UI tests when starting a new project.
In our brand new project, you can see the unit tests targeting class and the UI tests targeting class automatically created and displayed in your project navigator. You are also provided with the template to start writing each of these test classes and the test cases within them.
Now let's take a closer look at a test class that uses XCTest.
The class imports the XCTest framework along with the target to be tested.
The class itself is a subclass of XCTest case which allows its methods to be used by Xcode to execute tests.
Each method we want to use as a test case must start with the word test and then hopefully be named something that indicates what it will do.
You'll also see a test diamond appear to the left of the test to show that Xcode can execute it. Inside of the test, assertion APIs are used to evaluate and validate your source code.
In this case, XCTAssertEqual will compare the first two values given to it and make sure that they're equal.
If they differ, the test will fail instead.
Now, once we run this test, we hope that it passes and the test diamond turns green with the checkmark inside.
We know this isn't always the case though.
If the test fails, the test diamond turns red with an x and the relevant line will highlight.
We also get an error message that shows what went wrong in the test.
The string we pass to XCTAssertEqual also shows up now to give us more information to debug the issue. In this case, we may have an off by one error in our source code or you may have initialized to an unexpected value.
We can go back to the source code, fix this issue, and run our test again until it passes. Each test class template will also include a setUp and a tearDown method.
These blocks serve as a way for you to do any work you need to around your test in order to keep your tests specific to their purpose.
SetUp is called before each of your test cases executes.
In UI test, this helps ensure that your app is launched before you try interacting with it.
XCTest then runs your test method and afterwards tearDown can be used to clean up any changes you've made to the data or the global state of your app, to make sure your test leaves nothing behind that could impact subsequent tests.
Now, let's go into a demo to see how to write unit and UI tests for your app.
So, we've been working on a travel app.
This shows different destinations around the world and can help you plan a vacation.
I'd like to add a new feature to my app that shows how far away each of these destinations is from our current location in San Jose.
For this, I've written a new class called DistanceCalculator.
This class defines a city struct that contains a string with the name of the city and a tuple for its coordinates.
I currently have my list of cities stored in a dictionary. I'm planning on moving these two database later though.
I have a function called city that will return an optional city struct type to be able to search my dictionary for the cities.
The main function I'm planning on using from this class is distanceInMiles.
This takes in two strings with city names and returns the distance between them as a double.
If either of the cities can't be found in our dictionary, an error will be thrown instead.
Lastly, I have another helper function also called distanceInMiles.
This one takes in our city struct and returns the distance between them.
This function uses the core location framework so that it does the heavy lifting for me.
Now, to start writing unit test for this class, I've created a new test class called DistanceCalculatorTests.
As I start writing tests, I want to see my source code so I'm going to open another editor

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
