例えばこんなUITestコードがある場合、若干見にくいかと思います
import XCTest
import EarlGrey
@testable import QiitaPresents
class QiitaPresentsTests: XCTest {
func testButton() {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_selected())
var success: Bool = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Hoge"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "Hogeに変わらなかった、、、、")
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_not(grey_selected()))
success = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "Fugaに変わらなかった、、、、")
}
}
こんな時はEarlGreyとQuickを併用して使うようにしましょう。
Quickのdescribe/context/itを使おう!
先ずは、describe/context/itを使いましょう。
そうするとかなり可読性が上がると思います
各Quickメソッドの引数(String型)は以下のように書きます。
describe
: どんなテストか
context
: どんな条件のテストをするのか
it
: 期待する動作は何か
import EarlGrey
import Quick
@testable import QiitaPresents
class QiitaPresentsTests: QuickSpec {
override func spec() {
describe("画面テスト") {
context("メイン画面上") {
it("Hogeが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_selected())
let success: Bool = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Hoge"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
it("Fugaが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_not(grey_selected()))
let success = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
}
}
}
}
beforeEach
/afterEach
を使ってテストの前後で確認したい事を書こう!
Quickには各it
テストの始まりの前と終わりの後に処理を挟むことができます。
beforeEach
: it
テストの前に処理を行う
afterEach
: it
テストの後に処理を行う
import EarlGrey
import Quick
@testable import QiitaPresents
class QiitaPresentsTests: QuickSpec {
override func spec() {
describe("画面テスト") {
beforeEach {
/// ラベルが表示されているか確認
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_sufficientlyVisible())
}
afterEach {
/// ラベルが表示されているか確認
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_sufficientlyVisible())
}
context("メイン画面") {
it("Hogeが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_selected())
let success: Bool = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Hoge"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
it("Fugaが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_not(grey_selected()))
let success = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
}
}
}
}
今回は、grey_sufficientlyVisible()
を使っていますが(アホみたいな例です。すいません)、お好きな処理を記述してください。
beforeSuite
/afterSuite
を使ってテストの最初と最後に確認を行う。
beforeEach
/afterEach
とはまた別に、テストの最初と最後に処理を挟むことができます。
beforeSuite
: テストを行う前に処理を行う
afterSuite
: テスト行った後に処理を行う
import EarlGrey
import Quick
@testable import QiitaPresents
class QiitaPresentsTests: QuickSpec {
override func spec() {
describe("画面テスト") {
beforeSuite {
/// テスト前は"Fuga"か
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"))
}
afterSuite {
/// テスト後は"Fuga"か
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"))
}
beforeEach {
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_sufficientlyVisible())
}
afterEach {
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_sufficientlyVisible())
}
context("メイン画面") {
it("Hogeが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_selected())
let success: Bool = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Hoge"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
it("Fugaが表示されるか") {
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).perform(grey_tap())
EarlGrey.select(elementWithMatcher: grey_kindOfClass(UIButton.self)).assert(grey_not(grey_selected()))
let success = GREYCondition(name: "値が変わるまで5秒間待つ") { () -> Bool in
var error: NSError?
EarlGrey.select(elementWithMatcher: grey_accessibilityID("resultLabel")).assert(grey_text("Fuga"), error: &error)
return error == nil
}.wait(withTimeout: 5)
GREYAssertTrue(success, reason: "値が変わらなかった、、、、")
}
}
}
}
}
これを使えばUITest前にAPIを叩いて、画面の準備を行うことができるかと思います。
お願い
間違い箇所などがある場合は、指摘していただけると嬉しいです
最後に
いかがでしたでしょうか。
Quickはテストをするタイミングをコントールできるので、EarlGreyと併用すると楽にテストコードが書けるかと思います。
よかったら試してみてください。
※一応、クソースコドを載せておきます。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var resultLabel: UILabel!
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
resultLabel.accessibilityIdentifier = "resultLabel"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func didPushButtoon(_ sender: Any) {
button.isSelected = !button.isSelected
resultLabel.text = button.isSelected ? "Hoge" : "Fuga"
}
}
おまけ
もし、afterSuite
/beforeSuite
が使えなかった場合は以下のメソッドを変わりに書きましょう。
class QiitaPresentsTests: QuickSpec {
/// テストの前に処理を行う
class func setUp() {
/// 処理
}
/// テストの後に処理を行う
class func tearDown() {
/// 処理
}
}
代わりに使えるかと思います。