Your SlideShare is downloading. ×
0
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Nds#24 単体テスト
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Nds#24 単体テスト

1,748

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,748
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 第 24 回 長岡 IT 開発者勉強会今日から始める!単体テストの自動化のススメ 単体テストしやすいモジュール設計の指針をつくってミタ      ~カバレッジ 40% めざせ 2012/01/29 @nemuzuka
  • 2. 自己紹介● id:nemuzuka,@nemuzuka● 昨年の春、地元の長岡に帰ってきました!● サーバサイドに Java を使用した Web アプリ ケーションの開発を主にやっております● 新潟は Java やってる人少ない気がします
  • 3. みなさん、テストしてますか? 「お金」という対価を受け取るレベルの プログラムを提供する以上、テストしないということは考えられません。 ま 自 許 テ リ テ え で 己 さ ス リ ス | だ 満 れ ト | ト よ プ る し ス し ね ロ の な ? な | グ は く い ラ て で ム
  • 4. テストは1回やればおしまい?システムは生き物。機能を追加していく過程でそもそもの振る舞いを壊してしまうこともしばしば。ソフトウェアの場合は関係ないと思ってた箇所に思いもよらず影響を及ぼすこともあります。開発言語 /DB サーバ / フレームワークのバージョン UP を行う際にデグレってないかの確認を全部手動でやるのはかったるい。だからといって、構築した時のバージョンを維持するってのも・・・ねぇやっぱり複数回やることが多いんです
  • 5. テストはしなきゃいけないのはわかるけど面倒なんだよなー
  • 6. そりゃ、毎回手動でおこなってたんじゃ効率が悪い。 機械の力を借りましょう。
  • 7. そこで今日のお題はテストなんてかったるくてやってられな限りある時間を有効に使いたいそんなあなたに、うってつけ!
  • 8. 単体テストを自動化しやすい モジュール設計テ について考えてミタストを考える 会
  • 9. テストの自動化というと xUnit を使えばいいよね あとよろしく
  • 10. 失敗 END へのフラグ
  • 11. ある程度の方針が必要なんです● テストしやすい設計、アーキテクチャの確立● 開発者個人にまかせてしまうと、粒度はバラバラ (あ、これ俺のスキーマでないと動かないっスよ)● 何やってるテストなのかわからない (でも、カバレッジ高いから良いでしょ?)● 作られたは良いけど、結局放置 テストが通らなくなってくると、魔法のパラメータ 「 -Dmaven.test.skip=true 」 でテストの実行を無かったことに作ったものの、使い続けられないテストクラスが量産されることに・・・
  • 12. せっかくつくったのに モッタイナイ
  • 13. まずは前提条件対象: MVC モデルを採用した Web アプリ【思想】・ View/Controller  →ロジック記述量を少なく (Action にロジック書く奴はおしおき )・ Model  →もう、嫌って程集約【自動化の対象範囲】・ Ui 部分 (View) は自動化対象外  → selenium とか使ってもいいけど、 UI 部分って変更多いし、   かけた時間に対してメリットが少ないと思うの・サーブレット (Controller) も自動化対象外  →いいから Model に全部任せておけって!    Mock でリクエストパラメータとか作るの面倒じゃん。  →でも、 Session オブジェクトとか HttpRequest とか    J2EE 前提なオブジェクトは Model に渡すなよ。   パラメータは POJO だ ( 簡単にインスタンスを生成できる奴でお願いします )  → Model からの結果をそのままレスポンスに設定するくらいの勢いで!
  • 14. 頑張って自動化する箇所は Model画面に表示する項目の加工すらも Model に持たせるとかして、 View 部分にはできるだけ判断文を持たせないようにした方が幸せになれる気がします。( ロジックの分散を避けるのが目的です。 )システム全体を自動化するには膨大な時間と工数がかかるので、対象を絞りましょう  →バグり易い所 (Model) を重点的にリグレッションテストしやすいように   した方が費用対効果高そう。  → Web ブラウザからの打鍵テストを行う時の確認事項も少なくなるはず。  →本来、 Web ブラウザの打鍵から始まる一連の処理は結合テストだと思う。
  • 15. 自動テストしやすいメソッド「このメソッドを呼んだら、結果どうなる」 が容易に定義できるものもっと言えば、パラメータだけで処理して結果を返すメソッドDB アクセスの場合は、前提条件のデータを格納しておいて、メソッド呼び出しで SQL発行させて結果確認、というのが基本的な流れだから、まぁとっつきやすい
  • 16. 例えばこんな疑問● xUnit のサンプルって、単純な処理(足し算と か引き算)ばっかであんまり実務っぽくない んだもん – 現実のシステムはそんなに単純じゃないよ – 1 回のメソッド呼び出しでいろんなことやる じゃないでもそれは、メソッドの振る舞いを 一連の処理としてみたときの話
  • 17. 粒度を小さくすれば 「結果どうなる」が定義しやすくなるんじゃね?
  • 18. ファイルのインポート処理アップロードされたファイルを1行ずつ読み込んで、テーブルに格納されていなければ、登録。格納されていれば、更新 public void doImport(InputStream is) { Readerインスタンスを生成 while(1行読み込む) { 読み込んだ情報を元に検索条件作成 DB検索 if(該当レコードあり) { 更新データを作成 DB更新 } else { 登録データを作成 このメソッドを呼び出したら DB登録 どうなるべきか?? } } Readerをクローズ テストケースのパターンを増 } やす時は、 InputStream のパ ターンを増やす?
  • 19. こうしたらどうかな? public void doImport(InputStream is) { 検索条件 create検索条件(行データ) { Readerインスタンスを生成 XXXX while(1行読み込む) { } create検索条件 do検索 検索結果 do検索(検索条件) { create登録・更新Entity (DBアクセス) do永続化 } } Readerをクローズ 登録・更新Entity create登録・更新Entity(検索結果) { } if(検索結果あり) { 更新用のEntity生成 } else { 登録用のEntity生成 } }メソッド内の処理を細分化 void do永続化(登録・更新Entity) { →メソッドが何をしているのか if(登録) {  わかりやすくする ( メソッド間も疎結合 ) 登録処理(DBアクセス) →テストパターンを追加する時は } else {  引数のパターンを増やす 更新処理(DBアクセス) } } ※ ソースコード中にコメントを書くよりも細 分化単位で JavaDoc を書いた方がよっぽどい いソースコードになる、と思う
  • 20. さらに一手間● 細分化したメソッドのスコープはパッケージ プライベート – private だとテストクラスから参照できない ● わざわざリフレクション使うのもなぁ・・・ ● public でなければ大体良いんじゃね?● テストクラスは同じパッケージに配置 – どのクラスのテストをしているのかわかりや すく – クラス名も XXXTest とかね。
  • 21. Mock オブジェクト● 使わなくても良いように実装を見直してみる● Mock はあくまでも Mock – テストクラス以外にもメンテナンスコストが かかる – Mock を作ることに情熱をかけ始めたら本末転 倒● テスト済みであれば、実クラスを呼び出して も全然アリだと思う
  • 22. 実装設計にもうひと手間● Model を責務に分けたレイヤーで細分化 Model Service Logic Dao DB ※ トランザクションスクリプトでもいいじゃない
  • 23. レイヤーの責務● Dao – DB アクセス ● 1 テーブルに対する CRUD ● 複数テーブルを結合した SELECT 文発行● Logic – DAO に対するアクセスのとりまとめ ● 親子関係のテーブルに対する登録処理 – Web/Batch 共通で使えそうな処理 ● メール送信 ● 複数 Service で利用される処理● Service – Controller との間を取り持つ delegate – Logic に対するアクセスの取りまとめ
  • 24. テスト自動化のメリット● リグレッションテスト● カバレッジレポート – テストクラスで実行した箇所がわかる● Jenkins 等の CI ツールと組み合わせて – 最新のソースコード取得 – ビルド ( リリースモジュールの生成 ) – テスト ・プロジェクトは進んでいる – レポート出力 ・「俺、仕事している」感 を体感できるハズ を自動で行うことができる 開発者の環境以外でも動作するようにテストクラスを記述することで、環境依存 を減らす ( テストクラスにおけるフルパス指定禁止、スキーマは CI ツールや開発者毎 )
  • 25. 老婆心ながら・・・● カバレッジの目標はがんばりすぎない – 高カバレッジ≠高品質 ● そもそも仕様を満たしていないかもしれません – カバレッジ 100% にするのは難しい ● 外部リソースアクセス ● 標準 API の例外 – カバレッジでなく、 assert にこだわりましょう – SQL のカバレッジは取れない ● SQL でがんばっている箇所があれば、データパターンを増やし てテストもがんばる!● バグが発生したら – 再現するテストケースを書いて、そこから修正 – 抜けてた観点をチーム、組織で共有できれば尚良し● 単体テストはあくまでもメソッドとしての振る舞い – 結合テスト、システムテストが不要な訳ではない
  • 26. 最後にテストのスキルは、言語がかわってもそんなに変わりません。なにより、テストしやすい実装ができるということは、開発者として大きなアドバンテージがあると思います。「テストしやすい実装=シンプルな実装」を目指せるはずです。システムは生き物なのでシンプルに保てれば保守もしやすくなるでしょう。テストがいくら完璧でも、使う人に価値が無いと思われれば、そのシステムは意味がありません。テストだけに情熱をかけすぎないように、ほどほどに。
  • 27. 興味が出てきたら 買って読んでね
  • 28. ご清聴ありがとうございました

×