Xcode testing Using XCTest. Testing in XCode Done using XCTest class Test classes are created...
-
Upload
marybeth-fisher -
Category
Documents
-
view
240 -
download
6
Transcript of Xcode testing Using XCTest. Testing in XCode Done using XCTest class Test classes are created...
Xcode testingUsing XCTest
Testing in XCode
Done using XCTest class
Test classes are created separately from code
Test classes can access and call classes in your app
Test classes have assertion functions that you can call to test results
You can define how fine-grain your tests are.
Test Navigator
Create a new single-view project.
Click on the test navigator button in the left panel
You’ll see two templates for testing
Test NavigatorThe Run button ( ) appears to the right of the item name when you hold
the pointer over any item in the list.
This is a quick way to run all the tests in a bundle, all the tests in the class,
or any individual test.
Tests return pass or fail results to Xcode.
As tests are being executed, these indicators update to show you the
results, a green checkmark for pass or a red x for fail.
In the test navigator shown here, two of the tests have asserted a failure.
Test NavigatorClicking any test class or test method in the list opens the test class in the
source editor.
Test failures display the result string at the associated assertions in the
source editor.
TestingIn the test navigator in the single-view application that you created earlier, click on the class testExample()
In the editor, you’ll see the code:
import UIKitimport XCTest
class testingInSwiftTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() }
Continued on next slide…
Testing func testExample() { // This is an example of a functional test case. XCTAssert(true, "Pass") } func testPerformanceExample() { // This is an example of a performance test case. self.measureBlock() { // Put the code you want to measure the time of here. } } }
Click on the run button that appears next to testExample() when you put your mouse over it.
This is an assertion that always passes
The green check means test was passed
Test OrganizationThe setUp method gets called before each test runs.
If you have initialization code you call before running each test, place the code in the setUp method so you don’t have to repeat the code in each test.
The tearDown method gets called after each test runs. If you run any cleanup code after running each test, place that code in the tearDown method so you don’t have to repeat the code in each test.
The testExample method provides an example of a test method.
The testPerformanceExample method provides an example of a performance test case, which measures how long a task takes to complete.
Test Methods
A Swift test method has the following conditions:
It must begin with the word test.
It takes no arguments.
It returns no value.
You can create as many test methods in a class as you like.
Every test method must have an assertion which determines whether or not the test is passed.
Assertions
XCTest assertions start with XCTAssert. If you start typing XCTAssert, Xcode’s code completion should show you a list of all the available assertions
The following are the most widely-used assertions:XCTAssertNotNil asserts a variable is not nil.
XCTAssertTrue asserts a condition is true.
XCTAssertFalse asserts a condition is false.
XCTAssertEqual asserts two values are equal.
XCTAssertEqualObjects asserts two objects are equal.
XCTAssertEqualWithAccuracy asserts two floating-point values are equal.
AssertionsXCTest assertions take two or more arguments.
The first arguments depend on the assertion. XCTAssertTrue and XCTAssertFalse take a condition as the first argument.
The XCTAssertEqual assertions take two arguments at the start: the two items you’re checking are equal.
After the assertion testing arguments comes the error message, which is a string.
Xcode displays the error message if the assertion fails.
If you want to show the value of a variable in the error message, place the variable name in parentheses in the error message, prefixed by a backslash character.
\(variableName)
The following code shows an example of an assertion involving a variable named length:
XCTAssertTrue(length == 12, “The length should have been 12. Actual length: \(length)")
Testing
Add the following method to the testExample() class.
Run the testExample()
func testMultiplyingTwoNegativeNumbersYieldsAPositiveValue() { let x = –6 let y = –4 let product = x * y XCTAssertTrue(product > 0, "Multiplying two negative numbers should yield a positive number. Product: \(product)") }
This test does not test the code in the app but only serves to demonstrate how assertions work
Testing II
Create the following view in your app
Add and connect the following IBOutlets:
@IBOutlet weak var addButton: UIButton! @IBOutlet weak var resultText: UITextField! @IBOutlet weak var secondText: UITextField! @IBOutlet weak var firstText: UITextField!
Testing IIAdd the following code to the viewController
@IBAction func addButtonPressed(sender: UIButton) { // toInt returns optional that's why we used a:Int? let a:Int? = firstText.text.toInt() // firstText is UITextField let b:Int? = secondText.text.toInt() // secondText is UITextField // check a and b before unwrapping using ! if a != nil && b != nil { var ans = a! + b! resultText.text = "\(ans)“ } else { resultText.text = "Input values are not numeric" } }
connect the button in the storyboard to this IBAction method
Testing II
Go to the Project Navigator and click on the file ViewController.swift
Then click on the File Inspector on the rightmost panel and add the ViewController to the test target
Do the same with the AppDelegate.swift file
This enables methods in the test file to see variables in the viewController
Testing II
Go to your test class
At the top add the line
import testingInSwift
Where testingInSwift is the name of your project.
Testing IIFirst determine whether the root view loads:
func testViewDidLoad()
{
// we only have access to this if we import our project above
// Viewcontroller is the name of the root view controller class in your app
let v = ViewController()
// assert that the ViewController.view is not nil
XCTAssertNotNil(v.view, "View Did Not load")
}
}
Testing III
It’s easy to test your models.
It’s tricky to test your storyboard.
First stepsGo to the project navigator on the left (where the classes in your project are listed).
Click on your project name
Go to the Build Settings tab
Go to the Packaging section
Change Defines Module to “YES”
Note the Product Module Name several lines below this; this name is what you’ll need to import into your test class
Testing III
Go to your test class and import the product module name:
import testingInSwift
class testingInSwiftTests: XCTestCase {
Add this line but substitute your product module name
Testing III
Manual Lifecycle eventswhen your app runs, lifecycle events are generated automatically (viewWillAppear, viewDidLoad, etc.)
in tests, you will need to generate these in code
Testing III
First, need to give your storyboard a name.In the project navigator, go to the Main.storyboard (this app only has one storyboard; some apps have more)
In the storyboard navigator, click on the view controller
Then open the identity inspector in the right side panel
Give the storyboard an identifier
Testing III
Now we can write a test method to test our interface.
go to your test class and add the following method (can be anywhere in the class):
func testAddMethod() {
let SB = UIStoryboard(name: "Main", bundle: nil)
myVC = SB.instantiateViewControllerWithIdentifier("testStoryboard") as ViewController
let _ = myVC.view
// more code goes here
}
We’ll examine each of these lines on the next slide
Testing III
func testAddMethod() {
let SB = UIStoryboard(name: "Main", bundle: nil)
myVC = SB.instantiateViewControllerWithIdentifier("testStoryboard") as ViewController
let _ = myVC.view
// more code goes here
}
First we create an instance of the storyboard
Then we instantiate the viewcontroller for this storyboard (note the “as ViewController). The variable myVC now points to the viewcontroller.
The IBOutlets are only created when the view loads, so we create a blank variable that contains the view, thus forcing the view to load.
Testing III
We can now populate the fields and click the button.
Add this code after the “more code goes here “ comment on the previous slide:
let sumText = “–10“ // this is the expected answer
myVC.firstText!.text = “–6" // Now set values in the textfields
myVC.secondText!.text = “–4"
Testing III
Now click the button
myVC.addButton!.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
and then test the answer
XCTAssertEqual(sumText, myVC.resultText!.text, "Adding two numbers should yield \(sum)")
}We’re getting the answer out of the result textfield
Now you can run the test!
This is the string containing the expected answer
This is the IBOutlet to the button
Implementing the test plan
Every test in the plan should have a method that implements that test