my cognition

Cognitiveはよいぞ。電波伝搬はよいぞ。

【福岡】ゆるっとIT vol.10「ソフトウェアテストの話を聞こう」 #yurutto_it にお邪魔してきました。

4/4(木)に【福岡】ゆるっとT vol.10「ソフトウェアテストの話を聞こう」にお手伝い枠として参加してきました。本稿は、そのレポートです。

tl;dr

  • テストは、変更毎に必ず1回されるのが望ましい
  • テストは、とりあえず手を付けられるところから、優先順位をつけて始める
  • テストは、{チーム|部署|会社}全体で認識、方針を合わせること

開場前

今回はお手伝い枠で参加したのですが、さくらインターネットさんの福岡オフィスが非常におしゃれですげー!とか思いつつ、主催のiseki_taketoさんと、お手伝いのkamikentaさんとお話しながらぼちぼちと参加者の皆様をお待ちしておりました。

f:id:kitkatayama:20190407151225j:plain
開場前の会場

f:id:kitkatayama:20190407151646j:plain
かんぱーい!!

1.「天神開発チームのテスト自動化の話」 by 山崎 勝平さん

概要

  • コードが変更されたときは必ずテストする。
  • テストを何回実行しても同じ結果になるようにする
  • 複数の環境でテスト可能にする

上記のための手段を実例を交えて紹介。

詳細

Java開発をする上で、それにまつわる具体的なテストコードを元に手法を説明。

基本理念は概要に書いた通りですが、「じゃあ全部annotation書くの?」というのはきつい。それを楽にする方法の一つとして、外部ファイルで定義する方法を説明されてました。また、外部APIが絡む話はモックを使いましょうという、そのままでは開発ができないのでDI(Dependency Injection: 依存性注入)しましょう、SpringBootだとTestRestTemplateとかあるよって話があり。ただ、テストする際にはhtml単位でoutputを見ると差分が出たらすぐにテストが落ちてしまうので、Seleniumで主要機能をテストしていくという感じ。

次に、コードを乗せるインフラ要素、大きく分けて二つ・・・コンテナとVM。全てをK8s上に載せたいが、セキュリティなどの要件上VMを使わないといけない際があるので、それはChefで。インフラの負荷テストはApache Bench(ab)とかを使い、データ量のテストは本番想定を行って非常に大量の件数のデータを用意する。データを用意するプログラムはrubyで書き、引数を指定して件数や種類(DB insert, csvなど)をできるように。それをCIの際にコマンドで注入するような設計。

さて、上記のようにテスト手法が分かったところで、テストコードはどのような観点で作るか。山崎さんは(1)境界値、(2)Null値、(3)例外計、(4)壊れないテストコードを念頭に置いているとのこと。ただ、特に(4)はシステムをわかってしまっているとブラックボックステストができない(コードのリファクタリングに影響を受けるテストコードを書いてしまう)ことがあるので、難しいとのこと。

ところで、コードテストとは別に、静的解析を行い、コードがポリシーに従っているかCheckStyle lintで確認もする。

ここまで様々なことを紹介してきたが、負荷テストやE2Eテスト(Ent to Endテスト、UIテスト)など、自動化できていない部分もある。そこは手動で行ったとのこと。また、テストが時々失敗する例と解決策として、以下のようなことがあった。

  • DBをテスト間で共有してしまっている->テスト毎に実行環境に差分が発生し、テストが落ちていた
    • 解決策: インメモリデータベースに。Dockerで固めるように。

質問解答

  • Q Seleniumのテストについて、テストを選択的に実行するということだが、重要度の付け方とは?/それ以外のテストは?/UIはどうテストしている?
    • A ビジネス的に重要なことを重点的に。例えば、入会手続きや購入手続き。/テストは単体・機能テストほど。/ブラウザで見る程度。
  • Q テストデータ作成の際、分散は考えている?
    • A 考えていない。
  • Q テストを複数回行うという話は、どのように回数を決めているのか
    • A コード変更毎に必ず1回。特にあるコードに何回するという決め打ちはしていない。
  • Q 負荷テストのベースの考え方は?どのようにして必要な負荷を見積もるのか。
    • A 本番想定。(補足として、)現PJが既存システム入れ替えなので、必要ラインが決まっているのでそれに従っている。
  • Q ブラックボックステストにVerifyとか、ある程度作っていないと...(注:質問内容を理解していませんでした...)
    • A たしかに難しい。「関数の呼び出し」に1回とか粒度を決める。リファクタリングしたら壊れるのは課題と思っている。

キーワード、参照先(URLなど)

2.「テストエンジニアから見たテストの話」 by 吉武 伸泰さん (@yoshitake_1201)

概要

  • テストの種類の話
  • テストケースの考え方・実施方法
  • テストやバグとの向き合い方
  • issueの書き方

上記について議論していく(by 主催の井関さんのオーダー)。

詳細

テストの種類の話

まず、「テストをすれば品質は上がるのか」という話で、答えはNO。テストというのは、現在の製品・コードについての情報収集するための手段。テストから得られた情報をもとに、バグの原因を整理し、直すことで品質を向上させる。また、バグの発見を蓄積し、再発を防止する。これらを可能とするツール。

では、テストを始めるにはどうするのか。よく言われるウォーターフォール型のそれぞれでテストするようなイメージの中で、各工程で、まずは、「自分の書いたコードが自分の思い通りに動いていることを保証するテスト」を書く。QCDを考えてテストを絞ることも大事。

テストケースの考え方・実施方法、テストやバグとの向き合い方

ところで、テストとは何か、カバレッジとは何かという疑問がある。どこまで書いたらいいのか、どのような粒度で書いたらいいのか。

テストをどのような範囲、どのような粒度で書くかという方針は、チーム内で共有していないといけない。また、方針を策定する際にはPJのテストに対する成熟度も考慮しないといけない。単体テストごとなのか、総合テスト時なのか。基本的には、書いたその場が良いが、PJ全体でそのような取り組みをいきなり導入するのは現実的ではない。なので、1機能ごとといった、まずは大きな粒度で導入すると良い。

尚、どの粒度でも必要なのは、仕様の把握で、ある機能が正しく動作するというのは仕様によってOK/NGが決まる。仕様があやふやだとテストも成否判定ができないし、プログラムもそのようになっているはず。仕様にフォーカスを当てる意識が大事。テストをすると、その意識が高まってくる。

現実問題として、プログラムを書いた人≠テストを書く人となる場合もある。その場合は、仕様に従ってTrue or Falseのように、確実に成否が出る内容のみをテストするところから手を付ければよい。それがそのまま仕様となるし、一致するはず。

ここで仕様という話が出てきたが、設計とテストでは思考方法は逆である。設計は「問題領域を狭めていく」行為なのに対し、テストは「この領域外への影響は何なのか」という思考になる。

仕様通りに確認する動作チェックは必要だが、仕様外への考慮がより重要。ウォーターフォールに寄れば、降りてきた仕様に書かれていないことで影響を見つけることは、テスト分析の際にしかわからない。

issueの書き方

では、テストを終えたところでissueを書くわけだが、その呼び方はどうしているか。人によっては、「バグ」という呼称だけでパフォーマンスが落ちるかもしれない。一例として、バグをドラゴンと呼ぶと「あのドラゴンどうなってる?」「あのドラゴン倒したいんだけど」というように、コミュニケーションが円滑になるかもしれない。

閑話休題。レポートに乗せる情報はさまざまなので、これはスライドを参考にしてほしい。

心がけることとして、「as-isとto-beがタイトルでわかるように」と「誰が読むのか」。また、バグを管理することも肝要で、PJの進行中はバグの分布、ヤバさの視覚化することで、どの機能にバグが多いのかといった内容をチーム内で把握することで、新たなバグが起こることを抑制できる。さらに、PJ終了後に振り返りの材料にもなる。

質問解答

  • Q オススメ本は?
  • Q issueを新人の振り返りに使うという話で、PJによっては外部要因などどうしようもないものがある/バグは評価に使わないは定説だが、どのように考えているか。
    • A 仰る通り、評価に使わないことが前提。どうしようもないものは、どうでもいいことなので扱わない。あくまで「これだけ成長したね」という客観的な情報として参照できる。
  • Q ユニットテスト以降のテストはテストケースを書くわけだが、楽な最適化方法、ツールはないか。現在はスプレッドシートで書いている。
    • A 前提として全網羅は不可能。スプレッドシートですることもある。(注:このあたり聞けなかった...)

キーワード、参照先(URLなど)

感想

私自身はインフラ環境の運用・開発だったので、プログラムの開発にほぼ携わったことのない人間ですが、大学時代に習った内容を思い出しつつ、テストを行うということにおけるマインドセットが少しわかった気がします。RubyやGoといったモダンな言語では、チュートリアルにすらテストが含まれているということなので、そのあたりから手を付けようかと思います。

個人的にですが、上記の内容を書く上で当日の #yurutto_it でつぶやかれた内容を一旦Togetterにまとめました。どうにもまとめた後は削除できないようで・・・必要であれば、運営のどなたかが作成されれば、そちらにポインタを書くのでTwitter等でメンションいただければと思います。

f:id:kitkatayama:20190407151349j:plain
お片付け完了!

終わりに

手書きのメモについては、以下のフォトライフに上げています。

http://f.hatena.ne.jp/kitkatayama/20190404_yurutto_it/?sort=old