Skip to content

Instantly share code, notes, and snippets.

@shinseitaro
Last active August 23, 2023 02:36
Show Gist options
  • Save shinseitaro/09d38dd19207fe2f0374b25c6a10d49f to your computer and use it in GitHub Desktop.
Save shinseitaro/09d38dd19207fe2f0374b25c6a10d49f to your computer and use it in GitHub Desktop.
gistpad-scratch

【ハンズオン】pytestを自動化してみよう

ハンズオン内容

  • 第1部:tox でテストの自動化、Github Actionsを使ってプッシュと同時にGithub上でテストを実行
  • 第2部:Issue の課題を解決し、Pull Requestとつなげてマージと同時にテストを行う
  • 次回以降:フォーク元の Issue を解決し Pull Request を建ててマージしてもらう

前回までの資料

参考資料

第1部:tox でテストの自動化、Github Actionsを使ってプッシュと同時にGithub上でテストを実行

環境構築

memo:4月の勉強会で fork したものをそのまま使いたい方は、📌 マークが付いているところだけを更新すればよいと思います。

  1. fork
    1. https://github.com/fin-py/connpass-client/fork でフォークする
    2. forkしたリポジトリで Settings -> Actions -> General のページで Workflow permissions へ移動
    3. Read and write permissionsAllow Github Actions to create and approve pull requests を選択して Save
    4. 📌 フォークしたレポジトリは、Issue機能がデフォルトでOFFになっています。Settings > General > Features で、 Issues に✔を入れてONにしてください
    • 詳細は前回資料の 環境構築を見てください。
  2. ローカル開発環境構築
    # フォークした自分のレポジトリを git clone
    git clone [email protected]:YOUR-GITHUB-ACCOUNT/connpass-client.git
    cd connpass-client
    
    python -m venv .venv
    source .venv/bin/activate
    
    pip install -U pip
    pip install . pytest tox coverage pytest-cov "genbadge[coverage]" # 📌

tox

  1. tox.ini 新規作成

    touch tox.ini
  2. Pythonのバージョンを確認

    python -V
  3. tox 記述

    tox.ini

    [tox]
    envlist = py38 
    isolated_build = True 
    
    [testenv]
    deps = 
        pytest
        faker        
    commands = pytest
    • tox: python のための仮想環境管理およびテストツール。バージョン管理、依存関係の解決、テスト実行、スタイルチェック、静的解析、カバレッジ測定などのタスクを実行する。異なる環境でもOK。CIプラットフォームの一部としてよく用いられる。
    • envlist = py38 : 先に確認したPythonのバージョンを指定
    • isolated_build = True : ビルド用の仮想環境を作成してその中でビルドする。ビルドの再現性を確保。
    • deps = : テストを実行するために必要な依存パッケージを指定。これらのパッケージがテスト環境でインストールされる
    • commands = pytest: テストを実行するコマンド
  4. tox 実行

    • tox でテストが実行できることを確認
    tox
    
    py39: install_deps> python -I -m pip install faker pytest
    .pkg: install_requires> python -I -m pip install poetry-core
    
    ... 
                                                                                                                                                         
    tests/test_sample.py .              [100%]

Github Actionsをつかってtoxを実行する

  1. .github/workflows 新規作成

    mkdir -p .github/workflows
  2. workflow yaml file 新規作成

    touch .github/workflows/tox-demo.yml
  3. ワークフローを記述

    name: tox demo
    
    on:
        push:
            branches: [ main ]
        pull_request:
            branches: [ main ]
    
    jobs:
        test:
            runs-on: ubuntu-latest
            steps:
                - name: Checkout repository
                  uses: actions/checkout@v2
    
                - name: Set up Python
                  uses: actions/setup-python@v2
                  with:
                    python-version: 3.8 # tox で指定したpythonに合わせる
    
                - name: Install tox
                  run: pip install tox
    
                - name: Run tox
                  run: tox
    
  4. add / commit / push する

  5. Github のレポジトリにいって、Actions を確認

第2部:Issue の課題を解決し、Pull Requestとつなげてマージと同時にテストを行う

第1部の内容を利用して、例えば以下のような開発環境を整えることができます。

  1. バグや機能強化などのIssueを建てる
  2. その Issue の Branch を作成
  3. Branch を fetch してローカルで課題を解決して、テストを行う
  4. Branch を Push
  5. Pull Requestを作成するタイミングでGithub Actionsを使ってテストを行う
  6. BranchをMainにマージ

Issue を立てる

  1. 練習用Issueを作成
    • 練習Issue
      タイトル:test for get method
      
      内容:ConnpassClient().get(event_id="266898") で得ることができる辞書のキーは、
          ['results_start', 'results_returned', 'results_available', 'events'] 
          であることを確認するテストを書く
      
  2. 作成した Issue で、Development > Create a branch
  3. Branch nameRepository destination を確認して、 Checkout locally のまま Create Brance
  4. Checkout in your local repository に従ってローカルにブランチをフェッチする

テスト作成

  1. 先程作ったブランチで作業
  2. tests/test_sample.py
    def test_data_keys():
        data = ConnpassClient().get(event_id="266898")
        res = set(data.keys())
    
        assert res == set(
            ["results_start", "results_returned", "results_available", "events"]
        )
  3. ローカルで tox を実行してテストを確認
  4. add / commit / push
    • 【確認】main ブランチにプッシュしたわけではないので、GAでテストは走らない

Pull Request 作成

  1. レポジトリの Pull requests に行く
  2. Compare & pull request で、Pull Request を作成。
    • デフォルトではマージ先が fin-py/connpass-client になっているので、自分のレポジトリに変更
    • 適当なメッセージを書いて、Create pull request

Merge pull request

  • 無事プルリクエストが終わるとIssueもCloseしていることを確認

演習

  1. 現在の tox-demo.ymlでは mainブランチにPushする、もしくはプルリクエストするタイミングだけでテストが走る設定になっています。これを、Pushしたときは常にテストが走る設定に変更してください。
    • ヒント: ブランチを指定しなければ全てのPushでワークフローが実行されます
  2. 第2部の内容を以下のテストでおさらいしましょう。
    内容: ConnpassClient().get(event_id="266898") で得ることができる辞書の 
           `results_returned` キーの値は、`events` の配列データ数と一致することを確認するテストを書く
    def test_results_returned():
       an_event_data = ConnpassClient().get(event_id="266898")
       assert an_event_data["results_returned"] == len(an_event_data["events"])

フォーク元の Issue を解決し Pull Request を建ててマージしてもらう

(次回以降の予定なのでまだ未完成です)

upsteam として fork 元のリポジトリ( https://github.com/fin-py/connpass-client/fork )を登録

  1. 現在のブランチを確認
    git branch -a 
        * main
        remotes/origin/HEAD -> origin/main
        remotes/origin/coverage
        remotes/origin/main    
    
  2. 現在の remote レポジトリの確認
    git remote -v
    origin  [email protected]:YOUR-NAME/connpass-client.git (fetch)
    origin  [email protected]:YOUR-NAME/connpass-client.git (push)
  3. upstream という名前で fork 元(fin-py / connpass-client)を登録
    git remote add upstream [email protected]:fin-py/connpass-client.git
    【確認】 ssh じゃない人は https://github.com/shinsei-taro-test/connpass-client.git ??
  4. remote レポジトリの確認
    git remote -v
    
        origin	[email protected]:YOUR-NAME/connpass-client.git (fetch)
        origin	[email protected]:YOUR-NAME/connpass-client.git (push)
        upstream	[email protected]:fin-py/connpass-client.git (fetch)
        upstream	[email protected]:fin-py/connpass-client.git (push)
  5. fetch upstream
    git fetch upstream
    
        remote: Enumerating objects: 4, done.
        remote: Counting objects: 100% (2/2), done.
        remote: Total 4 (delta 2), reused 2 (delta 2), pack-reused 2
        Unpacking objects: 100% (4/4), 844 bytes | 844.00 KiB/s, done.
        From github.com:fin-py/connpass-client
        * [new branch]      coverage   -> upstream/coverage
        * [new branch]      dev_test   -> upstream/dev_test
        * [new branch]      main       -> upstream/main
  6. ブランチを確認
    git branch -a
        * main
        remotes/origin/HEAD -> origin/main
        remotes/origin/main
        remotes/upstream/coverage
        remotes/upstream/dev_test
        remotes/upstream/main
  7. main ブランチに、upstream/main をマージ 📌
    git checkout main  
    git merge upstream/main
@drillan
Copy link

drillan commented Jun 19, 2023

Settings > Features

Settings > General > Features
のほうが探しやすいと思います

git clone https://github.com/YOUR-REPOSITORY/connpass-client

sshのほうがよいかも、 YOUR-REPOSITORYYOUR-GITHUB-ACCOUNT ですかね

[email protected]:YOUR-GITHUB-ACCOUNT/connpass-client.git

source .venv/bin/activate

Windowsユーザもいるかもしれないので
https://www.python.jp/install/windows/venv.html

envlist = py38 : 仮想環境で作ったPythonのバージョンに合わせる。

activateした後に
python -V で確認するコマンドを入れておくとよさそう

on:
push:

push ではく、 pull_request にしておくと、PR時にテストが走ります

Checkout in your local repository に従ってローカルにブランチを作る

すでにできてるので
作る -> フェッチする
のほうがよさそう

add / commit / push
【確認】main ブランチにプッシュしたわけではないので、GAでテストは走らない

  • ブランチ名はissueで作ったブランチ名であることを書いておくとよいかも
  • コミットメッセージにissue番号( #1 など)を含めておくとよいかも

無事プルリクエストが終わるとIssueもCloseしていることを確認

もし、 on: pull_request: してるなら、プルリク時にテストが走るはずです

image

@shinseitaro
Copy link
Author

複数バージョン でテストしたい場合

https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-python

[testenv]
deps = 
    pytest
    faker
commands = pytest
name: tox demo
on:
    push:
        branches: [ main ]
    pull_request:
        branches: [ main ]

jobs:
    test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            python: ["3.10", "3.11"]
        steps:
            - name: Checkout repository
              uses: actions/checkout@v2

            - name: Set up Python
              uses: actions/setup-python@v2
              with:
                python-version: ${{ matrix.python }}

            - name: Install tox
              run: pip install tox

            - name: Run tox
              run: tox -e py

@drillan さんありがとうございます!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment