自分の才能の無さに気が付いたら...pytestを試していた..

#この記事は.
テスト自動化のライブラリを使ってみたのでその手順をメモっておきます.(pytestというよりpythonそのものにはまった..)

# テスト自動化を導入するまで
最近,javascript(vue),pythonなどでコードを書くけど,はやりバグはあり注意深くソースなどを見てコミットするようにはするがデグル..:bow_tone1:などをやっていると時間がもったいないので,テスト自動化を取り入れることにしました.

# テスト自動化の歴史
こちらは,今後お勉強します.以下が大変ためになりました.
[テスト自動化について、調べてみた](https://qiita.com/yutachaos/items/857472c7d3c65d3cf316)

# what is the pytest ???
公式より
>The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.

pythonのテストライブラリの1つです.標準にunittestがついてますが,コードが長いので__pytest__を採用しました.
理由はそれだけなので,他も試して自分に合うものを採用しようと思います.

# インストール
pytestをインストールします.その後にガバレッジを出してくれるプラグインもあるので追加しておきます.

```py
pip install pytest
pip install pytest-cov
```

#FizzBuzz

今回は使ってみたが目的なのでFizzBuzzで.

フォルダ構成は,srcフォルダは開発ソース,testファルダはテストソースを入れる.
テストファイル名はtest_を先頭に付けます.

Moduleフォルダ

- main.py
- srcフォルダ
  * \_\_init\_\_.py
  * FizzBuzz.py
- testフォルダ
  * \_\_init\_\_.py
  * test_FizzBuzz.py

ソースは以下です.(python初心者なのでinitファイルとかこれで正しいかは正直よくわからないです.)
__テスト失敗するために,if-elifの順番を間違ってます__

```python:__init__.py
from . import FizzBuzz
```

```python:FizzBuzz.py
# 3の倍数なら「Fizz」,5の倍数なら「Buzz」,両方の倍数なら「FizzBuzz」
def FizzBuzz(number):
    if number % 5 == 0:
        say = 'Buzz'
    elif number % 3 == 0:
        say = 'Fizz'
    elif number % 15 == 0:
        say = 'FizzBuzz'
    else:
        say = str(number)

    return say
```

これで,バグを含んでいる状態でソースが完成です.

#テストコード
今回はこれで終わりでなく,テストコードも書いて検証します.

検証は4種類かと思います.

* 3の倍数のとき
* 5の倍数のとき
* 両方の倍数のとき
* 上記以外のとき

```python:テストコードの書き方
import src import file
def test_function():
    assert file.function(arg) == answer
```

以下がソースです.(initファイルでシステムパスをいじります.これが滅茶苦茶躓きました.実行ファイルより上のパスに行けないのね..:thinking:)
__次にガバレッジを100%にしないため,Fizz,Buzz,FizzBuzz以外のテストをしません.__

```python:__init__.py
import sys, os
sys.path += [os.path.dirname(os.path.dirname(__file__))]
```

```python
from src import FizzBuzz

def test_Fizz():
    assert FizzBuzz.FizzBuzz(3) == 'Fizz'
    assert FizzBuzz.FizzBuzz(297) == 'Fizz'

def test_Buzz():
    assert FizzBuzz.FizzBuzz(5) == 'Buzz'
    assert FizzBuzz.FizzBuzz(40) == 'Buzz'

def test_FizzBuzz():
    assert FizzBuzz.FizzBuzz(15) == 'FizzBuzz'
    assert FizzBuzz.FizzBuzz(150) == 'FizzBuzz'
```

#テスト実行
コマンドラインから__pytest__でテストフォルダ内のテストファイルを実行してくれます.
(test_となっているファイルをテストファイルとみなしている)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/8955bf76-5387-5fbb-d039-0346438fd228.png)
無事,エラーになりました.
15を入れたのに'FizzBuzz'でなく'Buzz'が返ってきてます.if-elifの順番を入れ替えて再実行します.:triangular_flag_on_post:
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/42091a66-686c-f35c-ce6e-6ad2b450b5e9.png)

#ガバレッジ
テストコードは通りました.が,テストが書いたコード全てを網羅しているのか?テストが漏れていないのか?という問題があります.
そこで,__pytest-cov__というプラグインを使います(事前インストール済み)
コマンドラインで以下を叩きます.

```py
pytest --cov --cov-report=html
```

テストが終わると,module直下にhtmlcovというフォルダが生成されています.
中身はテスト結果であり,ガバレッジとその詳細を教えてくれます.(今回はその他の場合のテストがないのでそこがテストできてないです.)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/76825aa9-015b-d98b-82e4-02970000b881.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/4610793d-bf66-0f4d-8621-08c614ce455c.png)

#まとめ
今回は,テスト自動化ということでpytestを試してみました.
テストコードをちゃんと書くことで,意識してソースを書くようになった.(と思う):smiley:
(天才でもやるべき!)

#今後
他にも機能はたくさんあるのでどんどん試していきたいです.TDDの考え方などいろいろあるのでそちらもお勉強しようと思います.
テストコード書いてるから大丈夫だけど,テストコードが間違っている場合もあるのでそちらも注意しようと思うこの頃.

#参考
[公式doc](https://docs.pytest.org/en/latest/)
[pytestのとりあえず知っておきたい使い方](https://qiita.com/kg1/items/4e2cae18e9bd39f014d4)