Что не так с этим вызовом параметра pytest?

Я широко использовал pytest.mark.parametrize, но наткнулся на его использование в одном методе тестирования:

    @pytest.mark.parametrize("is_except, except_pattern, in_query, table, out_query",[
        (False,None,"WHERE     Table1.Col1='Foo'", "Table1","select * from Table1"),
        (True,None,"Table in query (Table11) must match the parameter value (Table1)", "Table1",None)
    ])
    def test_all_parameters(self,is_except,except_pattern,in_query,table,out_query):
        # logic ..

Это приводит к:

E TypeError: TestDeltaLakeReader.test_all_parameters() отсутствуют 5 обязательных позиционных аргументов: 'is_except', 'except_pattern', 'in_query', 'table' и 'out_query'

Полная трассировка стека:

(TestDeltaLakeReader.test_all_parameters)
self = <unittest.case._Outcome object at 0x121d78b20>
test_case = <framework.tests.ddex.reader.test_deltalake_reader.TestDeltaLakeReader testMethod=test_all_parameters>
isTest = True

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, isTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

/usr/local/Cellar/[email protected]/3.10.10_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/unittest/case.py:59: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/Cellar/[email protected]/3.10.10_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/unittest/case.py:591: in run
    self._callTestMethod(testMethod)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <framework.tests.ddex.reader.test_deltalake_reader.TestDeltaLakeReader testMethod=test_all_parameters>
method = <bound method TestDeltaLakeReader.test_all_parameters of <framework.tests.ddex.reader.test_deltalake_reader.TestDeltaLakeReader testMethod=test_all_parameters>>

    def _callTestMethod(self, method):
>       method()
E       TypeError: TestDeltaLakeReader.test_all_parameters() missing 5 required positional arguments: 'is_except', 'except_pattern', 'in_query', 'table', and 'out_query'

/usr/local/Cellar/[email protected]/3.10.10_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/unittest/case.py:549: TypeError

Есть идеи?

Обновление. Я довел это до одного параметра тестирования и все равно получаю ошибку.

Еще одно обновление. Тот же самый parametrize отлично работает, когда метод извлекается в отдельную функцию. У нас есть много применений parametrize внутри тестовых классов, поэтому я этого не понимаю.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
51
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Количество передаваемых параметров не соответствует количеству значений. Вы где-то пропустили запятую. Приведенный ниже результат запуска pytest показывает ошибку:

================================================================================================================= ERRORS =================================================================================================================
____________________________________________________________________________________________________ ERROR collecting random_test.py _____________________________________________________________________________________________________
random_test.py::test_all_parameters: in "parametrize" the number of names (5):
  ['is_except', 'except_pattern', 'in_query', 'table', 'out_query']
must be equal to the number of values (4):
  (False, None, "WHERE     Table1.Col1='Foo'", 'select * from Table1')

вы правы, в оригинале было неправильное количество записей, я исправил это, но все еще есть ошибка

WestCoastProjects 14.07.2023 04:17

Ваши параметры "is_except, except_pattern, in_query, table, out_query".

Но этот кортеж состоит из четырех элементов.

(False,
None,
"WHERE     Table1.Col1='Foo'",
"select * from Table1")

этот кортеж состоит из шести элементов.

(True,
None,
"Table in query (Table11) must match the parameter value (Table1)",
"select * from Table11",
"Table1",
None)

хорошие глаза. я исправил неправильные числа в некоторых строках, но все равно получаю ту же ошибку

WestCoastProjects 14.07.2023 04:07

@WestCoastProjects, похоже, ваша IDE запускает не pytest, а unittest.

Constantin Hong 14.07.2023 04:35

Этот же тестовый пример работал в той же IDE до добавления parametrize . Мне придется разбить 4 контрольных примера, это безумие

WestCoastProjects 14.07.2023 04:37

@WestCoastProjects, проверьте этот кейс. Я только что проверил тест моего проекта с вашими ошибками, но сообщение об ошибке отличается.

Constantin Hong 14.07.2023 04:38

Пожалуйста, перейдите в <ваш тестовый каталог> и pytest <your_the_testfile.py>.

Constantin Hong 14.07.2023 04:41

Да, я пробовал это, он также не работает в командной строке таким же образом

WestCoastProjects 14.07.2023 04:47

Этот тест работает как отдельная функция. Видимо parametrize не всегда работает для метода тестирования. У нас есть много методов тестирования с использованием параметризации, так что это было неожиданным открытием.

Ответ принят как подходящий

Параметризация Pytest обычно хорошо работает с автономными функциями (как вы сказали), а также (как правило) с методами экземпляра. Согласно документации pytest, параметризация, фикстуры и пользовательские хуки явно НЕ работают с классами, унаследованными от unittest.TestCase.

Поскольку вы заявили, что параметризация работает с некоторыми классами, я подозреваю, что эти классы не наследуются от unittest TestCase или что у них есть какая-то внутренняя «волшебная» логика, позволяющая хорошо работать с pytest. Из предоставленной трассировки кажется, что конкретный класс, о котором идет речь, наследуется от модуля unittest, что объясняет проблему, с которой вы столкнулись.

Следующий код должен завершиться ошибкой с аналогичным исключением, которое вы показываете:

import unittest
import pytest

class TestClass(unittest.TestCase):

    @pytest.mark.parametrize("y", ["a", "b"])
    def test_x_y(self, y):
        assert y in ("a", "b")

Поскольку этот тестовый класс довольно прост, решение тоже. При удалении наследования (class TestClass(unittest.TestCase): -> class TestClass:) два теста должны пройти успешно.

Если это действительно проблема, с которой вы столкнулись, я разместил более подробный ответ здесь с возможными решениями. В противном случае, пожалуйста, дайте мне знать о любой дополнительной информации, которую вы можете предоставить.

Подтверждено, что простое удаление наследования unittest.TestCase решает эту проблему.

WestCoastProjects 14.07.2023 20:25

Другие вопросы по теме