Вопрос №55206 от пользователя Nmbrtw в уроке «Подготовка данных», курс «Python: Автоматическое тестирование»
Как-то мало в этом модуле уроков обсуждений, хотя они намного сложнее (и возможно важнее) предыдущих. Поэтому буду задавать глупые вопросы, надеюсь ответы на них кому-то после меня пригодятся.
В документации пайтеста в фикстурах есть такие конструкции:
import pytest
@pytest.fixture
def a():
return []
@pytest.fixture
def b():
return 'b'
@pytest.fixture
def c():
return 'c'
test_append_b(a, b):
assert a.append(b) == ['b']
test_append_c(a,c):
assert a.append(c) == ['c']
верно я понимаю, что каждый раз, когда тест вызывает фикстуру, то внутри ее пересоздается все заново, и так мы решаем вопрос с мутабельными объектами и в целом с зависимостью тестов друг от друга?
И почему бы тогда не порекомендовать все последующие практики решать через такие конструкции? Чтобы хотя бы руку набить и привыкнуть
Обсуждений мало, потому что курс только-только опубликовали и его ещё предстоит отполировать! Заодно и обсуждения появятся :)
когда тест вызывает фикстуру, то внутри ее пересоздается все заново, и так мы решаем вопрос с мутабельными объектами и в целом с зависимостью тестов друг от друга?
Тест не вызывает фикстуру, они вызываются внутри pytest, как только среди имён аргументов того или иного теста встретится нужное имя. Но суть вы уловили правильно: любая функция, помеченная как фикстура, вызывается для каждого, зависящего от неё теста, заново. И да, таким образом обеспечивается независимость тестов от окружения. Однако, так ведут себя функции, которые декорированы pytest.fixture
без параметров.
А вот используя параметры, можно заставить каждую фикстуру породить несколько значений, после чего pytest будет вызвать каждый зависимый тест для каждого отдельного значения:
@pytest.fixture(
params=[
'foo',
42,
object(),
(1, 2, 3),
[None],
],
)
def truthful():
return pytest.param
# ^ так можно получить доступ к параметру
def test_truth(truthful): # этот тест будет вызван пять раз
assert truthful
Кроме того, можно задать и область видимости фикстуры. Скажем, описать фикстуру, которая создаёт временную директорию, единоразово распаковывает в неё файлы из заготовленного архива и делает доступной для всех тестов в модуле, а удаляет директорию только после завершения всех тестов:
@pytest.fixture(scope='module')
def sandbox():
with tempfile.TemporaryDirectory() as tmp:
yield Path(tmp)
# ^ директория отправляется как значение фикстуры
# к этому моменту директория будет удалена
@pytest.fixture(scope='module')
def data_files(sandbox):
with zipfile.ZipFile(
Path(__file__).parent / 'data' / 'examples.zip',
) as z:
z.extractall(sandbox)
return [
sandbox / name
for name in z.namelist()
]
def test_foo(data_files):
assert all(p.exists() for p in data_files)
Словом, возможностей у pytest предостаточно!
И вот тут мы как раз подходим к
И почему бы тогда не порекомендовать все последующие практики решать через такие конструкции?
Возможностей у pytest слишком много, чтобы был смысл подробно расписывать сколько-нибудь приличную их часть. Поэтому в курсе показаны только самые основы. За подробностями же лучше всего обращаться к официальной документации — только так вы будете получать максимально актуальную и полную информацию.
Ребята, наверное стоит более ясно сформулировать задание, а в теории подробнее рассмотреть, на какие случаи стоит писать тесты. Без просмотра решения учителя совершенно непонятно было, каких и сколько тестов нужно написать. В предыдущих заданиях все было понятно по примеру выдачи REPL, а тут оказалось нужно делать все иначе.
И при теории с фикстурами и общими данными для группы тестов в решении это не используется никак =(
Aleksei Pirogov, попробовал запустить ваш код под первым спойлеров (фикстуры с использованием параметров). И там функция def test_truth получает в качестве аргумента <function param at 0x7f7fbfc204c0> (5 раз разные) А вы же наверное имели в виду что в эту функцию в качестве аргумента передаются именно значения параметров? Вроде нашел в интернете, что это делается так: def truthful(request): return request.param Тогда, например, если поставить в параметры что-то со значением False, то тест с этим параметром не пройдет.
Иван Рябкин, да, всё верно, это я напутал: pytest.param
про другое :) А вы нашли правильный вариант: функция-фикстура должна иметь принимать один аргумент и обращаться к его атрибуту .param
.
Используйте Хекслет по максимуму!
- Задавайте вопросы по уроку
- Проверяйте знания в квизах
- Проходите практику прямо в браузере
- Отслеживайте свой прогресс
Зарегистрируйтесь или войдите в свой аккаунт
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.







