pipenvとtoxでpytestをやってみました

# やりたいこと
・各ローカル環境の違いによって、PCが変わったらpythonがあれこれ足りなっかたりうまく実行できなくなったりする問題を解決するため、pipenvを導入
・toxでテストの自動化をする

# 前提
・Pythonインストール済み
（今回はpython3.12でやっていきます）
・pipインストール済み

# ディレクトリ構成
```ruby:
root 　　   
  ┣━ functions
      ┗━ api
          ┗━ app.py
  ┣━ tests
      ┣━ conftest.py
      ┗━ test_app.py
  ┣━ Pipfile
  ┣━ Pipfile.lock
  ┗━ tox.ini
```


# やり方
### pipenvのインストール
```ruby:
pip install pipenv
```
### Pipfileの作成
いろんな理由でPipfileがrequirements.txtより便利と思うので、今回はrequirements.txtを作らず、直接Pipfileを作成した～
あくまでも一例ですが、今回自分の環境に必要なものは以下でした。。。

[[source]]：ここからライブラリを落としてくる
[dev-packages]：dev環境のみ必要なライブラリ
[packages]：すべての環境で必要なライブラリ
[requires]：pythonのバージョン
[scripts]：lintなどその他必要なもの

※バージョン指定したい場合はバージョンを記入し、指定しない場合は*を記入する


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

[dev-packages]
pytest = "*"
pytest-mock = "*"
pytest-cov = "*"
pytest-env = "*"
pytest-testdox = "*"
coverage = "*"
tox = "*"
flake8 = "*"
autopep8 = "*"
freezegun = "*"

[packages]
requests = "==2.31.0"
cerberus = "*"
pytz = "*"
boto3 = "*"
moto = "==4.2.11"

[requires]
python_version = "3.12"

[scripts]
lint = "flake8 --show-source functions"
fix = "autopep8 -ivr functions"

```
### pipenvの作成
rootで、以下のコマンドを実行する
今回はdev環境を作るので、--devをつける
```ruby:
pipenv install --dev
```
このコマンドを実行することで、Pipfile.lockは自動で作られるはず

### tox.iniの作成
今回はテスト環境に、python3.12とflake8を使用る～

[tox]：テスト環境に何を使うかを記入（pythonのバージョンなど）
[testenv:py312]：pythonの環境変数、python関連の実行コマンド（今回はpipenv環境の更新とpytest実行）
[testenv:flake8]：flake8関連の実行コマンド
[pytest]：テスト時dummyの環境変数、pytest実行対象のパスやファイル名
[flake8]：flake8関連の設定

```ruby:tox.ini
[tox]
envlist = py312,flake8
skipsdist = True
setupdir = .

[testenv:py312]
passenv = CI*,AWS_DEFAULT_REGION,GITLAB_DYNAMO_DB_HOST
setenv =
    LOG_LEVEL=DEBUG
    DYNAMO_DB_HOST={env:GITLAB_DYNAMO_DB_HOST:http://localhost:8000}
deps = pipenv
commands =
    - pipenv sync --dev
    pytest --showlocals --junitxml=junit.xml --cov-report=html:htmlcov --cov-report=term --cov=functions -s
    
[testenv:flake8]
basepython = python3.12
deps = flake8
commands = flake8 --show-source --tee --output-file=flake8.txt functions tests
[pytest]
addopts = --force-testdox
looponfailroots = tests
python_files = test_*.py tests.py
junit_family = xunit2
env =
    D:DYNAMO_DB_HOST=http://localhost:8000
    DYNAMO_TABLE_NAME = 'auth_table'

[flake8]
max-line-length = 180
max-complexity = 10
import-order-style = google
application-import-names = flake8tox

```
### toxの実行
rootで以下のコマンドを打つと、PCのローカルではなく作れたpipenvの環境内でpytestを実行し、flakeでソース文のチェックを実行する
```ruby:
pipenv run tox
```
まずはtox内に定義されたpythestコマンドが実行される
（今回はapp.py以外のソースも一緒にテストしたので、いったんモザイク対応）
```ruby:
pytest --showlocals --junitxml=junit.xml --cov-report=html:htmlcov --cov-report=term --cov=functions -s
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/4d0bb544-b12a-c555-0639-7ea05279342e.png)
次に、flakeでのチェックが実行される
「この書き方はよくないよ」っていろいろ言ってくるね～
```ruby:
flake8 --show-source --tee --output-file=flake8.txt functions tests
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/8662a26f-1785-7ad2-48b2-a8dc19de2744.png)


# 参照サイト
https://majisemi.com/topics/oss/4037/#tox%E3%81%AE%E3%80%8C%E6%A6%82%E8%A6%81%E3%80%8D

https://qiita.com/tamazoo/items/9fc0dfda3c583583c402#pipfile

https://python.civic-apps.com/difference-between-pipenv-install-update-sync/

https://qiita.com/miyashiiii/items/92e6f745a940c4df2ddd#requirementstxt%E3%81%98%E3%82%83%E3%81%A0%E3%82%81