#python #pytest
Вопрос:
Когда я вызываю pytest
свой скрипт slurm, журнал тестового сеанса показывает, что все test_<test_name>.py
файлы вызываются дважды, при этом в первый раз они пропускаются, а во второй раз они выполняются:
[1m============================= test session starts ==============================[0m
platform linux -- Python 3.8.5, pytest-5.2.0, py-1.9.0, pluggy-0.13.1 -- /n/sw/eb/apps/centos7/Anaconda3/2020.11/bin/python
cachedir: .pytest_cache
rootdir: <removed for privacy reasons>, inifile: pytest.ini, testpaths: tests
plugins: flakes-2.0.0, pythonpath-0.7.3, cov-2.6.1, pep8-1.0.6, anyio-2.2.0
[1mcollecting ... [0mcollected 25 items
tests/conftest.py [32mPASSED[0m[36m [ 4%][0m
tests/conftest.py [32mPASSED[0m[36m [ 4%][0m
tests/test_base_dataset.py [33mSKIPPED[0m[36m [ 8%][0m
tests/test_base_dataset.py [32mPASSED[0m[36m [ 8%][0m
tests/test_base_dataset.py::test_base_dataset [32mPASSED[0m[36m [ 12%][0m
tests/test_base_model.py [33mSKIPPED[0m[36m [ 16%][0m
tests/test_base_model.py [32mPASSED[0m[36m [ 16%][0m
tests/test_base_model.py::test_base_dataset [32mPASSED[0m[36m [ 20%][0m
tests/test_base_options.py [33mSKIPPED[0m[36m [ 24%][0m
tests/test_base_options.py [32mPASSED[0m[36m [ 24%][0m
Это приводит к окончательному выводу:
[32m[1m======================== 19 passed, 6 skipped in 6.36s =========================[0m
Что может привести к такому поведению?
Я импортирую только pytest
один раз в моем conftest.py
conftest.py — по просьбе SergioLema в комментариях
import pytest
import numpy as np
import torch
import argparse
from options.train_options import TrainOptions
from data.base_dataset import BaseDataset
from models.base_model import BaseModel
from models.cycle_gan_model import CycleGANModel
from data.image_folder import ImageFolder
# test base dataset
class TestDataset(BaseDataset):
"""Test implementation of the BaseDataset class
"""
__test__ = False
def __init__(self, opt):
BaseDataset.__init__(self, opt)
self.dummy_data = np.asarray([np.random.random((2, 2)) for _ in range(0, 3)])
def __len__(self):
return self.dummy_data.shape[0]
def __getitem__(self, index):
return self.dummy_data[index]
class TestOption(BaseOptions):
__test__ = False
def __init__(self, parser):
BaseOptions.initialize(self, parser)
@pytest.fixture(scope="function")
def option_constructor():
yield TestOption(argparse.ArgumentParser(description="Test parser"))
@pytest.fixture(scope="function")
def base_dataset(ran_root):
yield TestDataset(ran_root)
# test image folder
@pytest.fixture(scope="function")
def image_folder_instance(dummy_data):
yield ImageFolder(dummy_data)
# test base options
@pytest.fixture(scope="module")
def dummy_data():
yield "/n/pfister_lab2/Lab/leander/cust_cgan/ccgan/tests/dummy_data"
# test train options
@pytest.fixture(scope="function")
def train_options(dummy_data):
yield TrainOptions().parse(['--dataroot', dummy_data, '--name', 'test_cyclegan',
'--model', 'cycle_gan', '--lambda_identity', '0.0'])
@pytest.fixture(scope="function")
def train_options_match_encoding(dummy_data):
yield TrainOptions().parse(['--dataroot', dummy_data, '--name', 'test_cyclegan',
'--model', 'cycle_gan', '--match_encoding', 'True',
'--match_encoding_weight', '0.5'])
# test base model
class TestBaseModel(BaseModel):
__test__ = False
def __init__(self, opt):
BaseModel.__init__(self, opt)
def set_input(self, input):
pass
def forward(self):
pass
def optimize_parameters(self):
pass
@pytest.fixture(scope="function")
def base_model(train_options):
yield TestBaseModel(train_options)
# test cycle_gan model
@pytest.fixture(scope='function')
def cycleGAN_instance(train_options):
yield CycleGANModel(train_options)
@pytest.fixture(scope='function')
def cycleGAN_match_encoding_instance(train_options_match_encoding):
yield CycleGANModel(train_options_match_encoding)
@pytest.fixture(scope='module')
def input():
A_data = torch.stack([torch.randn(3, 32, 32) for _ in range(0, 2)])
B_data = torch.stack([torch.randn(3, 32, 32) for _ in range(0, 2)])
A_path = ["path_of_img_A_{0}".format(i) for i in range(0, 2)]
B_path = ["path_of_img_B_{0}".format(i) for i in range(0, 2)]
yield {'A': A_data, 'B': B_data, 'A_paths': A_path, 'B_paths': B_path}
test_base_options.py — по просьбе Shod в комментариях
from options.test_options import TestOptions
def test_base_options(dummy_data):
opt = TestOptions().parse(["--dataroot", dummy_data])
assert (opt.dataroot == dummy_data)
Комментарии:
1. Не могли бы вы показать нам conftest.py и как вы запускаете свои тесты из командной строки?
2. @SergioLema Я добавил conftest.py досье. Я вызываю
pytest
из скрипта SLURM и не имею прямого доступа к командной строке. Я либо вызываюpytest
, либоpytest -k test_<test_abrivation>
. В обоих случаях я вижу поведение, описанное выше3. можете ли вы показать содержимое
test_<test_name>.py
?4. @Shod У меня есть несколько тестовых файлов. Однако, чтобы ответить на ваш вопрос, я удалил все файлы, кроме одного, и сократил файл до одного фиктивного теста (см.
test_base_options.py
Выше). Когда я запускаюpytest
снова, проблема сохраняется.5. @L.Lauenburg можете ли вы удалить
Test
префикс из тестовых классовconftest.py
и проверить один раз? Я знаю, что вы уже упоминали__test__ = False
, но идк, также проверьте эту проблему . Кроме того, попробуйте передать-vvv
, чтобы получить больше подробностей для отладки..