『テスト駆動Python』入門 ― pytestとテスト駆動開発

Acd2f6f7498ea41881e161e191aa7c02?s=47 yattom
June 12, 2019

『テスト駆動Python』入門 ― pytestとテスト駆動開発

書籍『テスト駆動Python』の内容に沿って、Pythonようテスティングフレームワークであるpytestの簡単な使い方などを紹介します。テスト駆動開発についても触れます。

Acd2f6f7498ea41881e161e191aa7c02?s=128

yattom

June 12, 2019
Tweet

Transcript

  1. 『テスト駆動Python』入門 やっとむ こと 安井力 2019.6.12 https://is.gd/Bpl5XQ

  2. 安井 力 / やっとむ twitter:@yattom https://www.facebook.com/yattom プログラマー Java Python Ruby

    JavaScript テスト駆動開発 アジャイルコーチ ワークショップ 現場導入 技術支援 ゲームを作って一緒に遊ぶ 宝探しアジャイルゲーム、 カンバンゲーム、 心理的安全性ゲーム Python歴 10年以上! (だと思う)
  3. None
  4. None
  5. パンパイプ

  6. pytestとは • Pythonで人気のテスティングフレームワーク • 導入が容易で、テストが書きやすく、学習曲線がなだらか • コミュニティが活発で、機能拡張が豊富 • 日本語の情報も多い (Qiitaで273件)

    • わかりやすい日本語の書籍がある
  7. 『テスト駆動Python』とは ― 目次 1. はじめてのpytest 2. テスト関数を作成する 3. pytestのフィクスチャ 4.

    組み込みフィクスチャ 5. プラグイン 6. 構成 7. pytestと他のツールを併用する
  8. 豪華付録も! 付録A. 仮想環境 付録B. pip 付録C. pytestのプラグイン 付録D. Pythonプロジェクトのパッケージ化と配付 付録E.

    xUnitフィクスチャ 付録F. クラウドでpytestを使う 付録G. pytestを用いたテスト駆動開発
  9. 豪華付録も! 付録A. 仮想環境 付録B. pip 付録C. pytestのプラグイン 付録D. Pythonプロジェクトのパッケージ化と配付 付録E.

    xUnitフィクスチャ 付録F. クラウドでpytestを使う 付録G. pytestを用いたテスト駆動開発 pytestに依存しない Pythonの利用方法ガイド 日本語版書き下ろし! 日本語版書き下ろし!
  10. テストの種類について ― まえがきより • ユニットテスト • 統合テスト (インテグレーションテスト、 結合テスト) •

    システムテスト • 機能テスト • 皮下テスト 参考: JSTQBの定義(テストレベル) • コンポーネントテスト • 統合テスト • システムテスト • 受け入れテスト JSTQB=日本ソフトウェアテスト資格認定委員会
  11. 簡単なテストコード user_test.py: from user import User def test_20歳は成人(): sut =

    User(name='yattom', age=20) assert sut.is_adult() def test_10歳は子ども(): sut = User(name='yattomy', age=10) assert sut.is_child()
  12. 簡単なテストコード ― クラスにする user_test.py: class TestUser: def test_20歳は成人(self): sut =

    User(name='yattom', age=20) assert sut.is_adult() def test_10歳は子ども(self): sut = User(name='yattomy', age=10) assert sut.is_child()
  13. pytestは簡単に使える • テストケースの命名 • ファイル名を test_*.py か *_test.py にする •

    関数名の先頭にtestを付ける • クラス名の先頭にTestを付ける • assert • 生のassertで書くだけ • 他ツールではいろいろなassertの書き方を覚えないといけない • 実行結果 • テスト失敗時の表示が懇切丁寧!
  14. 実行結果の例

  15. 実行結果の例 ― 結果の差異

  16. 実行結果の例 ― 文字列の差異

  17. フィクスチャ フィクスチャ = テストで必要となるデータやオブジェクト、前提条件 • 必要なオブジェクトを生成する • データを事前に作っておく • ファイル、ネットワーク接続などのリソースを準備する

    @pytest.fixtureで定義し、必要なテスト側でパラメータとして受け取る • それだけ! • 全テストで自動的に利用する、などの設定も可能
  18. フィクスチャの例 @pytest.fixture def clear_db(): pass # データベースを初期化 @pytest.fixture def adult():

    return User(name='yattom', age=20) @pytest.fixture def child(): return User(name='yattomy', age=10) def test_20歳は成人(clear_db, adult): assert adult.is_adult() def test_10歳は子ども(clear_db, child): assert child.is_child()
  19. その他のフィクスチャ関連情報

  20. パラメータテストの例 @pytest.mark.parametrize('age, adult, child', [ (20, True, False), (10, False,

    True), (19, False, True), ]) def test_成人かどうか(age, adult, child): sut = User(name='yattom', age=age) assert sut.is_adult() == adult assert sut.is_child() == child
  21. モック テストケース内で、テスト対象以外のオブジェクトが必要になるとき、本物のオブジェクト の代わりにモックオブジェクトと呼ばれるテスト用の特別なオブジェクトを用いる。妥当な 結果を返したり、使われ方が合っているか確認したりするのに使う。 • データベースにアクセスしてテストが遅くなるのを防ぐ • 本来なら通信する処理を省略して安定させる • 複雑なオブジェクト構造を構築しないですむ

    ※テストダブルの一種(ダブル=影武者、代役) 。テストダブルの種類として、モック、スタブ、 スパイ、フェイク、ダミーがある。 http://bliki-ja.github.io/TestDouble/
  22. pytestで使えるモック monkeypatch (組み込みフィクスチャ) • 好きなオブジェクトのアトリビュートやメソッドを自由に置き換える • テストケース内だけで有効、自動で元通りになる • 環境変数も書き換えられる unittest.mock

    (標準ライブラリ) • コード内のテスト対象外のオブジェクトや、組み込みオブジェクトを モック化する • モックへの呼び出しを記録し、正しいか確認する • pytest-mockerプラグインと併用すると便利
  23. monkeypatchの例 def read_file(filename): with open(filename, "r") as f: lines =

    f.readlines() return lines def test_file_read(monkeypatch): import io dummy_stream = io.StringIO("a¥nb¥nc¥n") monkeypatch.setitem(__builtins__, 'open’, lambda a, b: dummy_stream) lines = read_file('dummyfilename’) assert lines == ['a¥n', 'b¥n', 'c¥n']
  24. mock + pytest-mockerの例 • TBA

  25. テスト実行の制御 テストに@pytest.mark.XXXXを付けて、テスト実行を制御できる XXXXに指定する値 • skip • スキップする(実行しない) まだ開発中でテストできない、など • skipif

    • スキップする条件を指定できる • 例: 特定のバージョンの時だけテストする • 自由に指定する • テストに自由にマークを付けて、実行する・しないを指定できる • 例: ローカルの時だけ、CIの時だけ、機能をグループ化する、など
  26. テストの整理分類 • ユニットテスト、コンポーネントテスト • 開発中、手元環境、高速 • 開発者が書く、依存関係や通信などはモックする • 統合テスト •

    人が作ったものと組み合わせる、CI環境 • 開発者やテストエンジニアが書く、モック使いすぎると意味なくなるが必要な場合も • E2E(エンドツーエンド)テスト • フロントエンドや外部通信など引っくるめて、テスト環境 • テストエンジニアが手でやるか自動化、pytest-seleniumの出番(かも) • システムテスト • シナリオベース、時間がかかる、データが必要 • テストエンジニアが手でやる、完全な自動化はまれ
  27. テストの整理分類

  28. pytestによる開発者とテストエンジニアの コミュニケーション • pytestは読みやすい、書きやすい • 本体+拡張が非常に強力で機能が豊富、共通ツールになる可能性 • 開発者がテストを書き、テストエンジニアがレビューする • テストエンジニアがテストを書き、開発者が利用・実行する

    • 開発者とテストエンジニアがペアプロする • 障害が起きたら、再現テストを書く
  29. “Pytest - why it‘s more popular than unittest?” なんでPytestはunittestより人気なの? http://www.blog.j-labs.pl/2019/02/Pytest-why-its-more-popular-than-unittest

    • unittestから簡単に乗り換えられた • 複数CPUに分散実行できる • parametrized モジュールを簡単に利用できる • マーク(mark)を使ってテストスイート(テスト群)を整理できる • flake8と統合できる • テスト結果をHTMLで残せる
  30. 付録G pytestを用いたテスト駆動開発 テスト駆動開発とは… • 自動化テストを、開発を進める(駆動する)道具として活用する • テストコードとプロダクトコードを同時に書く※ • 「レッド・グリーン・リファクタリング」のサイクルを 高速にまわす(数分単位)

    • 仕様、設計、実装を一連の活動として織り込む ※厳密な「テストファースト」に限らない
  31. 「動作するきれいなコード」、ロン・ジェフリーズのこの 簡潔な言葉が、テスト駆動開発(TDD)のゴールだ。 動作するきれいなコードはあらゆる意味で価値がある ─ Kent Beck

  32. きれい 汚い (すぐには)動かない 動作する Green Refactoring TDDと黄金の回転

  33. https://www.flickr.com/photos/emotakespictures/33245514280/ 行き先を示す 道しるべ

  34. 足下を照らす 明かり https://www.flickr.com/photos/menschmaschine/19898877294/

  35. 自分の 歩幅で

  36. リファクタリング • リファクタリング… きれいなコードを維持するための作業 動作する きれいなコード

  37. きれい 汚い (すぐには)動かない 動作する Green Refactoring TDDと黄金の回転 動作する きれいなコード

  38. きれいを保つ http://www.flickr.com/photos/adwriter/226233780/

  39. リファクタリングの対象 • コードをきれいにする • メソッド名、変数名 • インデント • コメント •

    設計も見直す • プロダクトコードもテストコードも見直す • 常にやり続ける • 「動くコード」を保証するテストが前提 大
  40. 「きれい」? ◦ きれいな部屋、きれいな机、きれいな作業スペース ×きれいな花、きれいな色、きれいな風景 • 感覚ではなく、論理的なもの • 美醜ではなく、効率や安全に関わるもの 動作するきれいなコード=clean code

    that works clean beautiful, aesthetic
  41. なぜ「きれい」? • 読みやすさ • シンプル • 予測 • 安全 •

    「動作するもっともシンプルなコード」 • 「もっともシンプル」に到達するには試行錯誤が必要 • きれい、シンプルの基準は、スキルや経験による
  42. TDDは開発手法 あるある: 「あ、きみテスト駆動開発やったことあるの? じゃあテスト書けるね!」 • テスト手法ではない! • プロダクションコードを書くために、テストコードも書く • 他の手法と組み合わせて使える

  43. アジャイルテスト 高品質を追求するアジャイルチームにおけるテストの視点 増田聡 Developer Summit 2010 http://www.slideshare.net/satoshimasuda/ss-3241717

  44. 余談: TDDのテストはテストじゃない…? • TDD=開発手法≠テスト手法 • でもテスト書いてるじゃんね • 単純な事実: TDDで書いたテストは 必要なテストすべてを

    網羅しない可能性がある (網羅したかったら 網羅するように 書かないといけない) https://www.slideshare.net/goyoki/votddtdd-tdd-on-live
  45. 時間があれば… ライブコーディングで テスト駆動開発デモ! 時間なかったら懇親会で!

  46. 質問:TDDをやろうと思ったのはなぜですか? 面白そうだったから! ↓ •脳味噌の想像力を超えた設計に到達 •自分の能力を拡大する

  47. 質問:TDDを実際の仕事で使いますか?

  48. None
  49. None
  50. None
  51. まとめ • pytestはとっつき易く、修得も早く、痒いところに手が届く • しかも高機能で、さまざまな拡張があり、情報も豊富 • pytestのフィクスチャは最高、知らずに死ぬのはもったいない • プログラマもテストを知るとよいし、 テストエンジニアもpytestを知るとよい

    • テスト駆動開発は楽しいし、開発者にとって強力なツール • リファクタリングは技術的負債の返済 = ハードな先行投資 ≠ 感覚やポリシーの話ではない • テスト駆動開発 = 開発手法 ≠ テスト手法
  52. おまけ モブプロについて: アギレルゴ川口さんのHunter社見学記 • http://kawaguti.hateblo.jp/entry/2019/05/04/004855 • http://kawaguti.hateblo.jp/entry/2019/05/07/124007