pytestの前処理と後処理

# pytestの前処理と後処理

pytestで各テスト項目やテストクラス、テストモジュール（pyファイル）全体に対して
前処理と後処理を実行する書き方。

※2019/12/03 fixtureで書く場合のサンプルを追記した。
※自分でまとめるよりよほど有益なサイトをみつけた
[pytest ヘビーユーザーへの第一歩 \- エムスリーテックブログ](https://www.m3tech.blog/entry/pytest-summary)

## まとめ

前処理／後処理の対象と使用する関数／メソッド

- テスト関数ひとつひとつ(`test_～～`)
  - `setup_function(function)`と`teardown_function(function)`
- テストクラスのテストメソッドひとつひとつ(クラス内の`test_～～`)
  - `setup_method(self, method)`と`teardown_method(self, method)`
- テストクラス全体(`class Test～～`)
  - `setup_class(cls)`と`teardown_class(cls)`
    ※クラスメソッド(`@classmethod`)
- テストモジュール全体(～～.pyのファイル全体）
  - `setup_module(module)`と`teardown_module(module)`

## サンプル(xunitで書く場合)

```python:xunitで書く場合
def setup_module(module):
    print("\n*** setup_module ***")

def teardown_module(moduloe):
    print("\n*** teardown_module ***")

def setup_function(function):
    print("\n=== setup_function ===")

def teardown_function(function):
    print("\n=== teardown_function ===")

def test_test1():
    print("test1")

def test_test2():
    print("test2")


class TestCase:
    @classmethod
    def setup_class(cls):
        print("\n@@@ setup_class @@@")

    @classmethod
    def teardown_class(cls):
        print("\n@@@ teardown_class @@@")

    def setup_method(self, method):
        print("\n--- setup_method ---")

    def teardown_method(self, method):
        print("\n--- teardown_method ---")

    def test_test3(self):
        print("test3")

    def test_test4(self):
        print("test4")
```

## 実行結果

```text:実行結果
==================================== test session starts ====================================
platform linux -- Python 3.6.3, pytest-5.3.0, py-1.8.0, pluggy-0.13.1 -- /home/bskke1040/.pyenv/versions/3.6.3/bin/python3.6
cachedir: .pytest_cache
rootdir: /mnt/c/Users/bskke1040.KMJP/Clouds/OneDrive/study/pytest
collected 4 items

test_sample.py::test_test1
*** setup_module ***

=== setup_function ===
test1
PASSED
=== teardown_function ===

test_sample.py::test_test2
=== setup_function ===
test2
PASSED
=== teardown_function ===

test_sample.py::TestCase::test_test3
@@@ setup_class @@@

--- setup_method ---
test3
PASSED
--- teardown_method ---

test_sample.py::TestCase::test_test4
--- setup_method ---
test4
PASSED
--- teardown_method ---

@@@ teardown_class @@@

*** teardown_module ***


===================================== 4 passed in 0.05s =====================================
```

## サンプル(fixtureで書く場合)

```python:fixtureで書く場合
import pytest


@pytest.fixture(scope="module")
def my_setup_module(request):
    print("\n######## my_setup_module ########")

    def my_teardown_module():
        print("\n######## my_teardown_module ########")
    request.addfinalizer(my_teardown_module)


@pytest.fixture()
def my_setup_function(request):
    print("\n--- my_setup_function ---")

    def my_teardown_function():
        print("\n--- my_teardown_function ---")
    request.addfinalizer(my_teardown_function)


@pytest.fixture(scope="class")
def my_setup_class(request):
    print("\n***** my_setup_class *****")

    def my_teardown_class():
        print("\n***** my_teardown_class *****")
    request.addfinalizer(my_teardown_class)


@pytest.fixture()
def my_setup_method(request):
    print("\n=== my_setup_method ===")

    def my_teardown_method():
        print("\n=== my_teardown_method ===")
    request.addfinalizer(my_teardown_method)


def test_test1(my_setup_module, my_setup_function):
    print("\ntest1")


def test_test2(my_setup_module, my_setup_function):
    print("\ntest2")


class TestCase:
    def test_test3(self, my_setup_module, my_setup_class, my_setup_method):
        print("\ntest3")

        def test_test4(self, my_setup_module, my_setup_class, my_setup_method):
            print("\ntest4")
```