【CI/CD 第3話】Github Actionsによる自動テスト
こんにちは。
前回はGithub Actionsに利用するワークフローファイル(YAMLファイル)を作成し、Github Actionsをサンプル実行しました。
今回はThe CI/CDと私が勝手に思っている自動テストを試したいと思います。
CI(継続的インテグレーション)
自動テストの検証をする前にCI(継続的インテグレーション)の定義を復習しておきます。
上記の「正しく動作するか繰り返し検証する」ための一つの要素として自動テストがあると考えています。
あとは静的テストも一般的にあるようですが、今回は対象外とします。
自動テスト
では早速自動テストを試していきたいと思います。
今回は偶数か奇数かを判断する関数を作成し、自動テストの対象としたいと思います。
ディレクトリ構成
今回は下記のようなディレクトリ構成といたします。
my_project/
├── .github/
│ └── workflows/
│ └── test.yml
├── src/
│ └── is_even_or_odd.py
└── tests/
└── test_is_even_or_odd.py
簡単に上記のディレクトリ構成を説明します。
.github/
Github Actionsの設定を格納
src/
実装コードを格納
tests/
テストコードを格納
テストコードはtest_hogehoge.pyのように先頭にtest_をつけるのが一般的のようです。
リモートリポジトリの作成
それでは実際に上記ディレクトリ構成通りのプロジェクトを作成し、コードを書いていきます。
terminal上でGithub CLIを用いてリモートリポジトリ(is_even_or_odd)を作成します。
gh repo create is_even_or_odd --public --clone --add-readme
実装コードの作成
次に実装コードを作成します。
まずはsrcディレクトリを作成します。
mkdir src/
次にis_even_or_odd.pyファイルを作成します。
touch src/is_even_or_odd.py
これでsrc/is_even_or_odd.pyが作成されたのが確認できます。
次に実際にコードを記載します。
今回のコードでは入力された数字が偶数の場合は"even"、奇数の場合は"odd"と返します。
def is_even_or_odd(number):
"""
Determines if a number is even or odd.
:param number: int
:return: "even" if number is even, "odd" if number is odd
"""
if not isinstance(number, int):
raise ValueError("Input must be an integer")
return "even" if number % 2 == 0 else "odd"
テストコードの作成
続きまして、テストコードを作成しましょう。
pythonファイルのテストとしてはpytestが有名っぽいのでこちらを利用します。
pytestの基本的な使い方は下記がわかりやすかったです。
実装コードと同様にtest/ディレクトリを作成します。
mkdir tests/
次にテストファイルを作成します。
touch tests/test_is_even_or_odd.py
テストファイルの中身は以下とします。
import pytest
from src.is_even_or_odd import is_even_or_odd
def test_is_even_or_odd():
assert is_even_or_odd(2) == "even"
assert is_even_or_odd(3) == "odd"
assert is_even_or_odd(0) == "even"
assert is_even_or_odd(-2) == "even"
assert is_even_or_odd(-3) == "odd"
現在のディレクトリ構成は以下。
では実際にテストコードを動かしてみましょう。
私のSagemaker CodeDditor実行環境にpytestがなかったので、まずはインストール。
pip install pytest
続いてPython が src ディレクトリをモジュールとして認識できるようにPYTHONPATH 環境変数を設定。
export PYTHONPATH=$(pwd)
※ちなみに現在の実行場所は以下です。。
それでは準備が整いましたのでpytestを実行します。
pytestの使用方法は省略しますが、ディレクトリを指定して実行できます。
pytest tests
pytestを使ったことはない人は何がなんやらですが、無事にテストを通過しています!(一番下に"1 passed"と緑の文字で表示されてるので察して下さい、、、)
ワークフローファイルの作成
最後にGithub Actionsを実行するためのワークフローファイルを作成します。
いつものように.github/workflowsフォルダを作成。
mkdir -p .github/workflows/
ワークフローファイルを作成。
touch .github/workflows/test.yml
現在のディレクトリ構成は以下。
では、test.ymlの中身を書いていきたいと思います。
# ワークフロー名を指定
name: Python Tests
# トリガー条件を指定
on:
push: # コードがプッシュされたときに実行
branches:
- main # main ブランチへのプッシュが対象
pull_request: # プルリクエストが作成されたときに実行
branches:
- main # main ブランチに対するプルリクエストが対象
# ジョブを定義
jobs:
test: # ジョブ名を "test" に設定
runs-on: ubuntu-latest # テストを実行する環境を Ubuntu 最新バージョンに設定
steps:
# 1. リポジトリのコードをチェックアウト
- name: Check out code
uses: actions/checkout@v3 # GitHub の公式アクションを使用してリポジトリのコードを取得
# 2. Python をセットアップ
- name: Set up Python
uses: actions/setup-python@v4 # GitHub の公式アクションを使用して Python をセットアップ
with:
python-version: '3.9' # 使用する Python のバージョンを指定
# 3. 必要な依存関係をインストール
- name: Install dependencies
run: | # シェルコマンドを実行
python -m pip install --upgrade pip # pip を最新バージョンにアップグレード
pip install pytest # テストフレームワーク pytest をインストール
# 4. テストを実行
- name: Run tests
run: |
# PYTHONPATH にプロジェクトのルートディレクトリを設定してから pytest を実行
PYTHONPATH=$(pwd) pytest tests # カレントディレクトリを PYTHONPATH に設定し、tests ディレクトリ内のテストを実行
上記コードの細かい説明は省略いたします。。
Github Actionsの実行
全ての準備が整いましたので、Github Actionsを実行しましょう。
Githubのリモートリポジトリにpushいたします。
git add .
git commit -m "even_or_odd test"
git push -u origin main
Githubの"Actions"を確認するとワークフローが実行され正常完了されていることが確認できます。
中身を細かくチェックするとtestもしっかりと完了していることが確認でいますね。
まとめ
CIの定義を再確認した。
自動テストを行うにあたり、実装コードとテストコードを作成し、pytestにより動作確認した。
自動テストを組み込んだワークフローファイルを作成した。
Github Actionsを実行し自動テストが完了することを確認した。
以上でGithu Actionsのお試しは終わりです。
細かい機能なでは全く試せていませんが基本的な動作は確認できました。
応用例も必要に応じて記事にしていけたらと思います。