[iOS][EarlGrey]Run tests quickly

Small, small tips to enhance conducting speed for EarlGrey.
In many cases, iOS can’t handle animation speed such as Android even UI Test cases.

EarlGrey available changing animation speed except for UIScrollView. here

// Swift
let kMaxAnimationInterval: CFTimeInterval = 5.0
GREYConfiguration.sharedInstance().setValue(kMaxAnimationInterval, forConfigKey: kGREYConfigKeyCALayerMaxAnimationDuration)

// Swift
GREYTestHelper.enableFastAnimation()

https://github.com/google/EarlGrey/blob/master/docs/faq.md

In XCUITest case:

# swift
UIApplication.sharedApplication.keyWindow.layer.speed = 100

[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.

Allure2が開発途中だった

Test reporterの生成で有名どころと言えばAllureがありますね。Yandexのメンバが開発しているやつです。

最近、そのv2が開発されていることを知りました。

https://github.com/allure-framework/allure2

Gradleを使っていたので、早速Forkして使ってみることに。
人が増えて、テスト結果を複数人で見る必要が出てきた時に、こういう結果レポートから情報をざっと見ることができるツールはとても重宝しますね。

受託系の人たちはこういうことを欲する一方、Web系の人はそうでもない人も多いように見えます。
ただ、実施時間など含めて色々とまとめて情報をみたい場合、このようなUIを持ったツールは役に立つものです。

[iOS]Run multi simulators with FBSimulatorControl

複数のシミュレータを1つの端末/OS上で起動可能な FBSimulatorControl はご存知の方も多いかもしれません。
それを使った時のメモ。最後の方に、XCTestを実行する時のものも。

installはリポジトリを参考に。
(以下は 0.2.0 のバージョン)

  • listを表示
$ fbsimctl list
05AB6F68-813D-4C6C-A95E-F77CC00D2DDA | Apple TV 1080p | Shutdown | Apple TV 1080p | tvOS 10.0
A1C5C8BF-DB4E-4649-B29E-E8B2FB9351B9 | iPad Retina | Shutdown | iPad Retina | iOS 10.0
1E4AE723-317F-4598-9CB8-0C92825FDC41 | iPad Pro (9.7 inch) | Shutdown | iPad Pro (9.7-inch) | iOS 10.0
F3DEEDB4-3CC0-46F3-90EB-E01C8955D1CD | iPad Pro (12.9 inch) | Shutdown | iPad Pro (12.9-inch) | iOS 10.0
A7EEA0FE-36B3-40A3-AE67-41E3324B4B7E | iPad Air 2 | Shutdown | iPad Air 2 | iOS 10.0
98A63C99-B352-4039-8D3D-3F3393387BC0 | iPad Air | Shutdown | iPad Air | iOS 10.0
56CEEBD7-DF37-4E17-AD7C-B42BD4A2C6E5 | iPhone SE | Shutdown | iPhone SE | iOS 10.0
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Shutdown | iPhone 7 Plus | iOS 10.0
B5A0DFCE-C33A-4362-9109-EA19530FC7BF | iPhone 7 | Shutdown | iPhone 7 | iOS 10.0
E3B28E7A-E7DB-469F-B41C-1244C7718A1C | iPhone 6s Plus | Shutdown | iPhone 6s Plus | iOS 10.0
6D533AC6-94AF-4EC1-BA69-9EF73E6C9A38 | iPhone 6s | Shutdown | iPhone 6s | iOS 10.0
ED558E83-9DFE-4027-8108-6173EE518F9F | iPhone 6 Plus | Shutdown | iPhone 6 Plus | iOS 10.0
C523040C-CDCF-42FD-864C-26DE36A2424F | iPhone 6 | Shutdown | iPhone 6 | iOS 10.0
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Shutdown | iPhone 5s | iOS 10.0
EA829C44-9313-45A4-9770-A0B8BD15967C | iPhone 5 | Shutdown | iPhone 5 | iOS 10.0
E27018D9-5783-4A85-8112-0B85EF2C9AD5 | Apple Watch Series 2 - 42mm | Shutdown | Apple Watch Series 2 - 42mm | watchOS 3.0
EB98AC75-E4F4-4B66-B57F-0B8CE18A6221 | Apple Watch Series 2 - 38mm | Shutdown | Apple Watch Series 2 - 38mm | watchOS 3.0
2405DF4B-31BC-4E50-98EA-B9DBC00A8B5D | Apple Watch - 42mm | Shutdown | Apple Watch - 42mm | watchOS 3.0
91B32C5D-DBD4-4477-BF18-94747EC77C65 | Apple Watch - 38mm | Shutdown | Apple Watch - 38mm | watchOS 3.0
  • 2つの端末を同時起動
$ fbsimctl 12995D09-DC3F-4921-8CF4-4931A59A40D0 0180EE6C-4749-4127-A983-B190856C3D29 boot
Container Application Did Launch => Process Simulator | PID 28616
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Shutdown | iPhone 7 Plus | iOS 10.0: launch: Process Simulator | PID 28616
Did Change State => Booting
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Booting | iPhone 7 Plus | iOS 10.0: state: Booting
Simulator Did launch => Process launchd_sim | PID 28618
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Booted | iPhone 7 Plus | iOS 10.0: launch: Process launchd_sim | PID 28618
Did Change State => Booted
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Booted | iPhone 7 Plus | iOS 10.0: state: Booted
Connection Did Connect => Bridge: Framebuffer ((null)) | HID (null) | (null)
0180EE6C-4749-4127-A983-B190856C3D29 | iPhone 7 Plus | Booted | iPhone 7 Plus | iOS 10.0: launch: Bridge: Framebuffer ((null)) | HID (null) | (null)
Container Application Did Launch => Process Simulator | PID 28647
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Shutdown | iPhone 5s | iOS 10.0: launch: Process Simulator | PID 28647
Did Change State => Booting
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Booting | iPhone 5s | iOS 10.0: state: Booting
Simulator Did launch => Process launchd_sim | PID 28649
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Booted | iPhone 5s | iOS 10.0: launch: Process launchd_sim | PID 28649
Did Change State => Booted
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Booted | iPhone 5s | iOS 10.0: state: Booted
Connection Did Connect => Bridge: Framebuffer ((null)) | HID (null) | (null)
12995D09-DC3F-4921-8CF4-4931A59A40D0 | iPhone 5s | Booted | iPhone 5s | iOS 10.0: launch: Bridge: Framebuffer ((null)) | HID (null) | (null)
Scale (null) | No Locale Override | Options [] | No Framebuffer
Scale (null) | No Locale Override | Options [] | No Framebuffer
  • help
$ fbsimctl help
[fbsimctl] Help
===============

    fbsimctl {{ [output] | [management] | --set <directory> }}* [targets]? [target-format]* {{ [action] ... -- [action] }}+
OR  fbsimctl [output]* help

fbsimclt is a Mac OS X library for managing and manipulating iOS Simulators

    --set


[action] Action
===============

    [approve]
OR  [boot]
OR  [clear_keychain]
OR  config
OR  [create]
OR  delete
OR  [diagnose]
OR  erase
OR  install <string>
OR  [launch(agent)]
OR  [launch(app)]
OR  [launch_xctest]
OR  [listen]
OR  list
OR  list_apps
OR  list_device_sets
OR  open <url>
OR  record {{ start | stop }}
OR  [relaunch]
OR  shutdown
OR  tap <double> <double>
OR  terminate {{ <application> | <bundle-id> }}
OR  uninstall {{ <application> | <bundle-id> }}
OR  upload <file>+
OR  [watchdog_override]
OR  set_location <double> <double>


[approve] Action: Approve
=========================

    approve {{ <application> | <bundle-id> }}+


[boot] Action: Boot
===================

    boot {{ --connect-bridge | --direct-launch | --use-nsworkspace | --scale=25 | --scale=50 | --scale=75 | --scale=100 | --locale <locale> }}*

    --connect-bridge
    --direct-launch
    --locale
    --scale=100
    --scale=25
    --scale=50
    --scale=75
    --use-nsworkspace


[clear_keychain] Action: Clear Keychain
=======================================

    clear_keychain {{ <application> | <bundle-id> }}?


[create] Action: Create
=======================

    create {{ --all-missing-defaults | {{ <device-name> | <os-version> | --aux <directory> }}* }}

    --all-missing-defaults
    --aux


[diagnose] Action: Diagnose
===========================

    diagnose {{ --current-format | --path | --content }} [diagnose/query]

    --content
    --current-format
    --path


[diagnose/query] Diagnose: Query
================================

    {{ <application> | <bundle-id> }} <string>+
OR  {{ --name <string> }}+
OR  --crashes-since <date> {{ --application | --system | --custom-agent }}*

    --application
    --crashes-since
    --custom-agent
    --name
    --system


[launch(agent)] Action: Launch (Agent)
======================================

    launch {{ --stdout | --stderr }}* <binary> <string>* --?

    --stderr
    --stdout


[launch(app)] Action: Launch (App)
==================================

    launch {{ --stdout | --stderr }}* {{ <application> | <bundle-id> }} <string>* --?

    --stderr
    --stdout


[launch_xctest] Action: Launch XCTest
=====================================

    launch_xctest {{ --test-timeout <double> }}? <directory> {{ --stdout | --stderr }}* {{ <application> | <bundle-id> }} <string>* --?

    --stderr
    --stdout
    --test-timeout


[listen] Action: Listen
=======================

    listen {{ --socket <port> | --http <port> }}

    --http
    --socket


[management] Simulator Management
=================================

    --delete-all | --kill-all | --kill-spurious | --ignore-spurious-kill-fail | --kill-spurious-services | --timeout-resiliance

    --delete-all
    --ignore-spurious-kill-fail
    --kill-all
    --kill-spurious
    --kill-spurious-services
    --timeout-resiliance


[output] Output Options
=======================

    --debug-logging | --json | --pretty

    --debug-logging
    --json
    --pretty


[relaunch] Action: Relaunch
===========================

    relaunch {{ --stdout | --stderr }}* {{ <application> | <bundle-id> }} <string>* --?

    --stderr
    --stdout


[target-format] Target Format
=============================

    --udid | --name | --device-name | --os | --state | --pid | --container_pid


[targets] Targets
=================

    all | [targets/query]+


[targets/query] Target: Queries
===============================

    --first <int> | <udid> | --state=creating | --state=shutdown | --state=booting | --state=booted | --state=shutting-down | --simulators | --devices | <os-version> | <device-name>

    --devices
    --first
    --simulators
    --state=booted
    --state=booting
    --state=creating
    --state=shutdown
    --state=shutting-down


[watchdog_override] Action: Watchdog Override
=============================================

    watchdog_override <double> {{ <application> | <bundle-id> }}+


Primitives:

    <application>             Path to an application.
    <binary>                  Path to a binary.
    <bundle-id>               Bundle ID.
    <date>                    Time since UNIX epoch (seconds)
    <device-name>             Device Name.
    <directory>               Path to a directory.
    <double>                  Double-precision floating point number.
    <file>                    Path to a file.
    <int>                     Signed integer.
    <locale>                  Locale identifier.
    <os-version>              OS Version.
    <port>                    Port number (16-bit unsigned integer).
    <string>                  String without spaces.
    <udid>                    Device or simulator Unique Device Identifier.
    <url>                     URL.

以下のPR/議論で、結果の出力フォーマットとしてJUnitなんかを選択できるようになったようです。

また、以下の通り .xctest を対象にすると、XCTestを実行可能なようです。

fbsimctl --state=booted \
launch_xctest /path/to/WebDriverAgentRunner.xctest com.apple.mobilesafari --port 8100 -- \
listen

という形でテストを実行できる模様。
.xctest はAWS Device Farmとかでも使えるコレですね。

http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-ios-xctest.html

reading “Advanced Software Testing – Vol. 3”

ISTQBのTTA(Technical Test Analyst)がどのようなことを学んでいるのか、を知るために読んでみました。

Advanced Software Testing – Vol. 3, 2nd Edition: Guide to the ISTQB Advanced Certification as an Advanced Technical Test Analyst

ざっというと、様々なソフトウェアに関するメトリスクやその計測方法、カバレッジの話、さらにはテスト自動化に関する話までありました。

内容として、これはゆるSoftware Engineer in Testと呼ばれるような位置の人は頭に入れておくべき事柄、という感じでしょうか。

data driven や keyword driven なテストコードの話とか、静的/動的テストの分け方やその詳細への落とし込み、様々なコードカバレッジの定義やその役割など。

中でも、コードカバレッジをはじめとした様々なカバレッジ(それこそ、変更量とか含む)の厚みはすごくページを割いていて、その計算(アルゴリズム)の理解までこの書籍でできる感じです。

ただ、これだけできても十分ではなく、ここと実際の経験(開発など)が合わさって相乗効果を発揮する、という感じでしょうか。

効率性のテストの中で、以下のように数多くの xx testingという呼び名があったことは今回初めて気付きました…

  • Load Testing
  • Stress Testing
  • Scalability Testing
  • Resource utilization Testing
  • Endurance or soak Testing
  • Spike Testing
  • Reliability Testing
  • Background Testing
  • Tip-over Testing

とてか04で多くのものを拾ってきた

とてか04とは

『とちぎテストの会議04』が正式名称。

toRubyを主催している方々が、主に”テスト”に関わる何かを主において開くイベントです。
その中で、今回は以下の通り「つくるいとなむ」を主なタイトルとして開かれました。

http://d.hatena.ne.jp/tochigitestnokaigi/20160423

私は以下のようにLTの1番目として発表いたしました。

これ自体は私の普段の学び方だったり、その中で特に業務に活かすために特に疑問に感じていたことをお話し致しました。

「チョットデキル人に訊け!」ででた”テストをうまくなるには?”

こちら、何が自分、ひいては周りの向上を誘うか、ですよね。私も考えてみたのですが、やっぱり以下のようにやりたいことベースでいろいろ学ぶなーと感じました。それ以外だと、業務上だったり一時の知的好奇心から、というのはちらほら。

これ以外だと、何か興味を持っていることの周辺でテストに絡めて学ぶ、というのが面白いのでないですかね。

拾ってきたもの

多くの方々とのつながり。

とてか03で初めて足を運んだとてか。そこから1年後の2回目。前回よりもいろいろな人と話をしましたし、つながりもできました。これは私にとってとても良いつながりだと感じます。ありがとうございました。

[Android]delete data stored in AccountManager via adb

As you know, you can remove local application data via adb command.

$ adb shell am clear your.package.name

The command is very useful to do Android test against release module with uiautomator, Appium an so on. But, if your application use AccountManager provided by Android platform, the command can’t remove the data stored via account manager.

What you can do is…

  1. Uninstall the app and install again.
  2. Remove account via application.

To make faster and more stable some Android test, 2 is better choice. Because installing apks take a lot of time.

So, I developed the simple application. Anyone can remove data via adb command if you install the following application into your target device.

https://github.com/KazuCocoa/DroidTestHelper

After installing DroidTEstHelper app in your target device, you only do the following broadcast command. Then data which is stored in Account Manager is remove.

$ adb shell am broadcast -a 'DroidTestHelper' --es ACCOUNT_TYPE your.target.account.type

You should replace your.target.account.type to your target account type.