GitHub ActionsでPythonのテスト自動化

GitHubが提供するCIツール、GitHub Actionsの基本的な使い方を解説します。


GitHub Actionsとは?

GitHub Actionsとは 公式ドキュメント によると

GitHub Actions は、ソフトウェア開発ライフサイクル内のタスクを自動化するのに役立ちます。 GitHub Actions はイベント駆動型で、指定されたイベントが発生した後に一連のコマンドを実行できます。 たとえば、誰かがリポジトリのプルリクエストを作成するたびに、ソフトウェアテストスクリプトを実行するコマンドを自動的に実行できます。

と説明されています。

GitHubへソースコードをPushした時や、masterブランチへmergeしたタイミングで、テストを走らせたりデプロイしたりすることができる仕組みになります。

イメージとしては、トリガーになるイベントが発生すると、複数ステップ(コマンドで実行されるタスク)をまとめたいくつかのジョブが順番に実行されます。この一連の流れをワークフローと言います。


今回は、GitHubのリポジトリにPushしたタイミングてPythonのテストコードが自動実行されるようにしてみいます。


GitHubアカウントの準備

GitHubのアカウントがない人は作成してください。

👉 GitHub 登録


リポジトリの作成

GitHub Actions用のリポジトリを作成します。右上 + のメニューから「New repository」を押して作成します。


リポジトリ名とリポジトリの説明、可視性について記載し作成したら、クライアント側でCloneしておきます。


ymlファイルの作成

Cloneしたフォルダ内に .github/workflows というディレクトリを作り、そこにymlファイルを作成します。今回はGitHubが公開しているサンプルをそのまま使います。記載するとその意味は以下の通りです、

  • name: xxxxx この一連のジョブ実行、ワークフローの名前を定義します。
  • on: [xxxx] トリガーになるイベントを記載します。今回は push にします。
  • jobs: このワークフローのjobをすべて1つにまとめます。
  • runs-on: どの環境でジョブが実行されるか記載します。今回は ubuntu-latest とします。
  • python-versions: [xxxx] Pythonのバージョンを指定します。
  • step: 実行するアクションを書きます。
  • name: stepの中に記載されているnameはアクションの名前です。
  • run: アクションで実行するコマンドを記載します。
  • uses: はあらかじめGitHub側が作成しているactionsを実行すること表しています。今回の actions/checkout@v2 はチェックアウトを意味しています。
name: python-test

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.8]

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install flake8 pytest
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
    - name: Lint with flake8
      run: |
        # Python 構文エラーまたは未定義の名前がある場合はビルドを停止する
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zeroはすべてのエラーを警告として扱う。 GitHubのエディタの幅は127文字
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      run: |
        pytest

テストコードを作成

mainというディレクトリをつくりmain.pyという名前のファイルに以下のコードを記載します。

class Car:
    def __init__(self, name='Banana', amount=10_000_000):
        self.car_name = name
        self.car_amount = amount

    def car_display_price(self):
        return f'{self.car_amount:,}円'


test_main.pyと言う名前のファイルに以下のコードを記載します。

from main.main import Car

def test_add_01():
    car = Car()
    assert car.car_display_price() == '10,000,000円'


def test_add_02():
    car = Car(amount=30_000_000)
    assert car.car_display_price() == '30,000,000円'


念の為、ローカル環境で `pytest` コマンドで正しく動くか確認します。


ワークフローの実行

上記のとおり作成したymlファイル、main.pyファイル、test_main.pyファイルをcommit, pushします。

GitHubのActionsタブからワークフローの実行ステータスと、結果を確認することができます。緑色のチェックが付いているので問題なさそうです。

また、該当のワークフローを選択し、詳細を確認することができます。テストが問題なく実行されたことがわかります。


失敗した時の挙動

わざとTestが通らないようなコードに変更してみます。main.pyを以下のように書き換えます。

class Car:
    def __init__(self, name='Banana', amount=10_000_000):
        self.car_name = name
        self.car_amount = amount

    def car_display_price(self):
        return f'{self.car_amount:,}' # 円を削除した

テストコードは変えずに同じようにcommit, pushします。すると、GitHub Actionsのほうのでは失敗したことが確認できます。

同じように詳細をみてみると、なぜTestが通らなかったのか、確認することができます。


以上が、GitHub ActionsでPythonのテストコードを動かす基本的な流れです。
ymlファイルを作成しただけでテストコードを動かせるので本当に便利です。ぜひ、活用してみてください。


このエントリーをはてなブックマークに追加