[automation]try Katalon

https://www.katalon.com/

これを少し触ってみた。

感想としては、これは

https://docs.katalon.com/display/KD/Installation+and+Setup

以下の結果を参考にすると良さそう。

このツールの目的は、Selenium/Appiumを使ったテストを記述/管理する労力を減らそうというものぽい。特に、コードを自分で書かなくて良い状態で。
なので、以下の比較を見るとわかるのだけれど、例えば専属の自動化エンジニアを抱えるところとか、そういうところはターゲットではないように見える。

https://www.katalon.com/blog/comparison-automated-testing-tools/

Emerging solution with a small community.
Feature set is still evolving.
Lack of choices for scripting languages: only Java/Groovy is supported.

[iOS]Bluepill1.0.0

Bluepillの1.0.0がリリースされていたのでメモ。

XCUITestサポートが少し前に完了し、1.0.0になったようですね。

https://github.com/plu/pxctest/releases

こちらに比べて、さすがに企業としての投資が違うのか、開発がBluepillの方が活発だ…

[iOS]run tests on simulators vol2

[iOS]Run multi simulators with FBSimulatorControl
にも書いている、iOSシミュレータを1つのマシンで複数動作させるやつ。最近ではLinkedInからOSSが公開されましたね。Blogはこちら。スターも多く、さすがLinkedInという感じ。

社内で FBSimulatorControl ベースの複数シミュレータで実行する環境を作ろうと思っていたけれど、もっと素晴らしいものが世に出てきててオォォォという感じ…(私、価値出せてない…)
ここら辺、実装能力が顕著に現れて私は本当にまだまだと思う一方です。。。

以下、以前からある類似のものをピックアップ。

類似

これを実施していると、正直なところ並列実行できないCloud実行環境はイマイチですね。
ローカル環境強し。。。

Architecture for GUI Testing(mobile)

In 2014, I talked about GUI testing architecture.

Recently, someone asks me about the architecture.So, I post the blog about it.

The following flow means the architecture. I think this architecture is common if anyone uses libraries such as Cucmber.

  Scenario     Abstract     Wrapper    Binding     Appium
(*.feature)   (*_steps.rb)  (*.rb)
     |           |            |           |          |
     |---------->|            |           |          |
     |           |----------->|           |          |
     |           |            |---------->|          |
     |           |            |           |--------->|
     |           |            |           |          |
     |           |            |           |<---------|
     |           |            |<----------|          |
     |           |<-----------|           |          |
     |<----------|            |           |          |
     |           |            |           |          |
  • Scenario layer
    • Describe scenarios.
    • This layer depends on “User scenarios”.
  • Abstract layer
    • Implement steps to run scenarios as Ruby code.
    • This layer absorbs the changes in scenarios.
  • Wrapper layer
    • Wrap binding.
    • This layer absorbs the changes in bindings.
  • Binding layer
    • Ruby binding

PageObject pattern is very famous. In this case, scenairo layer and abstract layer depends on pages. BTW, wrapper layer is common methods to help other layers.

[Appium]preventWDAAttachments for XCUITest strategy

Appium1.6.2から、 preventWDAAttachments というパラメータが付与されました。

これは、WebDriverAgentを動作させるときにXcodeのDerivedDataに多くの不要なファイルを書き込むことを抑制するために、そのディレクトリの権限を読み込み専用(555)に変更させるものみたいです。

defaultはtrueのようですね。

https://github.com/appium/appium-xcuitest-driver/blob/0c36c7659373c1c82a1411e50fa2503920909624/lib/desired-caps.js#L45

ただ、これはXcodeの権限設定を一部変更することになるので、capsには明記しておいたほうが良さそう。

[Android]Reactive系のテストではIdlingResourceやっぱり大事

Rx系において、Android向けの物にはRxJavaの他にAgeraがあります。
codelabsにAgeraがきていたので、簡単な学びがてらやってみました。

Rx系のテスト(Espresso使ったUI含む)までも書かれていたので、Rx系学ぶ人には良い材料になると思います。やっぱりRx系のテストコード書こうとしたら、 Espresso.registerIdlingResourcesIdlingResource の実装を使った非同期要素を待つ、ということがかけないといけないよなーということを思いました。

対象

Repositoryに対する処理

AgeraはRepositoryが1つの大事な要素だと書いていました。その中で、複雑なrepositoryを扱う場合は、以下のようになるそう。

https://codelabs.developers.google.com/codelabs/android-agera/#7

topAlbumsRepository = repositoryWithInitialValue(emptyList())
  .observe(accountManager,      // When the account changes...
           networkStatus)       // or when we get online...
  .onUpdatesPer(10000)          // but at most every 10 seconds...
  .goTo(networkExecutor)        // on the network thread...
  .getFrom(albumsFetcher)       // fetch albums from API...
  .thenTransform(                   
    functionFrom(String.class)
    .unpack(jsonUnpacker)       // unpack JSON items...
    .map(jsonToAlbum)           // for each album...
    .filter(fiveStarRating)     // filter the best...
    .thenLimit(5))              // and give us the first five of those!
  .compile();                   // Create the repository!

この中で、例えば値の変化を観測してそのないように変化があればそれをsetTextに反映する、というところは以下のようになる。

https://github.com/KazuCocoa/agera-example-android/commit/ba11829000bf820a2c34861cfb3e5c9b071a0e78

なるほど。

テストの書きやすさや保守も考えて…

このようなAgeraの特徴の他、Rx系はcallback地獄のように入れ子にコードを書けやすいが、その反面そうするとテストしにくかったり保守が困難なコードが出来上がる。そこで、Ageraの例ではそこを対応する方法を紹介している。

https://codelabs.developers.google.com/codelabs/android-agera/#9

他、処理の分散としてメインスレッド外へ処理を逃がすために、 .goTo(mExecutor) を使った処理方法も。

Espressoも使う

最後、UI含んだテストとして、 IdlingResource の実装を使った Espresso.registerIdlingResources を利用した非同期型のこのようなRx系に対するテストコードも書いています。

https://codelabs.developers.google.com/codelabs/android-agera/#11

アニメーションOFFは毎度のご愛嬌ですね 🙂

最後に

Reactive Programmingには幾つか世代があり、Ageraはまだまだ、RxJavaは2.0で世代3~4付近だと言われていました。
https://github.com/google/agera/issues/20#issuecomment-212007539

そうはいっても、Ageraを使ったこの題材は、Androidに対してReactive Programmingを入れてテスト書くまでをざっと学ぶことができるので、やることには良い意味があるものだなーと感じました。

[iOS]XCUITestを少し追って試しにシナリオを書いてみる

XCUITestがXcode7から利用できるようになったので、少し追ってみたので、メモ。

まだ正式に導入するとか、評価したとか、そういう話ではないです。

以下は、Xcode7.0で適当なXCUITestを書いたあと、コード上でメソッドを追った時の情報をもとに引用しています。Online Documentなどでは違うところがあるかも。また、 Swift をベースに追っています。

accessibility systemを使って要素を特定する

/*! Protocol describing the attributes exposed on user interface elements and available during query matching. These attributes represent data exposed to the Accessibility system. */

どうやら、XCUITestはXCTestを拡張し、さらにはAccessibilityの機構を使うみたいです。ひとまず、UIAutomationのために埋め込んだaccessibilityIdentifeirなど、そのまま流用可能のようです。

ということは、すでにUIAutomationを使いシナリオを記述している人は、テストシナリオを記述する粒度は変われど、同一のシナリオを記述することは可能かもしれないです。

例えば、 public protocol XCUIElementAttributes には

public var identifier: String { get }

が定義されています。これは accessibilityIdentifier の要素を指しているらしいので、accessibilityIdentiiferでつけた要素を特定する、ということは従来のUIAutomationと変わらず実施できます。

この要素特定には、

public func elementBoundByIndex(index: UInt) -> XCUIElement

public var allElementsBoundByAccessibilityElement: [XCUIElement] { get }

の2種類が使えそうです。見た感じ。(まだちゃんと使ってはない)

また、accessibilityベースではなく、より実装に依存することになりますが実装対象のUIButtonといったUIKitの要素単位を取得するためのインターフェースとして

public protocol XCUIElementTypeQueryProvider

が宣言されているようです。

ここら辺は、UIAutomationで取得できていた要素を、XCUITestで参照できるようにした、というもののようです。

@available(iOS 9.0, *) のある XCUI*

@available(iOS 9.0, *)

のアノテーションで指定されていうr、 XCUI* 群を使うことで、シナリオの記述などを行っていく模様。XCTestのコードを見ていると、随所で @available(iOS 9.0, *) を持った XCUI* 群を確認できます。

ここら辺では、操作を定義してたりしました。ただ、 @available をいろいろ見ていると、iOS7を対象としたものなんかもいろいろあって、XCUITestは今まで用意してきたUIAutomationだったり、accessibilityの要素をまとめあげた感じがしました。

シナリオを書いてみる

少しシナリオを書いてみました。テスト対象は新規でアプリを作成すると作られる、簡単なタスク追加のデモアプリです。その中で、navigation barのEditをタップして、Addする、というシンプルなものを書いてみました。

import XCTest

class SamplesForXCUITestUITests: XCTestCase {

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        XCUIApplication().launch()
    }

    override func tearDown() {
        super.tearDown()
    }

    func testExample() {
        let app = XCUIApplication()
        let masterNavigationBar = app.navigationBars["Master"]
        masterNavigationBar.buttons["Edit"].tap()
        masterNavigationBar.buttons["Add"].tap()
    }

}

これで、 cmd + u でXCUITestまでテストが実施されます。アニメーションなんかは従来のUIAutomationと同じ感じで、そのままUIAutomationをXCTestの一部として実施している以上の感想を持ちませんでした。

書いてみて思ったこと。

  • XCUITestはUIを見ながらシナリオを考える、というには、いささかテストコードがハードコーティングすぎる
    • まだaccessibitliyを付加して、とか試してないので、それによって印象変わるかも
    • allElementsBoundByAccessibilityElement とかで全要素取得できなかったので、ちょっと全要素取得のコツとか学ばないと、実際に書かれたコードを読む必要性が高い…
    • ひとまずRuby + Appiumのほうが同様のことをするには良い。実行速度も、Simulator上では、さほど差があるわけではない気がします。(Simulator再起動の時間は除く)
  • Espressoみたい
    • 特定のViewを直接描画する、とかできるのかな…
    • シナリオというか、操作の書き方も…
  • 操作のRecordは気軽にできてよいけれど、こういうシナリオの記述に知見がない人だとすぐにスパゲッティ作りそう
    • 開発経験を多少持っていると問題ないかな…

感想

Xcodeで accessibility* による補完を見てみると、 UIKit &gt; UIAccessibility の要素も参照していました。ここ、コードを読んでみるとiOS7とか、もっと古くからでも参照できるaccessibilityの要素にたどることができます。今までPrivate APIとして使われていた、FBが出している WebDriverAgent なんかでアクセスしているAPIを整理して、ちゃんとXCUITestのフレームワークとしてアクセスできるようにした、というのが正体なのかもしれませんね。

確かに、UIAutomationの欠点はUI操作をJavaScriptで書かないといけないという、iOS開発者にとってはなかなか酷なものでした。そこをそのままSwiftやObjective-Cで利用出来るように公式でおこなう、というだけでも、有益かもしれません。

KIFは完全にこっちに移りそうな予感がします。FBのWebDriverがこのXCUITestを経由することができるようになれば、AppiumなんかでもXCUITestの恩恵を受けられそう。

いずれにせよ、今までRuby + Appium + Android/iOSとテストを記述していたのですが、”Ruby + Appium + Android” and “XCUITest + iOS” というふうに、iOSにおいては、Ruby(などのほか言語) + Appium を経由してiOSアプリをGUI Testingするといった使い方は制限されそうな予感。次のXcode8とか、そのくらいのタイミングでUIAutomationは除かれる可能性を考えて動いたほうがよさそう。

んー。複数OSのアプリ対応を少人数で動かないといけないとき、UIAutomationが制限される未来に進む場合、iOSは制約厳しいな…