Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonを使った APIサーバー開発を始める際に 整備したCIとテスト機構 / python-api-ci-test

Pythonを使った APIサーバー開発を始める際に 整備したCIとテスト機構 / python-api-ci-test

PyCon JP 2019で発表するAPIサーバー開発で始めるCI・テスト機構の話です

Kazuki Higashiguchi
PRO

September 16, 2019
Tweet

More Decks by Kazuki Higashiguchi

Other Decks in Technology

Transcript

  1. © - BASE, Inc. X
    Pythonを使った
    APIサーバー開発を始める際に
    整備したCIとテスト機構
    . . PyCon JP
    - @hgsgtk

    View Slide

  2. © - BASE, Inc.
    本⽇話すこと
    https://pycon.jp/ /sessions
    CIでのコード検査‧⾃動テストを取り上げます。

    View Slide

  3. © - BASE, Inc.
    本⽇話すこと
    CIによるコード検査‧⾃動テストの
    開発者⾃⾝にとっての メリット
    を話します。
    https://pycon.jp/ /sessions

    View Slide

  4. © - BASE, Inc.
    話すこと
    • 学習サイクル促進のためのCI導⼊‧⾃動
    テストの考え⽅
    • Pythonでのコード検査‧⾃動テスト整
    備のためのキーワード
    • コード検査‧⾃動テストから得られる
    フィードバック

    View Slide

  5. © - BASE, Inc.
    話さないこと
    • CIツールの⽐較
    • 詳細なCIの設定⽅法
    • テスティングフレームワークの⽐較

    View Slide

  6. © - BASE, Inc.
    : @hgsgtk
    Who am I?
    東⼝ 和暉 ( Higashiguchi Kazuki )
    Back-end Engineer (Go, PHP, Python )
    BASE BANK, Inc. (BASE, Inc.)
    / Dev Division / Tech Lead

    View Slide

  7. © - BASE, Inc.
    お品書き
    .CI‧コード検査/テストに対する捉え⽅
    .CI導⼊‧コード検査
    .⾃動テスト作成‧実施
    .まとめ

    View Slide

  8. © - BASE, Inc.
    お品書き
    .CI‧コード検査/テストに対する捉え⽅
    .CI導⼊‧コード検査
    .⾃動テスト作成‧実施
    .まとめ

    View Slide

  9. © - BASE, Inc.
    CI (Continuous Integration)
    • 継続的インテグレーション
    • ビルド‧テストを頻繁に繰り返し⾏うこ
    とにより、問題を早期に発⾒、開発の効
    率化‧省⼒化を図る⼿法

    View Slide

  10. © - BASE, Inc.
    CIはなぜ⼊れたい?開発の効率化‧省⼒化?
    • エラーを⼩さな単位で早期に修正するこ
    とによる、修正コストの削減
    • ex. コミット単位でコンパイル‧テス
    ト‧静的解析 …etc

    View Slide

  11. © - BASE, Inc.
    このトークでの捉え⽅:学習サイクル促進
    • 業務開発での commit‧ pushから得
    られるフィードバックを増やす
    • XXX に対するフィードバック
    • コーディング
    • コード設計

    View Slide

  12. © - BASE, Inc.
    CIで防ぎ
    CIに学ぶ

    View Slide

  13. © - BASE, Inc.
    コーディングに対するフィードバック
    • PEP ‧PEP といったコーディン
    グ‧ドキュメントスタイルを守っている

    • すべてを読み込むのは⼤変‧漏れている
    可能性もある
    • コード検査で確認し、指摘結果から学ぶ

    View Slide

  14. © - BASE, Inc.
    コード設計に対するフィードバック
    • テスト、特にユニットテストを書くこと
    で、テスタビリティの声を聞く
    • テストがしやすい‧テストがしにくいの
    肌感をフィードバックとして受ける
    • 関⼼の分離がされた疎結合なパーツが協
    調するコード設計へ

    View Slide

  15. © - BASE, Inc.
    フィードバックからすぐアクションする
    • テストで振る舞いを保護する
    • 保護されたコードの内部詳細の実装‧
    コーディングを改善していく

    View Slide

  16. © - BASE, Inc.
    お品書き
    .CI‧コード検査/テストに対する捉え⽅
    .CI導⼊‧コード検査
    .⾃動テスト作成‧実施
    .まとめ

    View Slide

  17. © - BASE, Inc.
    背景:題材事例となるアプリケーション
    • DB‧外部APIへ依存するAPIサービス
    • エンドポイントは4つほど、⽐較的⼩さ
    いがビジネスロジックを持った
    • ex. ⾦額計算などを⾏う

    View Slide

  18. © - BASE, Inc.
    様々なCIツール
    • 様々CI導⼊するためのツールがある
    • Jenkins, Travis CI, CircleCI etc
    • 本資料ではCircleCIを⽤いた事例を紹介

    View Slide

  19. © - BASE, Inc.
    CircleCI jobs 例
    https://circleci.com/gh/hgsgtk/pycon -app/tree/master

    View Slide

  20. © - BASE, Inc.
    CircleCIでのコード検査実施

    View Slide

  21. © - BASE, Inc.
    Pythonコードスタイルチェック
    • pycodestyle
    • https://pypi.org/project/pycodestyle/
    • flake
    • http://flake .pycqa.org/en/latest/
    • Pylint
    • https://www.pylint.org
    • autopep
    • https://github.com/hhatto/autopep

    View Slide

  22. © - BASE, Inc.
    コードスタイル pycodestyle
    • Pythonコードスタイルガイドチェック
    ツール
    • PEP - Style Guide for Python Code
    • https://www.python.org/dev/peps/pep- /

    View Slide

  23. © - BASE, Inc.
    pycodestyleからのフィードバック
    • Python Codeのスタイルガイドに準拠
    しているかどうかが指摘される
    • 「Pythonの標準的なコードが書けてい
    るか?」

    View Slide

  24. © - BASE, Inc.
    Pythonドキュメントスタイルチェック
    • pydocstyle
    • https://pypi.org/project/pydocstyle/

    View Slide

  25. © - BASE, Inc.
    pydocstyle
    • Pythonのdocstring規約への準拠を確
    認する静的分析ツール
    • PEP — Docstring Conventions 
    • https://www.python.org/dev/peps/pep- /

    View Slide

  26. © - BASE, Inc.
    pydocstyleからのフィードバック
    • “Code is read much more often than
    it is written” by Guido
    • 「読まれるコードドキュメントが作れて
    いるか?」

    View Slide

  27. © - BASE, Inc.
    Pythonコード型検査
    • mypy
    • http://mypy-lang.org/

    View Slide

  28. © - BASE, Inc.
    mypy
    • コード上の型を静的解析するツール
    • PEP — Type Hints
    • https://www.python.org/dev/peps/pep- /

    View Slide

  29. © - BASE, Inc.
    mypyからのフィードバック
    • 「型アノテーションを設定するコード‧
    設定に違反したコードが書かれていない
    か?」

    View Slide

  30. © - BASE, Inc.
    CI導⼊‧コード検査のまとめ
    • CIツールを⽤いる
    • コーディングスタイル‧ドキュメントス
    タイル‧型検査を実施する
    • それらからコーディングに対するフィー
    ドバックをもらう

    View Slide

  31. © - BASE, Inc.
    お品書き
    .CI‧コード検査/テストに対する捉え⽅
    .CI導⼊‧コード検査
    .⾃動テスト作成‧実施
    .まとめ

    View Slide

  32. © - BASE, Inc.
    ⾃動テスト実施の選択肢
    • テストコードを作成‧実⾏するためのテ
    スティングツールを利⽤する
    • pytest
    • https://docs.pytest.org/en/latest/
    • unittest
    • nose etc

    View Slide

  33. © - BASE, Inc.
    pytest テストコード例

    View Slide

  34. © - BASE, Inc.
    ⾃動テストでしたいこと
    • コード設計へのフィードバックを得る
    • 関⼼の分離がされた疎結合なパーツが
    協調するコード設計か
    • 既存の振る舞いを保護し、リファクタリ
    ングをスピーディにする

    View Slide

  35. © - BASE, Inc.
    そのために考えること
    .外部環境からの隔離
    .依存関係の差し替え可能なコード設計

    View Slide

  36. © - BASE, Inc.
    そのために考えること
    .外部環境からの隔離
    .依存関係の差し替え可能なコード設計

    View Slide

  37. © - BASE, Inc.
    そのために考えること(1):外部環境からの隔離
    • テストスコープを対象アプリケーション
    内に留めたい
    • 対象外(ex. 外部APIなど)を含めた場
    合ネットワーク状態などに依存し不安定
    なテストになりうる

    View Slide

  38. © - BASE, Inc.
    背景:アプリケーション構造(概要)
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic

    View Slide

  39. © - BASE, Inc.
    (補⾜)背景:アプリケーション詳説
    • HTTP Handler: aiohttp
    • Asynchronous HTTP Client/Server
    for asyncio and Python.
    • http://docs.aiohttp.org/en/stable/
    • Database Access: sqlalchemy
    • The Python SQL Toolkit and Object Relational
    Mapper
    • https://www.sqlalchemy.org/

    View Slide

  40. © - BASE, Inc.
    テスト⽤ライブラリを活⽤する
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic
    pytest-aiohttp
    • pytest plugin for aiohttp
    • 擬似的なリクエストを再現
    • https://github.com/aio-libs/pytest-
    aiohttp

    View Slide

  41. © - BASE, Inc.
    テスト⽤ライブラリを活⽤する
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic
    kevin /vcrpy
    • 実⾏されたHTTPリクエスト/レスポンス
    を記録‧再⽣する
    • https://vcrpy.readthedocs.io/en/
    latest/

    View Slide

  42. © - BASE, Inc.
    テスト⽤ライブラリを活⽤しないもの
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic

    View Slide

  43. © - BASE, Inc.
    テスト⽤ライブラリを活⽤しないもの
    • データベースへの問い合わせをモックす
    るかどうか
    • たとえば、Goでは DATA-DOG/go-
    sqlmock という実⾏されるSQLが期待
    通りかを検証するモックを作成する⽅法
    がある
    • https://github.com/DATA-DOG/go-sqlmock

    View Slide

  44. © - BASE, Inc.
    モックに置き換えるかどうか
    • ⻑所は、テストの速度‧安定度
    • ⼀⽅、短所は、統合した際に期待通り動
    作するという安⼼感
    • ex. SQLが本当に正しい?

    View Slide

  45. © - BASE, Inc.
    結果的に⾏った施策
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic
    • テスト⽤DBを作成する
    (本例ではコンテナ)

    View Slide

  46. © - BASE, Inc.
    テスト⽤DBを作成する

    View Slide

  47. © - BASE, Inc.
    テスト⽤DBを利⽤する
    ※ スキーマ‧フィクスチャ管理については時間の都合上‧‧‧

    View Slide

  48. © - BASE, Inc.
    「外部環境からの隔離」のフィードバック
    • テスト⽤ライブラリで外部環境との接点
    を差し替えれる
    • ⼀⽅で、すべてのテストケースでこれら
    で差し替えるようなコードの場合、疎結
    合なコード設計になっていない可能性を
    ⽰唆

    View Slide

  49. © - BASE, Inc.
    そのために考えること
    .外部環境からの隔離
    .依存関係の差し替え可能なコード設計

    View Slide

  50. © - BASE, Inc.
    背景:アプリケーション構造(概要)
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic

    View Slide

  51. © - BASE, Inc.
    背景:アプリケーション構造(概要)
    外部
    API
    DB
    HTTP
    REQUEST
    HTTP
    Handler
    Database
    Access
    Inside API Application
    API
    Client
    Domain
    Logic
    たとえば、HTTP Handlerのテストをするのに
    DB‧外部APIすべてライブラリで差し替えるの
    は「前準備のコスト」が⾼い

    View Slide

  52. © - BASE, Inc.
    依存関係の差し替え可能なコード設計
    • 依存関係をなるべく差し替え可能へ
    • DI(Dependency Injection: 依存関係の
    注⼊)可能な設計へ

    View Slide

  53. © - BASE, Inc.
    DI可能にする
    constructorからオブジェクトを受け付ける

    View Slide

  54. © - BASE, Inc.
    DI可能にする
    テスト時には仮の値を返すテストダブルに置き
    換える
    ※ テストダブル: テスト固有の同等物(ex. スタブ‧モック)

    View Slide

  55. © - BASE, Inc.
    依存関係の差し替え⼿段
    • ⾃分でテスト⽤の代替クラスを作成
    • モックライブラリ利⽤
    • pytest-mock
    • https://pypi.org/project/pytest-mock/
    • spy, stub, mockが可能

    View Slide

  56. © - BASE, Inc.
    「依存関係の差し替え可能なコード設計」
    のフィードバック
    • テストの前準備のコスト‧実⾏速度が、
    疎結合なコード設計へ⽬を向けるきっか
    けへ

    View Slide

  57. © - BASE, Inc.
    おまけ 〜⾃動テストの維持のために〜
    • pytest-randomly で不安定なテストに
    気づく
    • https://pypi.org/project/pytest-randomly/
    • 実⾏順に依存するテストは、⼀般的に不安定な
    テストと呼ばれる、⾃動テスト維持にはデメ
    リットになる
    Refs: “Pythonでの開発を効率的に進めるためのツール設定” at PyCon
    JP by @aodag さん
    https://www.slideshare.net/aodag/python-

    View Slide

  58. © - BASE, Inc.
    お品書き
    .CI‧コード検査/テストに対する捉え⽅
    .CI導⼊‧コード検査
    .⾃動テスト作成‧実施
    .まとめ

    View Slide

  59. © - BASE, Inc.
    まとめ
    • CIを回すことで継続的なフィードバック
    環境を作る
    • コード検査からコーディングを、テスト
    からコード設計へのフィードバックをも
    らう

    View Slide

  60. © - BASE, Inc.
    まとめ
    • コード検査‧⾃動テストなどはある種
    「⾯倒だけどやったほうが良いこと」と
    捉えられがち
    • 開発者にフィードバックをくれるものと
    捉えて、「前向き」な捉え⽅をする⼀つ
    のアイデアでした

    View Slide