2021年6月3日木曜日

pytest でテスト配下に作成したヘルパーモジュールなどを参照する方法

pytest でテスト配下に作成したヘルパーモジュールなどを参照する方法

概要

pytest でテストディレクトリ配下にヘルパーメソッドやテスト用のダミーモジュールを作成することがあると思います テスト用に専用のモジュールを作成した場合は普通にインポートしようとしてもエラーになります そんな場合の対処方法を紹介します

環境

  • macOS 11.4
  • Python 3.8.7

準備

  • pipenv install pytest
  • mkdir user
  • touch user/user.py
  • mkdir -p test/unit
  • mkdir -p test/helper
  • touch test/unit/test_user.py
  • touch test/helper/helper.py

user/user.py

class User():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def profile(self):
        return {"name": self.name, "age": self.age}

test/unit/test_user.py

import pytest

from user.user import User

class TestUser():
    def test_profile(self):
        u = User("hawk", 10)
        assert(u.profile() == {"name":"hawk","age":10})

テストコマンド

  • PYTHONPATH=./ pipenv run pytest -s test/unit

ヘルパーメソッドを定義する

ではテスト用のヘルパーメソッドを定義しましょう 以下のような感じでダミーのプロファイルを返却するクラスを作成します

  • vim test/helper/helper.py
class DummyUser():
    def profile(self):
        return {"name": "snowlog", "age": 99} 

普通これをテストで使うには以下のように import すると思います

import pytest

from test.helper.helper import DummyUser

from user.user import User

class TestUser():
    def test_profile(self):
        u = User("hawk", 10)
        assert(u.profile() == {"name":"hawk","age":10})

しかしこれでテストを実行すると ModuleNotFoundError: No module named 'test.helper' になります

ヘルパーメソッドを import するには

sys.path.append を使って無理やり import します 以下のように修正しましょう

import pytest
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '../helper'))
from helper import DummyUser

from user.user import User

class TestUser():
    def test_profile(self):
        u = User("hawk", 10)
        du = DummyUser()
        assert(u.profile() == {"name":"hawk","age":10})
        assert(du.profile() == {"name":"snowlog","age":99})

これだとエラーにならないのが確認できると思います

ヘルパーモジュールを test 配下に作らないのも手

例えば test/helper/helper.py を helper/helper.py に作成するのも手です そうすれば test からは

from helper.helper import DummyUser

で参照することができます これでも OK なのですがテストのためだけに作ったクラスがアプリと同じ階層に来るのが嫌な人は上記の方法を使いましょう

参考サイト

0 件のコメント:

コメントを投稿