Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

安井 力 / やっとむ twitter:@yattom https://www.facebook.com/yattom プログラマー Java Python Ruby JavaScript テスト駆動開発 アジャイルコーチ ワークショップ 現場導入 技術支援 ゲームを作って一緒に遊ぶ 宝探しアジャイルゲーム、 カンバンゲーム、 心理的安全性ゲーム Python歴 10年以上! (だと思う)

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

パンパイプ

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

『テスト駆動Python』とは ― 目次 1. はじめてのpytest 2. テスト関数を作成する 3. pytestのフィクスチャ 4. 組み込みフィクスチャ 5. プラグイン 6. 構成 7. pytestと他のツールを併用する

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

豪華付録も! 付録A. 仮想環境 付録B. pip 付録C. pytestのプラグイン 付録D. Pythonプロジェクトのパッケージ化と配付 付録E. xUnitフィクスチャ 付録F. クラウドでpytestを使う 付録G. pytestを用いたテスト駆動開発 pytestに依存しない Pythonの利用方法ガイド 日本語版書き下ろし! 日本語版書き下ろし!

Slide 10

Slide 10 text

テストの種類について ― まえがきより • ユニットテスト • 統合テスト (インテグレーションテスト、 結合テスト) • システムテスト • 機能テスト • 皮下テスト 参考: JSTQBの定義(テストレベル) • コンポーネントテスト • 統合テスト • システムテスト • 受け入れテスト JSTQB=日本ソフトウェアテスト資格認定委員会

Slide 11

Slide 11 text

簡単なテストコード 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()

Slide 12

Slide 12 text

簡単なテストコード ― クラスにする 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()

Slide 13

Slide 13 text

pytestは簡単に使える • テストケースの命名 • ファイル名を test_*.py か *_test.py にする • 関数名の先頭にtestを付ける • クラス名の先頭にTestを付ける • assert • 生のassertで書くだけ • 他ツールではいろいろなassertの書き方を覚えないといけない • 実行結果 • テスト失敗時の表示が懇切丁寧!

Slide 14

Slide 14 text

実行結果の例

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

フィクスチャ フィクスチャ = テストで必要となるデータやオブジェクト、前提条件 • 必要なオブジェクトを生成する • データを事前に作っておく • ファイル、ネットワーク接続などのリソースを準備する @pytest.fixtureで定義し、必要なテスト側でパラメータとして受け取る • それだけ! • 全テストで自動的に利用する、などの設定も可能

Slide 18

Slide 18 text

フィクスチャの例 @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()

Slide 19

Slide 19 text

その他のフィクスチャ関連情報

Slide 20

Slide 20 text

パラメータテストの例 @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

Slide 21

Slide 21 text

モック テストケース内で、テスト対象以外のオブジェクトが必要になるとき、本物のオブジェクト の代わりにモックオブジェクトと呼ばれるテスト用の特別なオブジェクトを用いる。妥当な 結果を返したり、使われ方が合っているか確認したりするのに使う。 • データベースにアクセスしてテストが遅くなるのを防ぐ • 本来なら通信する処理を省略して安定させる • 複雑なオブジェクト構造を構築しないですむ ※テストダブルの一種(ダブル=影武者、代役) 。テストダブルの種類として、モック、スタブ、 スパイ、フェイク、ダミーがある。 http://bliki-ja.github.io/TestDouble/

Slide 22

Slide 22 text

pytestで使えるモック monkeypatch (組み込みフィクスチャ) • 好きなオブジェクトのアトリビュートやメソッドを自由に置き換える • テストケース内だけで有効、自動で元通りになる • 環境変数も書き換えられる unittest.mock (標準ライブラリ) • コード内のテスト対象外のオブジェクトや、組み込みオブジェクトを モック化する • モックへの呼び出しを記録し、正しいか確認する • pytest-mockerプラグインと併用すると便利

Slide 23

Slide 23 text

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']

Slide 24

Slide 24 text

mock + pytest-mockerの例 • TBA

Slide 25

Slide 25 text

テスト実行の制御 テストに@pytest.mark.XXXXを付けて、テスト実行を制御できる XXXXに指定する値 • skip • スキップする(実行しない) まだ開発中でテストできない、など • skipif • スキップする条件を指定できる • 例: 特定のバージョンの時だけテストする • 自由に指定する • テストに自由にマークを付けて、実行する・しないを指定できる • 例: ローカルの時だけ、CIの時だけ、機能をグループ化する、など

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

テストの整理分類

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

“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で残せる

Slide 30

Slide 30 text

付録G pytestを用いたテスト駆動開発 テスト駆動開発とは… • 自動化テストを、開発を進める(駆動する)道具として活用する • テストコードとプロダクトコードを同時に書く※ • 「レッド・グリーン・リファクタリング」のサイクルを 高速にまわす(数分単位) • 仕様、設計、実装を一連の活動として織り込む ※厳密な「テストファースト」に限らない

Slide 31

Slide 31 text

「動作するきれいなコード」、ロン・ジェフリーズのこの 簡潔な言葉が、テスト駆動開発(TDD)のゴールだ。 動作するきれいなコードはあらゆる意味で価値がある ─ Kent Beck

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

自分の 歩幅で

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

リファクタリングの対象 • コードをきれいにする • メソッド名、変数名 • インデント • コメント • 設計も見直す • プロダクトコードもテストコードも見直す • 常にやり続ける • 「動くコード」を保証するテストが前提 大

Slide 40

Slide 40 text

「きれい」? ○ きれいな部屋、きれいな机、きれいな作業スペース ×きれいな花、きれいな色、きれいな風景 • 感覚ではなく、論理的なもの • 美醜ではなく、効率や安全に関わるもの 動作するきれいなコード=clean code that works clean beautiful, aesthetic

Slide 41

Slide 41 text

なぜ「きれい」? • 読みやすさ • シンプル • 予測 • 安全 • 「動作するもっともシンプルなコード」 • 「もっともシンプル」に到達するには試行錯誤が必要 • きれい、シンプルの基準は、スキルや経験による

Slide 42

Slide 42 text

TDDは開発手法 あるある: 「あ、きみテスト駆動開発やったことあるの? じゃあテスト書けるね!」 • テスト手法ではない! • プロダクションコードを書くために、テストコードも書く • 他の手法と組み合わせて使える

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

余談: TDDのテストはテストじゃない…? • TDD=開発手法≠テスト手法 • でもテスト書いてるじゃんね • 単純な事実: TDDで書いたテストは 必要なテストすべてを 網羅しない可能性がある (網羅したかったら 網羅するように 書かないといけない) https://www.slideshare.net/goyoki/votddtdd-tdd-on-live

Slide 45

Slide 45 text

時間があれば… ライブコーディングで テスト駆動開発デモ! 時間なかったら懇親会で!

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

まとめ • pytestはとっつき易く、修得も早く、痒いところに手が届く • しかも高機能で、さまざまな拡張があり、情報も豊富 • pytestのフィクスチャは最高、知らずに死ぬのはもったいない • プログラマもテストを知るとよいし、 テストエンジニアもpytestを知るとよい • テスト駆動開発は楽しいし、開発者にとって強力なツール • リファクタリングは技術的負債の返済 = ハードな先行投資 ≠ 感覚やポリシーの話ではない • テスト駆動開発 = 開発手法 ≠ テスト手法

Slide 52

Slide 52 text

おまけ モブプロについて: アギレルゴ川口さんのHunter社見学記 • http://kawaguti.hateblo.jp/entry/2019/05/04/004855 • http://kawaguti.hateblo.jp/entry/2019/05/07/124007