I have this structure:
@pytest.fixture(scope='session')
def load_config() -> dict:
with open(r"test_plan_1.yaml") as f:
data = yaml.safe_load(f)
return data
class TestBase:
def calculate_mape_range(self, test_path_1: str, test_path_2: str, window_size: int, threshold: float) -> int:
class TestMapeHealthy(TestMapeBase):
@pytest.mark.parametrize("threshold", THRESHOLD_COMPREHENSION)
@pytest.mark.parametrize("window_size", WINDOW_SIZE_COMPREHENSION)
def test_MAPE_for_healthy_(self, threshold: float, window_size: int, load_config: dict) -> str:
try:
consecutive_failures = super().calculate_mape_range(
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids']['healthy_test_list'][0],
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids']['healthy_test_list'][1],
window_size,
threshold
)
assert consecutive_failures == 0
class TestMapeFaulty(TestMapeBase):
@pytest.mark.parametrize("threshold", THRESHOLD_COMPREHENSION)
@pytest.mark.parametrize("window_size", WINDOW_SIZE_COMPREHENSION)
def test_MAPE_for_faulty_(self, threshold: float, window_size: int, load_config: dict) -> str:
try:
consecutive_failures = super().calculate_mape_range(
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids']['faulty_test_list'][0],
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids']['faulty_test_list'][1],
window_size,
threshold
)
assert consecutive_failures == 0
I am basically using the same code in both test cases (the differences are that I'm passing different tags in the YAML to the calculate_mape_range and that the assert statement is different, How can I avoid this duplication of code in an elegant Pytest-way?
You could add a couple of additional parameters to your test function and you should be able to cover both cases with a single function:
@pytest.mark.parametrize("threshold", THRESHOLD_COMPREHENSION)
@pytest.mark.parametrize("window_size", WINDOW_SIZE_COMPREHENSION)
@pytest.mark.parametrize("final_key", ...)
@pytest.mark.parametrize("should_pass", ...)
def test_MAPE(threshold: float, window_size: int, final_key: str, should_pass: bool, load_config: dict):
consecutive_failures = super().calculate_mape_range(
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids'][final_key][0],
load_config['test_plan']['test_ids'][VERSION_TAG]['tools']['test_file_ids'][final_key][1],
window_size,
threshold
)
if should_pass:
assert consecutive_failures == 0
else:
assert consecutive_failures > 0