テスト駆動Python:環境構築~Chapter1:技術書メモ
読み進めた本
テスト駆動Python
pytest とは何か
- ソフトウェアテストフレームワーク。
- 既存の unittest/nose などと比較して、テストが読みやすい。
- 単純なテストを書くのが簡単。
- 複雑なテストを書くのも簡単。
- unittest/nose のテストを pytest でも実行できる。
サンプルソース
本書のコードは公開されている。 ※もちろんこれだけでは意味が分からないので、本の購入は必要。 [https://pragprog.com/titles/bopytest]
本書のサンプルコードを実行するにあたり作成した環境
私個人の実行環境であり、本の内容とは関係ない。 Windows の WSL2 環境で検証。 WSL2 の中身は Ubuntu。
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.1 LTS"
VERSION_ID="20.04"
$ python -V;pipenv --version;pytest --version
Python 3.8.2
pipenv, version 2020.8.13
pytest 6.1.0
pipenv を利用した仮想環境の場合
各個人の環境に依存。
私の場合は、今回はpipenv
を利用して仮想環境を構築した。
$ pip3 install pipenv --user
$ pipenv install pytest
##### pipenv の設定 #####
#.bashrc/.zshrcなどに追記する
## pipをユーザ権限でインストールしたときのライブラリの保存先にPathを通す
export PATH="$PATH:$HOME/.local/bin"
## pipenvで仮想環境を作るときにproject配下に.venvを作成
export PIPENV_VENV_IN_PROJECT=1
VSCode の設定
本書ではpytest
のコマンドでテストを実行させていたが、VSCode の GUI でも実行できるためそちらを試した。
pytest を VSCode から実行できるようにする。
コマンドパレット(ctrl+shift+p)からpython configure tests
を入力して設定を開く。
どのテストライブラリを利用するか選択。今回は本と同じ pytest を選択。
どこに test ファイルがあるのかを選択。
Chapter1 はじめての pytest
左側にフラスコのアイコンが現れるので、そこをクリックし、Run All Tests
ボタンを押下するとテストが実行される。
ターミナル(ctrl+shift+@)のPROGRAMS
のタブにより具体的な結果が表示される。
show test output からtest_failing
を確認することができる。
※test_failing
はなぜ失敗したのかの詳細セクション
assertについて
assert
の後にbool値を返す式を書く。
def test_check():
t = 1
assert 1 == t
assert (1, 2, 3) == (t, 2, 3)
サンプルコードの"namedtuple"について
例としてnamedtuple
を使っていたが、知らない関数だったので調べた。
https://qiita.com/Seny/items/add4d03876f505442136
## こんな風に使う
>>> from collections import namedtuple
>>> Car = namedtuple('Car' , 'color mileage')
## 出力
>>> my_car = Car('red', 3812.4)
>>> my_car.color
'red'
>>> my_car.mileage
3812.4
※qiita から抜粋
雰囲気だけ理解して、本質ではないので次に進む。
サンプルコードでやっていること
Task オブジェクトを作成して、その挙動を test 関数を使って検証している。
from collections import namedtuple
# Taskというデータ型のフィールド'summary', 'owner', 'done', 'id'を定義
Task = namedtuple('Task', ['summary', 'owner', 'done', 'id'])
# デフォルト値を定義
Task.__new__.__defaults__ = (None, None, False, None)
# パラメータを指定しないときのデフォルト値(t1)がt2と一致するかのテスト
def test_defaults():
t1 = Task()
t2 = Task(None, None, False, None)
assert t1 == t2
# namedtupleの.フィールド名が一致しているかテスト
def test_member_access():
t = Task('buy milk', 'brian')
assert t.summary == 'buy milk'
assert t.owner == 'brian'
assert (t.done, t.id) == (False, None)
pytest のオプション(紹介があったものだけ)
- -v, –verbose
- –collect-only
- -k EXPRESSION
- -m MARKERXPR
- -x, –exitfirst
- –maxfail=num
- -s, –capture=method
- –lf, –last-failed
- –ff, –failed-first
- -q, –quite
- -l, –showlocals
- –tb=style
- –durations=N
- –version
- -h, –help
ディスカバリルール(実行するテストとして認識させるためのルール)
- テストファイルは test_~~~ .py か ~~~_test.py 名前でないといけない。
- テストメソッド、関数は test_~~~ でないといけない。( ~~テストはダメ?)
- テストクラスは Test~~~ でないといけない。( ~~テストはダメ?)
pytest
を引数なしで実行すると、上記のルールで書かれたファイル、関数、メソッド、クラスを探索されてテストコードが実行される。
感想
TDD がどんな感じなのか、雰囲気を理解した。続きは読み次第追記。