Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ユニットテスト 1日目

3,003 views

Published on

Python Developer Camp2008
ユニットテストの紹介スライド

Published in: Technology
  • Be the first to comment

ユニットテスト 1日目

  1. 1. ユニットテスト - 1日目 - 渋川よしき
  2. 2. まずは <ul><li>目的 </li></ul><ul><ul><li>ユニットテストは何かを知る </li></ul></ul><ul><ul><li>ユニットテストは何ではないかを知る </li></ul></ul><ul><ul><li>テスト駆動開発の作法を知る </li></ul></ul><ul><ul><li>unittest.py, doctest を使ってみる </li></ul></ul><ul><li>やって欲しいこと ※ </li></ul><ul><ul><li>体験->発見 </li></ul></ul><ul><ul><li>いつもと違ったことをする </li></ul></ul><ul><ul><li>質問する </li></ul></ul><ul><ul><li>失敗はない、学びがある </li></ul></ul><ul><ul><li>楽しむ </li></ul></ul>ユニットテスト1日目 Page ※ 六本木ヒルズでやっている   NLP セミナー の手法を参考にしてます
  3. 3. チェックイン ※ <ul><li>ペアを作ってください </li></ul><ul><ul><li>二人一組で開発してもらいます </li></ul></ul><ul><ul><li>やろうとすること、考えていることを口に出すと学習効果アップ ※ </li></ul></ul><ul><li>自己紹介 (2 人で 2 分 ) </li></ul><ul><ul><li>自分の名前 or ハンドルネーム </li></ul></ul><ul><ul><li>Python との関わり </li></ul></ul><ul><ul><li>この1時間で何を学びたいか?という決意表明をしてください </li></ul></ul>ユニットテスト1日目 Page ※ 僕が勝手に 師匠と呼んでいる方の  スライド を参考にしました ※ 「言語技術」が日本のサッカーを変える
  4. 4. アジェンダ <ul><li>ディレクティブテスト </li></ul><ul><ul><li>ユニットテストとは何か? </li></ul></ul><ul><ul><li>ユニットテストとは何ではないのか? </li></ul></ul><ul><li>unittest.py を使ったテスト駆動開発体験 </li></ul><ul><ul><li>まずは開発のデモ </li></ul></ul><ul><ul><li>続きはみなさんの手で! </li></ul></ul><ul><li>doctest を使ってみる </li></ul>ユニットテスト1日目 Page
  5. 5. テストの分類 ~ディレクティブなテスト~
  6. 6. 2種類のテスト <ul><li>ディレクティブなテスト </li></ul><ul><ul><li>開発をディレクション ( 方向付け ) するためのテスト </li></ul></ul><ul><ul><li>アジャイルソフトウェア開発で言うところのテスト </li></ul></ul><ul><li>マネジメントのためのテスト </li></ul><ul><ul><li>品質などを管理するためのテスト </li></ul></ul><ul><ul><li>いわゆる、ソフトウェア工学の教科書に出てくるテスト </li></ul></ul>ユニットテスト1日目 Page
  7. 7. この分類の発想の種 <ul><li>フランクリンプランナー </li></ul><ul><ul><li>ディレクタ・リーダ ( メンバーをひっぱる ) </li></ul></ul><ul><ul><ul><li>戦略立案、決断、全体設計 </li></ul></ul></ul><ul><ul><li>マネージャ ( メンバーの尻をたたく ) </li></ul></ul><ul><ul><ul><li>人・モノ・金の管理、細かい設計 </li></ul></ul></ul><ul><li>ソフトウェアのテスト </li></ul><ul><ul><li>アジャイル開発のテスト </li></ul></ul><ul><ul><li>ソフトウェア工学の本に載っているテスト </li></ul></ul>ユニットテスト1日目 Page +ほりうち!師匠のスライド
  8. 8. テスト駆動開発 (TDD) とユニットテスト <ul><li>テスト駆動開発 </li></ul><ul><ul><li>テストを先に書き、実際のコードをその後に書くやり方 </li></ul></ul><ul><ul><li>この開発手法の中で書くテストがユニットテスト </li></ul></ul><ul><ul><li>eXtreme Programming で広まった手法 </li></ul></ul><ul><ul><li>開発の方向付けをするディレクティブなテスト </li></ul></ul><ul><li>いろんな呼び方 </li></ul><ul><ul><li>テストファーストプログラミング </li></ul></ul><ul><ul><li>デベロッパーテスト </li></ul></ul><ul><ul><li>動く仕様書 </li></ul></ul>Here comes your footer  Page
  9. 9. まとめ ~ユニットテストとは?~ <ul><li>ユニットテストとは何か? </li></ul><ul><ul><li>開発を方向付けする </li></ul></ul><ul><ul><li>テスト駆動開発の中で書く </li></ul></ul><ul><li>ユニットテストは何ではないか </li></ul><ul><ul><li>品質管理のテスト </li></ul></ul><ul><ul><ul><li>ウォーターフォールのテストフェーズのテスト </li></ul></ul></ul>Here comes your footer  Page
  10. 10. ユニットテストをテスト駆動で書く unittest.py
  11. 11. 例題:ダーツのクリケット <ul><li>15 ~ 20 、ブル ( 中心 ) だけを使う </li></ul><ul><li>交互に投げる </li></ul><ul><li>1つの数字に3本入ると占領 ( クローズ ) </li></ul><ul><ul><li>ダブルは2本分、トリプルは3本分 </li></ul></ul><ul><ul><li>全員が一つの数字をクローズするとキル </li></ul></ul><ul><ul><li>クローズしてキルされるまではスコアが入る </li></ul></ul><ul><li>誰かが全部をクローズすると終了 </li></ul><ul><ul><li>スコアが高い人の勝ち </li></ul></ul><ul><ul><li>最大 20 ラウンド </li></ul></ul>Here comes your footer  Page 引用元: Wikipedia
  12. 12. まずは準備 <ul><li>ファイルの構成はどちらでもいいです。 </li></ul><ul><ul><li>実際のコードとテストコードでファイル分割 </li></ul></ul><ul><ul><li>テストコードも実際のコードも同じファイルにする </li></ul></ul><ul><li>PyScripter を使っていればスタートアップコードは不要です </li></ul><ul><li>最初のテストをパスするところまではデモします。真似してタイプしてみてください </li></ul><ul><li>二つめ以降は画面に出しませんので、 挑戦してみてください </li></ul>ユニットテスト1日目 Page # -*- coding: utf-8 -*- import unittest # スタートアップコード if __name__ == “__main__”: unittest.runTests()
  13. 13. 例題:ダーツのクリケット ( 今回のワークで扱う範囲 ) <ul><li>15 ~ 20 、ブル ( 中心 ) だけを使う -> 18 と 20 だけ使う </li></ul><ul><li>交互に投げる ->一人分だけ実装 </li></ul><ul><li>1つの数字に3本入ると占領 ( クローズ ) </li></ul><ul><ul><li>ダブルは2本分、トリプルは3本分 </li></ul></ul><ul><ul><li>全員が一つの数字をクローズするとキル </li></ul></ul><ul><ul><li>クローズしてキルされるまではスコアが入る </li></ul></ul><ul><li>誰かが 全部 (18 と 20) をクローズすると終了 </li></ul><ul><ul><li>スコアが高い人の勝ち </li></ul></ul><ul><ul><li>最大 20 ラウンド </li></ul></ul>ユニットテスト1日目 Page
  14. 14. テスト駆動開発の基本ルール <ul><li>テストファースト </li></ul><ul><ul><li>Python が「コードを書いてくれ~」と言ってからコードを書く </li></ul></ul><ul><ul><li>具体的には AttributeError, AssertionError など </li></ul></ul><ul><li>仮実装 </li></ul><ul><ul><li>返値が 3 なら、 return 3 と書いてしまう </li></ul></ul><ul><li>三角測量 </li></ul><ul><ul><li>一つのメソッドにつき2つのテストケースを使う </li></ul></ul><ul><li>明白な実装 </li></ul><ul><ul><li>分かり切っている実装は仮実装を行わないでいきなり実装 </li></ul></ul><ul><ul><li>今回は封印してください </li></ul></ul>ユニットテスト1日目 Page
  15. 15. 最初のメソッドを実装するまで テストケースを書く <ul><li>テストケースは unittest.TestCase の子クラスとして実装します </li></ul><ul><li>テストを書くメソッドは test から始めます </li></ul><ul><li>TestCase クラスのメソッド (assert_, assertFalse, assertEqual など ) を使ってテストを書いていきます。 </li></ul><ul><li>なるべく小さいステップで上れるように、階段を設定していきます。 </li></ul>ユニットテスト1日目 Page class TestCricket(unittest.TestCase): def test_throw_1(self): game = Cricket() game.throw(18, 1)         self.assertEqual(game.get_count(18), 1)
  16. 16. 最初のメソッドを実装するまで Failure を見る->仮実装で OK を見る <ul><li>次に、 NameError( クラスが無い ) と言われるので、クラスを実装する。 </li></ul><ul><li>NameError->AttributeError( メソッドがない ) とひとつずつ解決していくと、 Error が Failure( テスト失敗 ) に変化する </li></ul><ul><li>Failure を見たら、仮実装 ( テストを通るだけの最低限 ) をしてテストを OK にする </li></ul>ユニットテスト1日目 Page class Cricket(object): def throw(self, area, count): pass def get_count(self, area): return 1 # 仮実装
  17. 17. 最初のメソッドを実装するまで 三角測量でメソッドを完成させる <ul><li>もう一つテストを書いて、実装を完成させます ( 三角測量 ) </li></ul><ul><ul><li>第一ステップ:一つ値を設定してから取得 ( 最初の仮実装 ) </li></ul></ul><ul><ul><li>第二ステップ:もう一つ値を設定して、合計値を取得 ( 今回のステップ ) </li></ul></ul>ユニットテスト1日目 Page def test_throw_2(self): game = Cricket() game.throw(18, 1) game.throw(18, 2) self.assertEqual(game.get_count(18), 3)
  18. 18. それでは手を動かしてみて下さい 残りの仕様を実装してみてください <ul><li>15 ~ 20 、ブル ( 中心 ) だけを使う -> 18 と 20 だけ使う </li></ul><ul><li>交互に投げる ->一人分だけ実装 </li></ul><ul><li>1つの数字に3本入ると占領 ( クローズ ) </li></ul><ul><ul><li>ダブルは2本分、トリプルは3本分 </li></ul></ul><ul><ul><li>全員が一つの数字をクローズするとキル </li></ul></ul><ul><ul><li>クローズしてキルされるまではスコアが入る </li></ul></ul><ul><li>誰かが 全部 (18 と 20) をクローズすると終了 </li></ul><ul><ul><li>スコアが高い人の勝ち </li></ul></ul><ul><ul><li>最大 20 ラウンド </li></ul></ul>ユニットテスト1日目 Page
  19. 19. ユニットテストのその後 今回はここまではできません m(_ _)m <ul><li>リファクタリング </li></ul><ul><ul><li>機能追加すると徐々にコードが汚くなる </li></ul></ul><ul><ul><li>プログラムを整理してキレイにする </li></ul></ul><ul><ul><li>修正後のコードの動作はユニットテスト が保証する </li></ul></ul><ul><li>開発のリズム </li></ul><ul><ul><li>レッド:テストが失敗 </li></ul></ul><ul><ul><li>グリーン:テストが成功 </li></ul></ul><ul><ul><li>リファクタリング:きれいなコードへ </li></ul></ul>きれい 汚い ( すぐに ) 動かない ※ 角谷さんのスライド より GREEN 動く Refactoring RED ユニットテスト1日目 Page
  20. 20. doctest を使ってみよう ユニットテスト1日目  Page
  21. 21. doctest <ul><li>doctest とは? </li></ul><ul><ul><li>docstring の中のテストコードを実行する仕組み </li></ul></ul><ul><ul><li>コメントの中に自然に書ける </li></ul></ul><ul><ul><li>インタラクティブモードをコピペすればテスト完成 </li></ul></ul><ul><ul><li>文芸的なテスト </li></ul></ul><ul><ul><li>Python が発祥? </li></ul></ul>ユニットテスト1日目 Page    import doctest    def pow(x, y):     &quot;&quot;&quot;calc power.    >>> pow(1, 2)    1    >>> pow(10, 2)    100    &quot;&quot;&quot;    result = 1    for i in xrange(y):    result *= x    return result    if __name__ == '__main__':    doctest.testmod()
  22. 22. doctest を書いてみよう <ul><li>例題:先ほど作ったクリケットのクラスのテスト </li></ul><ul><ul><li>ゲーム終了までの過程をインタラクティブモードで実行 </li></ul></ul><ul><ul><li>それをコピペして、 docstring に書き込みます。 </li></ul></ul><ul><ul><li>もしも unittest のスタートアップを書いていた場合には doctest の スタートアップに切り替えます。 </li></ul></ul><ul><li>実行の仕方 </li></ul><ul><ul><li>スタートアップコードを書いた場合にはそのままコンソールから実行できます </li></ul></ul><ul><ul><li>エラーがないと何も画面には出ません </li></ul></ul><ul><ul><li>-v をつけると、実況中継が出ます </li></ul></ul>ユニットテスト1日目 Page
  23. 23. doctest に関する渋川の所感 <ul><li>メリット </li></ul><ul><ul><li>気軽に書ける </li></ul></ul><ul><ul><li>コメントの中にかけるので、自然言語で補強できる </li></ul></ul><ul><ul><li>ユーザの目に触れやすい </li></ul></ul><ul><ul><li>ライブラリ系ならば動作可能なドキュメント / サンプルコードとして使える </li></ul></ul><ul><li>デメリット </li></ul><ul><ul><li>複雑なテストケースが書きにくい </li></ul></ul><ul><ul><li>網羅的なテストケースが書きにくい ( 1オブジェクトにつき数パターンが限度? ) </li></ul></ul><ul><ul><li>return で結果がきれい出るものじゃないと書きにくい ( 結果が DOM ツリーになるとか ) </li></ul></ul>ユニットテスト1日目 Page
  24. 24. 宿題 <ul><li>周りの人とユニットテストについて議論してみましょう。 </li></ul><ul><li>ダーツのクリケット </li></ul><ul><ul><li>残りのルールもすべて実装してみてください </li></ul></ul><ul><li>ボウリング </li></ul><ul><ul><li>ユニットテストのサンプルとして人気の、ボウリングのスコア計算を作ってみてください </li></ul></ul><ul><li>100 本ユニットテスト ※ </li></ul><ul><ul><li>ユニットテストを 100 本書いてみて下さい </li></ul></ul>※ MindMap のセミナー の宿題を   参考にしました ユニットテスト1日目 Page
  25. 25. 参考資料 これからユニットテストを深めていくために <ul><li>Python のライブラリリファレンス unittest , doctest </li></ul><ul><li>デブサミ 2008 和田卓人氏「デベロッパーテスティング・ライブ」 </li></ul><ul><li>JPUG 北海道支部 /Ruby 札幌合同 角谷信太郎氏「スはスペックのス」 </li></ul><ul><li>Google->TDD, ユニットテスト etc </li></ul><ul><li>http://www.codeplex.com/pyspec/ - 引っ越し予定 </li></ul><ul><li>まさ ー る 氏 Kent Beck Testing Framework 入門 ( 渋川の原点 ) – 1999 年 </li></ul>ユニットテスト1日目 Page

×