© 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
Developer Tools
#WWDC16
Session 409
Advanced Testing and
Continuous Integration
Zoltan Foley-Fisher Xcode Engineer
Agenda
Agenda
Testing Concepts Xcode
Agenda
Testing Concepts Xcode
• Crash Log Gathering Xcode Server
• Advanced Triggers
• Issue Tracking and Blame
Agenda
Testing Concepts Xcode
• Crash Log Gathering Xcode Server
• Advanced Triggers
• Issue Tracking and Blame
• Configurable Integration User xcodebuild
Testing framework
XCTest
Testing framework
XCTest
Sources TestClassA.m TestClassB.swift TestClassC.swiftTesting framework
XCTest
Compile Build Products UI.xctest Unit.xctest Sources TestClassA.m TestClassB.swift TestClassC.swiftTest harness
Xcode
Test harness
Xcode
Test harness
Xcode
Author tests Execute tests
Test harness
Xcode
Author tests Execute tests
Continuous Integration
Xcode Server
Continuous Integration
Xcode Server
Continuous Integration
Xcode Server
Schedules bot runs Generates reports
Continuous Integration
Xcode Server
Schedules bot runs Generates reports Sends notifications
Command line tool
xcodebuild
Command line tool
xcodebuild
Command line tool
xcodebuild
Used by Xcode Server Build and execute tests
Command line tool
xcodebuild
Used by Xcode Server Build and execute tests For custom CI systems
Previous Years’ Sessions
Testing with Xcode 6 WWDC 2014
Continuous Integration with Xcode 6 WWDC 2014
UI Testing in Xcode WWDC 2015
Behind the scenes
How Testing Works
Fundamental concepts
Testing Timeline
How testing starts
Test Hosting
How testing starts
Test Hosting
MyApp.app
How testing starts
Test Hosting
MyApp.app
How testing starts
Test Hosting
MyApp.app
Unit Tests UI Tests
How testing starts
Test Hosting
MyApp.app UI Test Runner MyApp.app
Unit Tests UI Tests
How testing starts
Test Hosting
MyApp.app UI Test Runner MyApp.app
Unit Tests UI Tests
How testing starts
Test Hosting
MyApp.app UI Test Runner MyApp.app
Unit Tests UI Tests
Comparison
Test Hosting
Unit Tests UI Tests
Direct access to host app data and APIs Uses Accessibility to access target app All tests run in single app launch Tests launch app for every test case
Comparison
Test Hosting
Unit Tests UI Tests
Direct access to host app data and APIs Uses Accessibility to access target app All tests run in single app launch Tests launch app for every test case
Fundamental concepts
Testing Timeline
Fundamental concepts
Testing Timeline
Test case structure
Test case structure
Test Observation
Test case structure
Test Observation
Test case structure
Test Observation
Test case structure
Test Observation
Test Suite A Test Suite B
Test case structure
Test Observation
Setup or tear down work
Test Suite A Test Suite B
Test case structure
Test Observation
Setup or tear down work Custom logging
Test Suite A Test Suite B
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testBundleWillStart(_ testBundle: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testSuiteWillStart(_ testSuite: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testCaseWillStart(_ testCase: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testCaseDidFinish(_ testCase: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testCase(_ testCase: AnyObject!, didFailWithDescription
description: AnyObject!, inFile filePath: AnyObject!, atLine lineNumber: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testSuiteDidFinish(_ testSuite: AnyObject!)
XCTestObservation Protocol
Test Observation
Test Suite A Test Suite B
Test Bundle
optional public func testBundleDidFinish(_ testBundle: AnyObject!)
// Test Observation
// Example LoggingObserver
class LoggingObserver: NSObject, XCTestObservation {
// Test Observation
// Example LoggingObserver
class LoggingObserver: NSObject, XCTestObservation {
override init() { super.init()
let sharedCenter = XCTestObservationCenter.shared()
sharedCenter.addTestObserver(self)
}
// Test Observation
// Example LoggingObserver
class LoggingObserver: NSObject, XCTestObservation {
override init() { super.init()
let sharedCenter = XCTestObservationCenter.shared()
sharedCenter.addTestObserver(self)
}
internal func testBundleWillStart(_ testBundle: Bundle) { print("Lights down, show is about to start")
}
// Test Observation
// Example LoggingObserver
class LoggingObserver: NSObject, XCTestObservation {
override init() { super.init()
let sharedCenter = XCTestObservationCenter.shared()
sharedCenter.addTestObserver(self)
}
internal func testBundleWillStart(_ testBundle: Bundle) { print("Lights down, show is about to start")
}
internal func testCase(_ testCase: AnyObject!, didFailWithDescription
description: AnyObject!, inFile filePath: AnyObject!, atLine lineNumber: AnyObject!)
print("That sounds off key…") }
// Test Observation
// Example LoggingObserver
class LoggingObserver: NSObject, XCTestObservation {
override init() { super.init()
let sharedCenter = XCTestObservationCenter.shared()
sharedCenter.addTestObserver(self)
}
internal func testBundleWillStart(_ testBundle: Bundle) { print("Lights down, show is about to start")
}
internal func testCase(_ testCase: AnyObject!, didFailWithDescription
description: AnyObject!, inFile filePath: AnyObject!, atLine lineNumber: AnyObject!)
print("That sounds off key…") }
internal func testBundleDidFinish(_ testBundle: Bundle) { print("Lights up, don’t forget your coat!")
} }
Use NSPrincipalClass
Use NSPrincipalClass
Test Observation
Use NSPrincipalClass
Test Observation
Test Bundle Info.plist
Summary
Testing Concepts
Crashes during testing
Crashes during testing
Crashes during testing
Crash Log Gathering
Crashes during testing
Crash Log Gathering
Test host or target application may crash Xcode completes test suite
Crashes during testing
Crash Log Gathering
Test host or target application may crash Xcode completes test suite
Improved test reports
Improved test reports
Improved test reports
Crash Log Gathering
For Unit and UI tests
Improved test reports
Crash Log Gathering
For Unit and UI tests
Local and Xcode Server crash logs
Improved test reports
Crash Log Gathering
For Unit and UI tests
Local and Xcode Server crash logs Logs included in test report
Improved test reports
Crash Log Gathering
For Unit and UI tests
Local and Xcode Server crash logs Logs included in test report
View crashes in Xcode’s Debug Navigator
Demo
Improved test reports
Crash logs gathered in test reports
Improved test reports
Crash logs gathered in test reports
View crashes in Xcode’s Debug Navigator
Improved test reports
Continuous Integration in Xcode
Xcode Server
Eric Dudiak
Overview
Overview
Xcode Server
Overview
Xcode Server
Custom environment variables Advanced trigger editing
Overview
Xcode Server
Custom environment variables Advanced trigger editing
Overview
Xcode Server
Custom environment variables Advanced trigger editing
Issue tracking and blame Upgrade integrations
Overview
Xcode Server
Custom environment variables Advanced trigger editing
Issue tracking and blame Upgrade integrations
New in Xcode 7.3
Integration scripts
Email notifications
Email notifications
Email notifications
Email notifications
Email notifications
Email notifications
We all have issues
We all have issues
Issue Tracking and Blame
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
• Errors will come up
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
• Errors will come up
• Xcode will blame you Even if you are perfect
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
• Errors will come up
• Xcode will blame you Even if you are perfect • SDKs change
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
• Errors will come up
• Xcode will blame you Even if you are perfect • SDKs change
We all have issues
Issue Tracking and Blame
Nobody is perfect • Tests will fail
• Errors will come up
• Xcode will blame you Even if you are perfect • SDKs change
• Language improvements • Smarter tools
Identifying issue owners
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified • You are the only committer
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified • You are the only committer
You can help fix it
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified • You are the only committer
You can help fix it
• You probably know how to fix an issue
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified • You are the only committer
You can help fix it
• You probably know how to fix an issue
• You seem to know about the area involved
Identifying issue owners
Issue Tracking and Blame
Lets you know when it’s time to act You broke it
• You introduced an issue
• Issue is on or near line you modified • You are the only committer
You can help fix it
• You probably know how to fix an issue
• You seem to know about the area involved • Fuzzy matching
Bot configuration changes
Bot configuration changes
Issue Tracking and Blame
Tracks changes to your bot configuration
Bot configuration changes
Issue Tracking and Blame
Tracks changes to your bot configuration
Attributes issues to changes where possible
Bot configuration changes
Issue Tracking and Blame
Tracks changes to your bot configuration
Attributes issues to changes where possible Included in email reports
When it’s not your fault
When it’s not your fault
Upgrade Integrations
Re-integrates your project
When it’s not your fault
Upgrade Integrations
Re-integrates your project
Same revision as the last integration
When it’s not your fault
Upgrade Integrations
Re-integrates your project
Same revision as the last integration
Any new issues are due to the upgrade
When it’s not your fault
Upgrade Integrations
Re-integrates your project
Same revision as the last integration
Any new issues are due to the upgrade Prevents blaming you for broken builds
Configurable Integration User
Configurable Integration User
Improved visibility into your integrations Allows customization
Configurable Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Configurable Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Configurable Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
••••••••••••••• •••••••••••••••
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Custom Integration User
Improved visibility into your integrations Allows customization
You own and manage how your integrations run
Can be any user on the system Runs as a menu extra
Demo
Configurable Integration User
Configurable Integration User
Improved visibility
Configurable Integration User
Improved visibility
Customized simulators Normal macOS user
Configurable Integration User
Improved visibility
Customized simulators Normal macOS user
Best practices
Best practices
Configurable Integration User
Best practices
Configurable Integration User
Dedicate a new user
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Customize for your needs • Simulators
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Customize for your needs • Simulators
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Customize for your needs • Simulators
• Networking (VPN and proxies) • User data and settings
Best practices
Configurable Integration User
Dedicate a new user
Avoid using administrator accounts
Stay logged in with Fast User Switching Disable screen lock
Customize for your needs • Simulators
• Networking (VPN and proxies) • User data and settings
Building block for Continuous Integration Systems
Test action
xcodebuild
xcodebuild test -workspace <path> -scheme <name>
Test action
xcodebuild
Builds sources
xcodebuild test -workspace <path> -scheme <name>
Test action
xcodebuild
Builds sources
Installs app on destination if needed
xcodebuild test -workspace <path> -scheme <name>
Test action
xcodebuild
Builds sources
Installs app on destination if needed Runs tests
xcodebuild test -workspace <path> -scheme <name>
Test action
xcodebuild
Builds sources
Installs app on destination if needed Runs tests
Reports results in console
xcodebuild test -workspace <path> -scheme <name>
Customizing tests
Test Options
NEWxcodebuild test -workspace <path> -scheme <name>
-destination <specifier>
-only-testing:TestBundleA/TestSuiteA/TestCaseA -only-testing:TestBundleB/TestSuiteB
Customizing tests
Test Options
NEWxcodebuild test -workspace <path> -scheme <name>
-destination <specifier>
-only-testing:TestBundleA/TestSuiteA/TestCaseA -only-testing:TestBundleB/TestSuiteB
-only-testing:TestBundleC
xcodebuild test -scheme <name>
Separating building from testing
Additional Test Actions
NEWSeparating building from testing
Additional Test Actions
NEWOnly building
Building for Testing
NEWxcodebuild build-for-testing -workspace <path> -scheme <name>
Builds sources for testing
Only building
Building for Testing
NEWxcodebuild build-for-testing -workspace <path> -scheme <name>
Builds sources for testing
Outputs products in Derived Data
Only building
Building for Testing
NEWxcodebuild build-for-testing -workspace <path> -scheme <name>
Builds sources for testing
Outputs products in Derived Data Generates an xctestrun file
Only building
Building for Testing
NEWxcodebuild build-for-testing -workspace <path> -scheme <name>
Only testing
Test Without Building
NEWxcodebuild test-without-building -workspace <path> -scheme <name>
Only testing
Test Without Building
Finds binary products in Derived Data
NEW
xcodebuild test-without-building -workspace <path> -scheme <name>
Only testing
Test Without Building
Finds binary products in Derived Data Installs if necessary
NEW
xcodebuild test-without-building -workspace <path> -scheme <name>
Only testing
Test Without Building
Finds binary products in Derived Data Installs if necessary
Runs tests and report results as before
NEW
xcodebuild test-without-building -workspace <path> -scheme <name>
Only testing
Test Without Building
NEWxcodebuild test-without-building -xctestrun <path>
Only testing
Test Without Building
Ingests the xctestrun file
NEW
xcodebuild test-without-building -xctestrun <path>
Only testing
Test Without Building
Ingests the xctestrun file
Finds binary products relative to xctestrun file
NEW
xcodebuild test-without-building -xctestrun <path>
Only testing
Test Without Building
Ingests the xctestrun file
Finds binary products relative to xctestrun file Runs tests, reports results as before
NEW
xcodebuild test-without-building -xctestrun <path>
Distributed testing
xcodebuild
Build Machine Test Machine #2
Distributed testing
xcodebuild
Build Machine Test Machine #2
Distributed testing
xcodebuild
Build Machine Test Machine #2
Test Machine #1
Distributed testing
xcodebuild
Build Machine Test Machine #2
Test Machine #1
xcodebuild test-without-building
Distributed testing
xcodebuild
Build Machine Test Machine #2
Test Machine #1
xcodebuild test-without-building
xcodebuild test-without-building
Distributed testing
xcodebuild
Build Machine Test Machine #2
Test Machine #1
Test manifest
Test manifest
Test manifest
xctestrun
Tests to run or skip
Test manifest
xctestrun
Tests to run or skip
Environment variables
Test manifest
xctestrun
Tests to run or skip
Environment variables
Command-line arguments
Test manifest
xctestrun
Tests to run or skip
Environment variables
Command-line arguments
Documentation in man pages
Test manifest
xctestrun
Tests to run or skip
Environment variables
Command-line arguments
Documentation in man pages
man xcodebuild.xctestrun
Summary
Testing Concepts Xcode
• Crash Log Gathering Xcode Server
• Advanced Triggers
• Issue Tracking and Blame
• Configurable Integration User xcodebuild