あらすじ
- test.py(xdist)で並列テストを実行しているプロジェクトが存在する。
- 現在、関数毎にテスト用の redis-server を起動して、都度廃棄している。
- redis-server を起動する処理をモジュール単位に変更し、テスト関数が始まる度に flushall() にする処理に変更したい。
というわけで検証してみた。
準備したファイル
% cat tests/conftest.py # -*- coding: utf-8 -*- import os import pytest import inspect import logging logging.basicConfig(filename='pytest.log',level=logging.DEBUG) def _log(): def_name = inspect.currentframe().f_back.f_code.co_name logging.debug('%s:%s' % (os.getpid(), def_name)) @pytest.fixture(scope='module', autouse=True) def module(): _log() @pytest.fixture(scope='function', autouse=True) def function(): _log()
% cat tests/test_pytest.py # -*- coding: utf-8 -*- import os import pytest import inspect import logging logging.basicConfig(filename='pytest.log',level=logging.DEBUG) def _log(): def_name = inspect.currentframe().f_back.f_code.co_name logging.debug('%s:%s' % (os.getpid(), def_name)) class TestMy(object): def test_001(self): _log() def test_002(self): _log() def test_003(self): _log() def test_004(self): _log() def test_005(self): _log() def test_006(self): _log() def test_007(self): _log() def test_008(self): _log() def test_009(self): _log() def test_010(self): _log()
実験開始
py.test を4つのプロセスで実行する
% py.test tests/test_pytest.py -n 4 ==================================== test session starts ===================================== platform darwin -- Python 2.7.3 -- py-1.4.27 -- pytest-2.7.1 rootdir: /Users/okamura/python/pytest-scope/tests, inifile: plugins: fixture-tools, xdist gw0 [10] / gw1 [10] / gw2 [10] / gw3 [10] scheduling tests via LoadScheduling .......... ================================= 10 passed in 0.61 seconds ==================================
ログを確認
% cat pytest.log DEBUG:root:90675:module DEBUG:root:90675:function DEBUG:root:90674:module DEBUG:root:90674:function DEBUG:root:90677:module DEBUG:root:90675:test_001 DEBUG:root:90674:test_007 DEBUG:root:90677:function DEBUG:root:90676:module DEBUG:root:90677:test_003 DEBUG:root:90676:function DEBUG:root:90674:function DEBUG:root:90675:function DEBUG:root:90674:test_008 DEBUG:root:90675:test_002 DEBUG:root:90676:test_005 DEBUG:root:90675:function DEBUG:root:90674:function DEBUG:root:90675:test_010 DEBUG:root:90677:function DEBUG:root:90674:test_009 DEBUG:root:90677:test_004 DEBUG:root:90676:function DEBUG:root:90676:test_006
見辛いので grep する
% cat pytest.log | grep 90675 DEBUG:root:90675:module DEBUG:root:90675:function DEBUG:root:90675:test_001 DEBUG:root:90675:function DEBUG:root:90675:test_002 DEBUG:root:90675:function DEBUG:root:90675:test_010
まとめ
- テストケースは(-nで指定された)4つのプロセスに分割され並列に実行される
- module単位の fixture は各プロセスが1度だけ実行するので、合計で4回実行される
- test_001からtest_010 のテストケースは4つのプロセスのいずれかで実行される
- 同じプロセス内では順次に処理が実行される
よってモジュール単位で redis-server を起動させた場合(port や dbfile などは独立しているとする)、それぞれのテストケースで影響が出る事はないでしょう。
あとがき
ちなみに -n で指定できる数値は CPU の コア数 * スレッド数 のようです。