pytest не подтверждает зависимость PASSED в базовом классе, что приводит к тестам SKIPPED в производном классе

У меня есть небольшой проект, в котором я использую pytest и pytest-dependency с tox для разработки интеграционных тестов для некоторого кода. До сих пор я использовал один базовый класс (BTestClass) с некоторыми общими тестами в корневом каталоге и специфическими тестами для каждого компонента кода в test_Component.py file рядом с ним, реализуя класс TestC, наследуемый от BTestClass.

Все работало нормально до тех пор. Теперь я хочу добавить BTestClass2 для другого набора компонентов. Поэтому я добавил еще один уровень наследования, но теперь он не работает, pytest проверяет общие тесты A, но затем пропускает тесты, которые от него зависят. Понятия не имею почему.

Вот макет файловой системы:

λ tree /F
Folder PATH listing
Volume serial number is F029-7357
C:.
│   B.py
│   requirements-tox.txt
│   tox.ini
│
├───app_C
│   └───tests
│           test_C.py
│
└───common
        A.py

common\A.py

import pytest


class ATestClass():

    @pytest.mark.dependency(name='test_a')
    def test_a(self):
        assert True

B.py

import pytest
from common.A import ATestClass


class BTestClass(ATestClass):

    @pytest.mark.dependency(name='test_b', depends=['test_a'])
    def test_b(self):
        assert True

test_C.py

import pytest
import sys


sys.path.append('.')
from B import *


class TestC(BTestClass):

    @pytest.mark.dependency(name='test_c', depends=['test_b'])
    def test_c(self):
        assert True

Вывод pytest:

λ tox -- -rs
py38 installed: ...
py38 run-test-pre: PYTHONHASHSEED='367'
py38 run-test: commands[0] | pytest -x -v -rs
=============================================== test session starts ===============================================
platform win32 -- Python 3.8.1, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- ...\poc\.tox\py38\scripts\python.exe
cachedir: .tox\py38\.pytest_cache
rootdir: ...\poc
plugins: dependency-0.5.1
collected 3 items

app_C/tests/test_C.py::TestC::test_b SKIPPED                                                                 [ 33%]
app_C/tests/test_C.py::TestC::test_c SKIPPED                                                                 [ 66%]
app_C/tests/test_C.py::TestC::test_a PASSED                                                                  [100%]
============================================= short test summary info =============================================
SKIPPED [1] .tox\py38\lib\site-packages\pytest_dependency.py:103: test_b depends on test_a
SKIPPED [1] .tox\py38\lib\site-packages\pytest_dependency.py:103: test_c depends on test_b
===================================== 1 passed, 2 skipped, 1 warning in 0.14s =====================================
_____________________________________________________ summary _____________________________________________________
  py38: commands succeeded
  congratulations :)

Есть идеи, почему test_b пропускается и не выполняется?

Редактировать: если я сделаю BTestClass автономным, удалив A / ATestClass из изображения, он будет работать нормально.

collected 2 items

app_C/tests/test_C.py::TestC::test_b PASSED [ 50%]
app_C/tests/test_C.py::TestC::test_c PASSED [100%]

person DaLynX    schedule 13.10.2020    source источник
comment
Кажется, у вас есть содержимое test_C.py в common\A.py - ошибка копирования и вставки?   -  person MrBean Bremen    schedule 13.10.2020
comment
Да, исправлено, спасибо.   -  person DaLynX    schedule 13.10.2020


Ответы (1)


В pytest-dependency зависимость от другого теста означает, что этот тест выполняется до зависимого теста. Если это не так (в вашем примере test_b запускается перед test_a, поскольку test_a находится в подкаталоге), тест просто пропускается. pytest-dependency не переупорядочивает тесты (к сожалению).

Если вы не можете легко установить порядок выполнения тестов с помощью именования, вы можете использовать pytest-ordering плагин для приведения тестов в нужный порядок. В вашем случае вы можете сделать:

class ATestClass:
    @pytest.mark.dependency(name='test_a')
    @pytest.mark.run(order=0)
    def test_a(self):
        assert True
...
class BTestClass(ATestClass):
    @pytest.mark.dependency(name='test_b', depends=['test_a'])
    @pytest.mark.run(order=1)
    def test_b(self):
        assert True

В этом случае тесты выполняются в порядке test_a - test_b - test_c, и все тесты будут выполнены.

ОБНОВЛЕНИЕ:
Вы также можете использовать pytest -order, который является ответвлением pytest-ordering. Если вы используете параметр pytest --order-dependencies, он попытается переупорядочить тесты с зависимостями, созданными pytest-dependencies, без необходимости добавления дополнительных меток.

Отказ от ответственности: я являюсь автором этой вилки.

person MrBean Bremen    schedule 16.10.2020