github actionsを使って、python のpytest、flake8などの試し

# はじめに
[Github Actionsの話](https://qiita.com/Guan21/items/f36130c3ecab9058c0e4)で、ブランチによる、トリガーの設定を試した。今回はpythonの自動テストを試したいとおもいます。二つ方法で実装したため、dockerの仮想環境 とgithubのubuntu環境の実行に対して、シミュレーションします。

# Target
- Github Actions でdocker-compose exec -T app pipenv run pytest、flake8の実行ができること
- ubuntu環境で pytest、flake8の実行ができること
- dockerの仮想環境 とgithubのubuntu環境に対して、シミュレーション
- その他


# 共通のテストファイル

簡単に以下のテストファイルを作成しました。

~~~test.py
def test_sample1():
    """add test """
    assert True
~~~

# Docker仮想環境

~~~pipenv.yml
name: dockerPipenv

on: [push]

jobs:
  DockerComposePytest:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: docker Build
      run: docker-compose build
    - name: Docker Compose Up
      run: docker-compose up -d
    - name: Pipenv Run Pytest
      run: docker-compose exec -T flask_app pipenv run test
    - name: Pipenv Run Lint
      run: docker-compose exec -T flask_app pipenv run lint
~~~

これはgithubの仮想環境の中に、dockerの仮想環境を構築し、testとlintを実行する感じです。

~~~bash.sh
=============================== test =======================================
Run docker-compose exec -T flask_app pipenv run test
  docker-compose exec -T flask_app pipenv run test
  shell: /usr/bin/bash -e {0}
============================= test session starts ==============================
platform linux -- Python 3.10.7, pytest-7.1.3, pluggy-1.0.0
rootdir: /service/flask_app
collected 1 item

modules/tests/test_util.py .                                             [100%]

============================== 1 passed in 0.01s ===============================

=============================== lint =======================================
Run docker-compose exec -T flask_app pipenv run lint
  docker-compose exec -T flask_app pipenv run lint
  shell: /usr/bin/bash -e {0}

~~~
無事に実行できた。


# ubuntu 環境

### ubuntu pytest

まずは、actionファイルは以下のようです。

~~~pytest.yml
name: pythonPytest

on: [push]

jobs:
  PythonPytest:
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python 3.10
      uses: actions/setup-python@v3
      with:
        python-version: '3.10'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pytest
        pip install flake8
        pip install Flask
        pip install Flask-WTF
        pip install pydocstyle
        pip install pyflakes
    - name: Analysing the code with pylint
      run: |
        ls -l
        flake8 source/
        pytest -vs
~~~

この感じで、直接にpython3.10のパッケージpytestとflake8などをにインストールすることですね。


~~~bash.sh
============================= test session starts ==============================
platform linux -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0 -- /opt/hostedtoolcache/Python/3.10.6/x64/bin/python
cachedir: .pytest_cache
rootdir: /home/runner/work/python_pipenv_test/python_pipenv_test
collecting ... collected 1 item

source/modules/tests/test_util.py::test_sample1 PASSED

============================== 1 passed in 0.01s ===============================

~~~

実行結果：無事にflake8とpytestを実行しましたね。

### ubuntu pipenv

アプリのパッケージバージョンを管理するため、以下のPipfileを作成しました。

~~~Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
Flask = "==2.1.0"
mod-wsgi = "==4.9.1"
Flask-WTF = "==0.15.1"
requests = "==2.26.0"

[dev-packages]
flake8 = "*"
pydocstyle = "*"
pyflakes = "*"
flake8-isort = "*"
isort = "*"
autopep8 = "*"
pytest = "*"

[requires]
python_version = "3.10"

[scripts]
lint = "flake8 /service/flask_app "
lint-fix = "bash -c 'isort /service/flask_app && flake8 /service/flask_app | cut -d: -f1 | sort | uniq | xargs autopep8 -i'"
test = "pytest"
~~~

github actionsファイルは以下でございます。

~~~pythonPipenv.yml
name: pythonPipenv

on: [push]

jobs:
  PythonPipenv:
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python 3.10
      uses: actions/setup-python@v3
      with:
        python-version: '3.10'
    - name: Install dependencies mod-wsgi
      run: |
       ★ sudo apt-get -y install --no-install-recommends libaio1
       ★ sudo apt-get -y install apache2 apache2-dev
    - name: Install dependencies pipenv
      run: |
        cp source/Pipfile Pipfile
        python -m pip install --upgrade pip
        pip install pipenv
        pipenv install --skip-lock --dev
    - name: Analysing the code with pylint again
      run: |
        pipenv run pytest -vs
        pipenv run flake8 source/
~~~

上記の★の部分を見てください。Pipfileの中に、依存関係があるパッケージのインストールが必要な場合、[Pipfile]をinstallする前に、やるべきです。
あと、apt-getの際に「sudo」を追加しないと以下のエラーがでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518634/3d176e69-8096-14b7-ddd1-e37472c9f6d2.png)

~~~bash.sh
============================= test session starts ==============================
platform linux -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0 -- /home/runner/.local/share/virtualenvs/python_pipenv_test-ulorymQ-/bin/python
cachedir: .pytest_cache
rootdir: /home/runner/work/python_pipenv_test/python_pipenv_test
collecting ... collected 1 item

source/modules/tests/test_util.py::test_sample1 PASSED

============================== 1 passed in 0.01s ===============================
~~~

実行結果：無事にpytestとflake8を実行しましたね。

# シミュレーション
## Docker仮想環境
### メリット
 - 商用環境と同じ環境で実行するため、信頼感がベスト
 - dockerのお掛けて、local環境、自動テスト環境、開発検証環境、商用環境の一元管理ができる
 - 複数コンテナの接続テスト場合、おすすめです。
### デメリット
 - 実行時間が遅い、2m24s
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518634/282a7b56-1bd8-4541-4f04-4ca5c2960a99.png)


## ubuntu pytest
### メリット
 - 実行時間が一番早い。32s
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518634/0332ed2c-d52d-d9ef-6d06-6627cf5ac9e7.png)
 - 環境設定が不要、テスト必要なパッケージをインストールだけ

### デメリット
 - local環境のpytest、flake8などパッケージバージョン変更がある場合、pytest.ymlの手動修正が必要かも

## ubuntu pipenv
### メリット
 - 実行時間がubuntu pytestによる、遅いけど、dockerより早い。59s
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518634/f36a4e5f-310c-695f-8b99-7c296362cc61.png)
 - Pipfileのお掛けて、local環境、自動テスト環境、開発検証環境、商用環境の利用するパッケージを一元管理することができるし、インストールはわざわざインストールしなくてもよい。

### デメリット
 - Pipfileのパッケージが外部依存がある場合、手動対応が必要です。「★」の部分

# その他
~~~test.py
~~~
上記の感じで、test.pyファイル中に、テスト関数がない場合、以下のエラーを出るので、気になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518634/efc75be2-9839-40f7-105b-86d787748be7.png)
普段はテストが通ったが、ただ、テストパータンがないため、成功と言えないですね。真面目だよね。

# まとめ
現在のＷＥＢ業界はアジャイル開発の実施と伴う、開発スピードを求めている背景で、（特にＳＲＥのGuidelinesを基づいて、自動化するべきであることで）今後の開発は以下のようにした方がよいかも。
- 開発環境は「ubuntu pipenv」を利用する。
- 商用環境にリリースする際に、「Docker仮想環境」を利用する。

※補足記事を追加しましたので、良かったら参考してください。

https://qiita.com/Guan21/items/43c87f41a12daef7f82e