Xcode Testを使おう
まずはプロジェクトを作成します
「Include Tests」のチェックボックスを入れておきます
テストの下準備として、「PlayData.swift」というSwiftファイルを作成します
import Foundation
class PlayData {
var allWords = [String]()
}
PlayData.swiftの置き場所は本番プロジェクトフォルダの中です
次は「プロジェクト名Tests.swift」というファイルを開きます
(このプロジェクトの名前はUnitTestingなので、UnitTestingTests.swiftというファイルになります)
サンプルテストのtestExample()
とtestPerformanceExample()
を削除します
import XCTest
@testable import UnitTesting
class UnitTestingTests: XCTestCase {
override func setUpWithError() throws {
}
override func tearDownWithError() throws {
}
}
そして、オリジナルのテストを加えます
このメソッドは、playData.allWords
は空き配列ではないかを検証します
現在は空き配列なので、検証は通過できると予想されます
(もし、空き配列ではない場合、検証は失敗になり、「allWords must be 0」というメッセージが出ます)
class UnitTestingTests: XCTestCase {
// ... 省略
func testAllWordsLoaded() {
let playData = PlayData()
XCTAssertEqual(playData.allWords.count, 0, "allWords must be 0")
}
}
テストメソッドを書くときの注意点は
- テストメソッドの名前は「
test〜
」です、test
というPrefixをつけることが必要です - メソッドは、引数を指定してはいけない、ノー引数は必須です
- メソッドは、返り値をするのがいけない、返り値なしのが必須です
以上の3つを守ったら、テストメソッドは正確に識別でき、コードの左に灰色の菱形アイコンが出ます
XCTAssertEqual()
の他には、XCTAssertGreaterThan()
やXCTAssertNotNil()
などが使えます
そして、テストを行います
class UnitTestingTests
の左の菱形のアイコンをクリックします
テストは通過できます、菱形のアイコンが緑になりました
Performance Test
Performance Testは、10回コードを運行して、そして平均値の所要時間を表示します
UnitTestingTests.swiftに以下のコードを追加します
class UnitTestingTests: XCTestCase {
...
+ func testWordsLoadQuickly() {
+ measure {
+ _ = PlayData()
+ }
+ }
}
func testWordsLoadQuickly()の左の菱形アイコンをクリック、テストを起動します
このように、平均時間は0.212secとなっております
緑の菱形アイコンの下のアイコンをクリックしたら
Performance Testの10回の詳細を見ることができます
Baselineを設定
Baselineは、今回のテストの結果を基準として設定
そして、以後のテストのかかる時間が良くなるか、悪くなるかをチェックすることができます
緑の菱形アイコンの下のアイコンをクリック、「Set Baseline」をクリックします
そして、もう一度緑の菱形アイコンをクリック、
もう一度テストを起動します
テスト完了後、所要時間の右には2% betterというテキストが出ました
さらに、前回はBaseline設定したので、今回の緑の菱形アイコンは
「所要時間はBaselineの±10%以内」ということを示しております
UI Test
Data Modelのテストと違い、UIが正常に作動しているかを確認するためにUIテストを書きましょう
「プロジェクト名UITests.swift」というファイルを開きます
testExample()
とtestLaunchPerformance()
削除しておきます
続いて、自分のUIテストを書きます
テーブルが7つ表示しているかのテストです
class UnitTestingUITests: XCTestCase {
...
+ func testInitialStateIsCorrect() {
+ let app = XCUIApplication()
+ app.launch()
+ let table = XCUIApplication().tables
+ XCTAssertEqual(table.cells.count, 7, "There should be 7 rows initially")
+ }
}
レコードしてUI Testコードを生成
上のようにUI Testのコードを書くのは一つの方法で、
そこでもう一つの手段としてのレコードでUI Testコードを生成させる方法を紹介します
まずはUnitTestingUITests.swiftに空きテストメソッドを書きます
class UnitTestingUITests: XCTestCase {
...
+ func testUserFilteringByString() {
+ // マウスはここにクリックしておく
+ }
}
そして、マウスはコメントの部分にクリックしておきます
次は、画面の下の赤いアイコンをクリックします
シミュレーターが起動され、操作を行います
操作を終えて、Xcodeに戻りまたアイコンをクリックします
これでレコードを終了させます
testUserFilteringByString()
の中にコードが生成されることが確認できます
func testUserFilteringByString() {
let app = XCUIApplication()
app.navigationBars["Unit Testing"].buttons["Search"].tap()
let tKey = app/*@START_MENU_TOKEN@*/.keys["t"]/*[[".keyboards.keys[\"t\"]",".keys[\"t\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/
tKey.tap()
tKey.tap()
let eKey = app/*@START_MENU_TOKEN@*/.keys["e"]/*[[".keyboards.keys[\"e\"]",".keys[\"e\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/
eKey.tap()
eKey.tap()
let sKey = app/*@START_MENU_TOKEN@*/.keys["s"]/*[[".keyboards.keys[\"s\"]",".keys[\"s\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/
sKey.tap()
sKey.tap()
tKey.tap()
tKey.tap()
app.alerts["Filter..."].scrollViews.otherElements.buttons["Filter"].tap()
}
生成されたコードなので色々改善できる部分があります
こちらは改善されたバージョンです
func testUserFilteringByString() {
let app = XCUIApplication()
app.buttons["Search"].tap()
let filterAlert = app.alerts
let textField = filterAlert.textFields.element
textField.typeText("test")
filterAlert.buttons["Filter"].tap()
}
最後に、自らAssertコードを入れます
「Test」という単語でフィルターしたら、テーブルの行数は56になるはずなのでこう書きます
func testUserFilteringByString() {
let app = XCUIApplication()
app.buttons["Search"].tap()
let filterAlert = app.alerts
let textField = filterAlert.textFields.element
textField.typeText("test")
filterAlert.buttons["Filter"].tap()
+ XCTAssertEqual(app.tables.cells.count, 56, "There should be 56 words matching 'test'")
}
Discussion