[Swift]try!Swiftで学んだことまとめ

私は職場で作ってきたテストの話のうち、UI Testに近いところの話をしました。

英語での発表は初めてだったのですが、一部想定通りに話せなかったところがありながらも無事に終えることができ、ホットしました。日本以外から来た人含め、いろんな人から英語も聞き取りやすかったし内容も良かったと言って貰えて、ひとまず安心しました。

お題の悩み

私はSwiftを使ったテストの話(Unit Test)をするかとか、protocolベースのDIの話をテストに絡めるか、UI Testの話をするか悩んでいました。

推薦されたことで話すことができるようになったので、try!Swift全体の中でそれぞれの話す内容が重ならない程度の話題にした方がバリエーション豊かになって良いかなと思い、UI Testsやその周辺の話をしました。

ただ、このレイヤの話はSwift自体でそこの話をするにはネタがない。XCUITestとかだとSwiftではなくiOSフレームワークの話になりますしね。半端にSwift x XCUITest(内部コードとか)の話をするよりは、テスト全体とUI Tests、Re-Engineeringnの話をする方が独自性を持った話ができるかと思い、結果的には話すことにしました。

結果的には、unit test関係で想定していたセッションの内容は他のスピーカーの方々が行なっていたので、重ならずに良かったかもしれません。

運営の方からは良かったとフィードバックをいただけたので、推薦いただいたことに対しては役目を果たせたと感じてはいます。

他のセッション

すでに nowsprinting さんがまとめを書いていたので、テストに関してはそこにお任せ。
http://nowsprinting.hatenablog.com/entry/2017/03/05/061441

内容自体はprotocolやstruct付近を使った話で、functional programmingもかじっていると理解を深めることができる内容でした。

The Two Sides of Writing Testable Code

ここで出てきた “co-effect” に関しては以下が参考になるらしいので、少し読んでみようと思います。

ReactNative

3日目のハッカソンでは、その間に行われたReactNativeのゲリラワークショップを経験しました。

ReactNativeのテストには、JSレベルでは jest、UIレベルだと testID を付与してからのUI Test系ですね。
JSの世界でテストが実行できると、unit testでもXCTestよりも素早くテストのサイクルを回すことができて良いですね。

最後に

本当にお疲れ様でした & ありがとうございました

[Mac][RedwoodHQ]Run on Mac

RedwoodHQ on Macを過去書いた時点ではMacで動かすことができていなかったのですが、最近見て見るとLinux/Mac上でも動作するようになっていました。

http://redwoodhq.com/redwood-download/

からダウンロード・展開して、

$ ./start.sh

を実行、 http://172.0.0.1:3000 へブラウザからアクセスする、です。私はNode 4.7.2で実行していました。

ちなみに、このRedwoodHQは以下にフォークされてPRなどが取り込まれていました。

https://github.com/wolterskluwer-redwoodhq/RedwoodHQ

もともと作ってた人は退いたのかな。

[Java][Android]Error patternを検出する

Google製のFindBugsみたいなもののようです。

これのパターンに何があるのかは以下に書かれていました。

ざっと見てみると、DaggerなどのDIツールを使っている時のルールもありました。
独自ルールも追加できるみたいですね。

なので、何らかの自社製ライブラリへ適合させる時も使いやすいのかな。


Bazelを見ると、Bazelではすでにこれが組み込まれてて、デフォルトONなのですね。

https://github.com/bazelbuild/bazel/blob/c4e92b1ba06fba48121e4db8050a69b6d998e2e9/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java#L108

もう少し話がそれると、Bazelでは以下がデフォルトで組み込まれているのですね。

https://github.com/bazelbuild/bazel/blob/c51d506eb83f1e5974e3317c53532f6e81ca50d8/third_party/BUILD#L310


以下、試しに適用してみたコミットになります。

これに対してビルドすると、generated codeに対してwarningが確認されました。
内容は http://errorprone.info/bugpattern/MissingOverride なのですが、ここら辺を見ているとGoogleのJava style gideに合致しているかも見ているのですね。

「レガシーソフトウェアー改善ガイド」を読んだ

レガシーソフトウェア改善ガイドを読みました。英語では “Re-Enginnering Legacy Software” なので、”改善ガイド”とするには少し内容とタイトルに乖離があるかもしれないですね。

この書籍は、最近のアーキテクチャ(モノリシック/SOA/Microservices)や言語特性の変化、CI/CD環境など含め最近の流れを踏襲した上でレガシーソフトウェアを継続してより改善できる形にするためのtipsが書かれています。そのため、開発環境/スタイル/設計などを含んだ全体的な改善の話が書かれていました。レガシーコード改善ガイドをベースとすると、テストできない、継続して機能を壊さず改善することが困難なソフトウェアがレガシーなものになります。

ソフトウェア開発においてしばしば言われるように、コードがレガシーとなる原因の多くは人に関係します。それは例えばサービス開発におけるサービスの成長フェーズに対するビジネスの要求に応えるためのものだったりとします。そのため、レガシーに見えるものも実はサービス開発を試行錯誤しながら行い、成長した結果と言える面もあるかと思います。(ここは組織の力に依存しそうですが)

この書籍の中で、コード品質の指標として欠陥密度に対する言及があります。それがCoverityによる2012年のLinuxカーネルの静的解析において、コード1000行あたりの欠陥密度(defect density)が0.66/klocであるというところでした。これは純粋に興味深い内容でした。OSSとして多くの意見が入る可能性の高い成果物が、高品質なコードであると示される珍しいものではないでしょうか。そしてそれを支える為に重視しているものがコードレビュー。これにより、低品質なコードの混入を防ぐ、知識の共有とそれらのサポートといった保守も含めた知見を共有しているとあります。

開発の中では心理的な障壁は最善の仕事を効率よく行うことを妨げます。この中に”恐れ”があります。この恐れは未知なものに対峙するときに顕著になため、未知な領域(コード)に足を踏み入れながら、未知を克服していくことが必要となってきます。このような未知を克服しながら進むことを”調査的リファクタリング”(exploratory refactoring)と呼んでいました。

Exploratory Testingが探索的テストと呼ばれる一方、こちらは調査的と表現しているのですが英語をベースとするとどちらも似たようなことをしながら”中身を理解し明らかにしていく”ことを達成しようとしているのですね。

ちなみに、これらを補助するためのツールなども書かれています。

理想のシステムは、コードの品質を開発者の努力なしに自動的に監視し、その情報をチームメンバ全員が利用できるようにするもの。意識しない、努力しないというのは大事で、それが系として組み込まれている状態を指します。やはり意識によって改善するには人は確率的に誤りをおかしすぎてしまいますからね。

そういえばミカドメソッドの話が出てました。これは修正したい対象の周辺をグラフに落としていって、見通しをよくした上で優先順位を定めて取り組むというものです。言及されるとは思いませんでした。

あとはmutableなものをimmutableにしていくところも言及されていました。これは最近の関数型言語に対する風潮もありますね。これは複雑奇怪なビジネスロジックをテスト可能にし、確認可能な状態で単純化することに貢献する説明の箇所で出てきています。

当然、テストの自動化にも言及していました。単体テストを自動化することに対しては誰もが納得することだろうという前提のもと。私もここ数年でモバイルアプリの領域でやってきたことなのですが、 とくに自動化を必要とするのがUIテストの領域 と書かれています。ここがちゃんとできているところはおそらくできていないところに比べて多くの利益を享受しています。不具合の見つからないごく一部の自動化されたUIテストではなく、不具合をちゃんと見つけてくれる多数の自動化されたUIテスト。個人的に、それは特にGUIが差別的な要素になる可能性の大きな特にモバイルアプリの領域では差が出てくるところだと考えています。(ここら辺は今度機会があるのでそこで話すかもしれません)

英語ではこれらのように書かれています。

– Unit tests are not a silver bullet.
– One area that cries out for automation is UI testing.

(4.3.2. Regression testing without unit tests)

他に面白かったところは、Webアプリのアーキテクチャの話でモノリス/SOA/Microservicesなどを比較しているところでした。特に、組織面での利点まで言及していたところが個人的には好印象でした。アーキテクチャはやはり組織に影響を及ぼしあうので。その中で、やはり情報伝達はモノリスがオーバーヘッドが小さく、個々の独立性が高まると従来の情報伝達はオーバーヘッドが大きくなるところが印象的。(いっていること自体は至極真っ当)

まとめ

主な対象はWebサーバアプリでしたが、これはモバイルアプリにも多く転用できるものでした。実際、私がモバイルの領域でやっていたものはこの書籍における改善案の方針として言及されているものが多かったです。

refactoring/rewriteしながら継続して価値を出しているサービスをより継続して開発し続けることができるように取り組んでいきたいですね。

[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を入れてテスト書くまでをざっと学ぶことができるので、やることには良い意味があるものだなーと感じました。

read “The Way of the Web Tester”

The Way of the Web Tester を読んでみました。

私が読んだ時は、まだBeta3でした。最近、Beta4が出て、JSによるテストコードの話が追加されている状態でした。

この書籍は、自動化されたテストを書くための、テストエンジニア向けの入門書という感じです。内容はいかが大まかなところです。

  • Unit/Integration/UIのテストピラミッドの話
  • Unit/Integration/UIのテストコードの書き方(Rubyを例に)
  • コラムとして、例えばrecord/playbackの使えないところ、など

全般的にWebだけの言及なので、モバイルに関しては対象外でした。Selenium系の書籍のようにツールに特筆してはいないので、そういう意味では確かに全般的な入門書という感じです。

ただ、コードの書き方などの話になるとリーダブルコードの内容や実装に近いところの話が含まれてきていたので、そこらへんの実装よりを詳しく学びたいとなったら何かWebフレームワークを使った実装とそのテストコードを書く、というところを開発者向けのなんらかの書籍など見て行う方が良いかもしれないです。

ある程度、書籍などで学んでいたり実装を経験した人からすると確かに入門的なものなのでザーッと読み飛ばしながらコラム中心に読んで終わり、となりそうです。

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