LoginSignup
0

More than 5 years have passed since last update.

EarlGreyのコードにQuickのコードを付け合わせて可読性を上げる

Posted at

例えばこんな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() {
    /// 処理
  }
}

代わりに使えるかと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0