VOYAGE GROUP エンジニアブログ

voyagegroup_techのブログ
VOYAGE GROUPエンジニアブログです。

tool

iOSの究極テストツール:Calabash-iOSを使いこなすぞ!(2)

前の記事の続きですが、相変わらず、genesixのTonnyです。


Simulatorでのテスト

Simulatorの場合は必ず同じMacにあるので、次のコマンドを叩くと大丈夫:

$ calabash-ios console
Running irb...
irb(main):001:0> 

Deviceでのテスト

Deviceでテストを行うとき、**必ず** DeviceとMacを同じWiFi環境に入れてください。しかもこの環境でお互いにアクセス制限をかけていないのが前提条件です。

例えば、iPhoneのWiFi IP アドレスは192.168.0.10、次のコマンドを叩く:

$ NO_LAUNCH=1 DEVICE=iphone OS=ios5 DEVICE_ENDPOINT=http://192.168.0.10:37265 calabash-ios console 
Running irb...
irb(main):001:0> 

Record/Playback

irbのインタラクションでrecord_beginを叩くと、Eventのレコーディングが始まるよ〜〜

Record Start

irb(main):001:0> record_begin
""
irb(main):001:0> 

SimulatorもしくはDevice上動作をしてくださいね。

Record End

irb(main):003:0> record_end "login_facebook"
Fetch version http://localhost:37265/version...
"login_facebook_ios6_iphone.base64"

playback

irb(main):003:0> playback "login_facebook"

BOOOOOM! なんと、すべての動作が自動的に動いている!これはすごくない?これはすごくない?

Assertionがあれば、もっとテストケースぽいよね

実はそんなにきにしなくてもいいよ。Assertionは本当にほんの一部のStepなので、他のStepももっともっと試してみてね。


これを見たら、試してみたいよね!?やりましょうよ!

Calabash-iOSをインストール

$ gem install calabash-cucumber

gemとRubyがまだインストールしていない?

何?それじゃGoogle先生に聞いてね〜〜

〜完了〜

iOSの究極テストツール:Calabash-iOSを使いこなすぞ!(1)

こんにちは、genesixで働いているiOSのエンジニアTonnyです。

Calabash-iOSって何?

まず、このツールを聞いたことが無い方に簡単に紹介します。Googleでcalabash-iosを検索すると一番のリンクをクリックすると、Calabash-iOSのHPに飛んでいきます。

原文を使って、簡単に説明すると

Calabash is an automated testing technology for Android and iOS native and hybrid applications

重要なポイントは全部太字にしました。よく見たら、すごいと思わないですね。このようなツールは世の中にすでにいっぱいありますよ。

既存のテストライブラリ・ツール

  1. KIF ( Keep It Functional ) by Square
    • UI Test用
    • accessibility labelを利用している
  2. Kiwi by Allending
    • BDD test用
    • Cedarと似てる
  3. Cedar by Pivotal
    • BDD test用
    • よくできている、OCUnitの代替品になる
    • Deviceのサポートがない
  4. GHUnit by Gabriel
    • OCUnitの代替品
  5. GTM Unit test by Google
    • OCUnitの代替品
  6. OCUnit by Sen:te, supported by Apple
    • Unit Testの一番良いツール
  7. UIAutomation by Apple
    • 大変使い辛い
    • 勿体無いなぁ!
  8. Zucchini by Playup
  9. FoneMonkey -> MonkeyTalk by Gorilla Logic
  10. Frank by Moredip
    • Deviceでの実行はサポートしているとはいえ、なかなか使いづらい
  11. Calabash-iOS by lessPainful
    • 今日の本題 一番良い
    • BDD用
    • SimulatorとDevice両方使える
    • Record/Playbackをサポート

先に結論からいうと:Calabash-iOSが一番良いツール

なぜかというと、

  1. Cucumber式のテストコード書き方。頑張れば、 全部日本語で テストコードを書ける。
  2. Record/Playback機能は非エンジニアのテスターを開放。これは素晴らしい。
  3. SimulatorとDeviceでのテストを同時にサポート。これは実になかなか難しいことだ。他のUIテストのフレームワークはSimulatorとDeviceを同時にサポートできていない。
    • UIAutomationは本当にダメな奴だ。

他の原因もあります。この記事では説明しませんが、興味があれば、Googleしてね。

その他の原因

  • CIシステムと統合しやすい
  • テストケースの中に画面キャプチャーを取れる

Cucumber式のテストコード

CucumberはBDDの世界で非常に有名なツールです。Gherkinを使っていますが、実はあまり気にしなくてもいいです。基本的に、そのテストコードが 自然言語(英語)と似ていて、読みやすい のが特徴です。

Calabashがデフォルトに入れてくれたテストケース

$ calabash-ios gen     # generate the basic test cases

これを実行すると、次のようなコードが生成される

$ cat features/my_first.feature 
Feature: Running a test
  As an iOS developer
  I want to have a sample feature file
  So I can begin testing quickly

Scenario: Example steps
  Given I am on the Welcome Screen
  Then I swipe left
  And I wait until I don't see "Please swipe left"
  And take picture

ちなみに、GFM(github flavored Markdown)で`cucumberを書くと上記のようなSyntax Highlightができる。これは読みやすいぞ!

Cucumberの詳細はまた同じぐらい長さのBlog Postが必要なので、ここでは割愛します。

Calabashがすでにいろいろな Steps を定義してくれたので、基本的な操作とテストは全部カーバー出来ました。その詳細はCalabash-iOSのWikiページを見れば、すぐに書けます。ここで敢えて一部の抜粋を説明します。

Calabash-iOSの Predefined Steps の抜粋

  1. Screenshots
  2. Playback of touch events
  3. Assertions

Record/Playback機能は大変助かる

チームのエンジニアが忙しくて、テストをサボっている。非エンジニアの方はチームにいって、どうしても助けてあげたい!ただ、テストコードを書けず、人力テストしかできない。2週間やったら、非エンジニアの方が疲れて、テストがうまく進めていけない〜〜。

このようなシーンは多々あると思いますね。このタイミングに、ちょっと力になるのはCalabash-iOSの自動テストですね。

一言の仕組み

Calabashは実際に**Private API**を使って、Eventをレコーディングして、後にそのレコーディングしたEventを完璧に再生できる。

Sample

まず、既存のアプリの.xcodeprojが所在のフォルダで、次のコマンドを叩く:

$ calabash-ios setup
$ xcodebuild -list

終わったら、自動的にテスト専用の**target**が生成される。例えば CoreDataBooksと言うサンプルコードを使うと、CoreDataBooks-calというターゲットが追加されます。

そのTargetを選択して、SimulatorもしくはDeviceに入れて、アプリを起動すると、Xcodeのコンソールに

2013-03-22 17:48:37.022 CoreDataBooks[11445:c07] Creating the server: <LPHTTPServer: 0x7574510>
2013-03-22 17:48:37.025 CoreDataBooks[11445:c07] simroot: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk
2013-03-22 17:48:37.027 CoreDataBooks[11445:c07] Started LPHTTP server on port 37265
2013-03-22 17:48:37.735 CoreDataBooks[11445:2103] Bonjour Service Published: domain(local.) type(_http._tcp.) name(Calabash Server)

このようなログが出力されます。

次は一番重要だ

ただ、長さの制限があるので(なぜかわからないよね! Livedoorさん!)次の記事を御覧ください。
 

Introducing our new team member: Ms. zombie.js

初めまして、VOYAGE GROUPの李一(@pank7)と申します。

昨年9月末に中国から参りまして、今子会社adingoでエンジニアをしています。すみませんが、日本語はまだ勉強中なので、これから英語でうちのチームの新しいメンバーを紹介させていただきたいです。

Have you and your team ever encounter the situation, or let's say, difficulty of deciding who will be responsible for scenario testing or browser testing before every release day? Seems like our team -- fluct, have been suffering from that once every 2 weeks for quite a long period of time, long enough for us to start to hate that kind of testings, which requires been done by clicking and typing according to certain movement lists -- scenarios, with only hands and without any automation.

What? Why do we hate that? For God's sake, clicking and typing according according to some instructions is not something an engineer should spend his/her precious time on, not even for 20 minutes! Not to mention that people make mistakes all the time. Well, seriously speaking, the most important reasons why we need some one who can do browser testings for us are that we wish to:
  1. release faster and more frequently,
  2. release with more automations,
  3. release flawlessly,
  4. the last but not the least, be able to release on Fridays.

Thus, we never stopped looking for some one we can count on. However, making browser testings work in the way we want is not as easy as it looks. Some of the obstacles are:
  1. Javascript's are difficult to test
  2. We need to emulate movements, such as clicking and typing, not just HTTP GET's and POST's
  3. There may be too many prerequisites or dependencies for even short testings
  4. Instruction list changes frequently
  5. Confirming the HTML elements on every page can be too boring, and people make mistakes easily

Of course we did have some progresses, however not until recently did we find a best one and think this is some one who can satisfy all our requests. Now, ladies and gentlemen, please allow me to introduce you an insanely fast, headless and so reliable member on our team: Ms. zombie.js. Don't be scared, she dose not bite your brains. Let's find out how she does her works.

Overview

Specifically speaking, we have already prepared a movements/confirmations list called scenario, that is something like the following:
  1. Open URL: http://www.example.com/login, confirm the page has a title called "Example";
  2. Input something into "user_id" and "user_password" boxes, if the page has two, then click the button called "Login", if the page has one, confirm that the page is redirected to URL: http://www.example.com/top, and that page has a title tag called "Top Page";
  3. Click a link called "TEST" if the page has one, confirm that the page goes to URL: http://www.example.com/test, and that page has a title tag called "test";
  4. Click a button called "Click me" if the page has one, confirm that javascript insert an a tag into the page, had text 'TEST', and links to URL: http://test.example.com/
  5. ...

Before Ms. zombie.js came, we test by doing exactly what's in that instruction list, only now that we have Ms. zombie.js doing the job for us. As Ms. zombie.js does not talk much, never actually, I'm afraid you can not talk to her, if you want know what she can do, you can refer to her homepage.

Ok I forgot to tell you Ms. zombie.js is actually a Web browser emulation robot library built with node.js. But to put it simply, Ms. zombie.js emulates a browser, and emulates it so really that it:
  1. has history records,
  2. keeps cookies,
  3. supports HTML5, XHR,
  4. and runs javascript's.
"All of that, just like a real browser, happens asynchronously", said her father. Ms. zombie.js has a group of API's which imitates human motions and easy to use. Ms. zombie.js speaks javascripts, CSS selectors and DOM. Thus, we believe Ms. zombie.js is competent in doing browser testings, in fact she did a good job.

So now if we want to test according the sample scenario above, we write the following code (of course we are using some other libraries like vows and assert, at the same time. You don't have to use them if you don't like them). See, things became easier than before, now we can test by only one command:

$ vows test.'s --spec

Pros

We have to admit that Ms. zombie.js is the best browser emulation robot ever, it
  1. helped us making automatic browser testing become possible;
  2. helped making testings easier because we can now reuse codes, if you organize your code in an elegant way;
  3. increased testing accuracy because it makes no misses, theoretically;
  4. shortened the time spent on testing because of its high speed;
  5. and gives us more confidence to release on Fridays.

All in all, it overcomes the main obstacles which was mentioned above.

and Cons

Although Ms. zombie.js simulates browsers in a really resemble way, that does not make it a real browser. There can be differences, thus you have to carefully organize you output and fit both Ms. zombie.js and real browsers in your development.

The second thing is that Ms. zombie.js is young and evolving, your testing code may get outdated fast, making it difficult to upgrade your zombie.js library.

And by the reason that Ms. zombie.js is a young lady, she can be buggy sometimes. This link demonstrates an example of a bug we found in zombie. We then report it to its github repository homepage, and it was resolved now.


The End

In conclusion, if you are now suffering from doing browser testings by hands, we'd like to strongly recommend you to hand over that work to Ms. zombie.js. She tests automatically, insanely fast, emulate almost everything that a browser has. Even thought she's not perfect in all ways, she is able to help a lot with your testings and releases, enjoy her!

blktraceによるI/Oトレース

こんにちは. adingoで検索周りの仕事をしているHと申します. 検索エンジンやデータベースなどのディスクI/Oが多いアプリケーションでは, いかにI/Oを抑えるかがパフォーマンスの決め手になります. 今回はアプリケーションが出したI/Oリクエスト一つ一つがどのようにデバイスドライバに渡るかをトレースするblktraceというツールを簡単に紹介します. blktraceはlinux kernel 2.6におけるツールとなっており, 2.6.17-rc1以降ではカーネルにパッチを当てることなく利用可能です. (ツール自体はインストールする必要があります.)

何がトレースされる?

linuxカーネルではI/Oリクエストは多数のレイヤーを通じて実際にデバイスに要求が出されます. ざっくり書くと, アプリケーションから発行されたI/Oリクエストは以下のようなパスを通りデバイスへと辿りつきます. ([...] はカーネルの範囲を表しています.)

アプリケーション -> [ファイルシステム -> ページキャッシュ -> ブロックI/Oレイヤ -> デバイスドライバ] -> デバイス
           

blktraceがトレースするのは, "ブロックI/Oレイヤ"の部分になります. ブロックI/Oレイヤでは, I/OスケジューラによりI/Oリクエストの並び換えや連接ブロックへのI/Oリクエストのマージ等が行われているため, ブロックI/Oレイヤの入口と出口ではI/Oリクエストの順番が異なります. つまり, blktraceはブロックI/Oレイヤの入口と出口, そして内部でのI/Oリクエストの状態をトレースすることができるツールとなります.

インストール

通常は, ディストリビューションのパッケージ管理システムからインストールが可能だと思います. 私が試した範囲では, CentOS(yum), Debian(apt), openSUSE(yast) では可能でした. 一応, CentOS(yum)での例を載せておきます.

% sudo yum install blktrace
            

使い方

私も使い方が詳しい訳ではないので, 一番基本的な使い方のみ紹介します. とりあえずこれだけでも何とかなると思います.

% blktrace -d /dev/sda -o - | blkparse -i > trace.out
            

blktraceは実際にトレースを行うプログラムで, blkparseが見やすく整形してくれるツールとなります. 上のコマンドでは監視するデバイス(上では/dev/sda)とトレースログの出力先(上ではtrace.out)を指定すれば良いことになります. これを実行し, 別のシェルなどでI/Oを発行するプログラムを実行すると, そのプログラムのI/Oをトレースすることができます. 実際には, カーネルやその他の動作中のアプリケーションすべてのI/Oが捕捉されてしまうため, 注意が必要です. (また, ファイルにトレース結果を書き込んでしまうため, その分のI/Oも捕捉されてしまいます. blktraceのオプションで別のマシンにネットワーク経由で転送するモードもあるので, それにより回避できます.)

以下に, 自分のsortした時の出力の一部を載せておきます.

8,0    5        1     0.073660305 21678  A   R 280968474 + 32 <- (8,3) 263971704
8,1    5        2     0.073660507 21678  Q   R 280968474 + 32 [zsh]
8,1    5        3     0.073662783 21678  G   R 280968474 + 32 [zsh]
8,1    5        4     0.073664230 21678  P   N [zsh]
8,1    5        5     0.073665153 21678  I   R 280968474 + 32 [zsh]
8,1    5        6     0.073666419 21678  U   N [zsh] 1
8,1    5        7     0.073667496 21678  D   R 280968474 + 32 [zsh]
8,0    5        8     0.078350794 21678  A   R 280968506 + 8 <- (8,3) 263971736
8,1    5        9     0.078350962 21678  Q   R 280968506 + 8 [zsh]
8,1    5       10     0.078351973 21678  G   R 280968506 + 8 [zsh]
8,1    5       11     0.078352571 21678  P   N [zsh]
8,1    5       12     0.078353001 21678  I   R 280968506 + 8 [zsh]
            

結果は左から, 1:デバイス番号, 2:CPU, 3:シーケンス番号, 4:タイムスタンプ, 5:PID, 6:イベント名, 7:リクエストタイプ, 8:開始ブロック(セクタ番号(LBA)) + ブロック(セクタ)数, 9:プロセス名 となります. どのプロセス(5)のどのブロック(8)のI/Oリクエストが, どの状態であるか(6)を見ることができます. イベント名には, I(I/Oスケジューラのキューに挿入された), D(ブロックI/Oレイヤからデバイスドライバに送られた), C(I/Oが完了した)などがあります. 詳しくはマニュアルをご確認ください.

まとめ

linux kernel 2.6から導入されたI/Oトレースのツールを紹介しました. このツールの出力結果を解析して, カーネルのI/Oスケジューリングアルゴリズムを修正する人は少ないと思いますが, 既存スケジューリングアルゴリズムやカーネルのパラメータを調整する場合などは一つの指標になると思います. また, 内部の動作を見てみるのは単純に面白いものです. blktrace自体ができることや, 詳しい使い方は以下のマニュアルやプレゼン資料を見てください.

記事検索
QRコード
QRコード