170 похожих чатов

Pytest, хочу в нескольких тестах проверять результат работы некоторой штуки,

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

class DoStuffOnce:
target: str

@pytest.fixture(scope='class', autouse=True)
def run_long_stuff(self):
assert self.target
self.output = f'{self.target} ok: foo'
print(self.output)

def check(self, to_check):
assert f'ok: {to_check}' in self.output

class TestSomething(DoStuffOnce):
target = 'first'

def test_first(self):
self.check('foo')
но увы,
def test_first(self):
> self.check('foo')
def check(self, to_check):
> assert f'ok: {to_check}' in self.output
E AttributeError: 'TestSomething' object has no attribute 'output'
видимо, я неправильно варю scope=class, хотя по доке как будто бы это то что нужно: Fixtures are created when first requested by a test, and ... destroyed during teardown of the last test in the class.

ЧЯДНТ?

15 ответов

33 просмотра

Чет вообще не понятно, что ты делаешь

Igor-Ivanov Автор вопроса
genya
Чет вообще не понятно, что ты делаешь

интеграционный тест для софтины, которая долго бежит, выплёвывает оутпут, и в этом оутпуте должно быть несколько интересующих меня фрагментов запуск с набором параметров — один класс, проверка фрагментов — несколько def test_x() в этом классе хочу не запускать софтину несколько раз с одними и теми же параметрами

Igor Ivanov
интеграционный тест для софтины, которая долго беж...

выкинь классы и напиши нормальную фикстуру и передавай ее в тест функцию

Igor-Ivanov Автор вопроса
genya
выкинь классы и напиши нормальную фикстуру и перед...

ок, как тогда должна выглядеть "нормальная фикстура", инициализация которой будет происходить единожды для уникального параметра?

Igor Ivanov
ок, как тогда должна выглядеть "нормальная фикстур...

Фикстура не должна быть методом класса, делаешь отдельно фикстуру и указываешь скоуп, какой тебе надо (module, class, session). Дальше передаешь её аргументом или в декораторе

Igor-Ivanov Автор вопроса
genya
Фикстура не должна быть методом класса, делаешь от...

@pytest.fixture(scope='class') def run_long_stuff(rls_arg): c = Checker(f'{rls_arg} ok: foo') print(f'OUT::: ${c.out}') return c class TestClass: @pytest.mark.parametrize('rls_arg', ['sometarget']) def test_first(self, run_long_stuff): run_long_stuff.check('foo') @pytest.mark.parametrize('rls_arg', ['sometarget']) def test_second(self, run_long_stuff): run_long_stuff.check('foo') выдало: ScopeMismatch: You tried to access the 'function' scoped fixture 'rls_arg' with a 'class' scoped request object, involved factories test/inh_test.py:9: def run_long_stuff(rls_arg) на всякий случай уточняю, что фикстуры в pytest я вижу второй раз в жизни

Igor Ivanov
@pytest.fixture(scope='class') def run_long_stuff(...

про скоупы фикстур прочитай

Igor-Ivanov Автор вопроса
std::mpa 🇺🇦
про скоупы фикстур прочитай

восхитительный ответ! прочитал https://docs.pytest.org/en/stable/fixture.html#fixture-scopes Fixtures are created when first requested by a test, and are destroyed based on their scope: class: the fixture is destroyed during teardown of the last test in the class. вон фикстура, скоуп class, должна создасться при первом обращении (в test_first), и уничтожиться после последнего (после test_second) дальше что?)

Igor Ivanov
восхитительный ответ! прочитал https://docs.pytest...

может быть тебе нужно его в самом class и объявить? сейчас ты хочешь скоуп модуля, имея функцию вне класса.

Igor Ivanov
восхитительный ответ! прочитал https://docs.pytest...

Ты уверен что тебе скоуп класс нужен. Ты же используешь его в каждом методе с разным аргументом

Igor Ivanov
@pytest.fixture(scope='class') def run_long_stuff(...

Убери скоуп класс, и добавь indirect=True в parametrize, тогда должно заработать

Igor-Ivanov Автор вопроса
genya
Ты уверен что тебе скоуп класс нужен. Ты же исполь...

абсолютно уверен, погляди внимательнее, там одинаковые аргументы функционал который бы хотелось иметь в идеале, в голове выглядит как-то так: class RunApp: ... def run(self): output = subprocess.check_output(['app'] + self.run_parameters) def output_contains(self, regex): ... def output_not_contains(self, regex): ... class TestWithFoo(RunApp): run_parameters = ['--foo'] def test_a_mentioned(self): assert self.output_contains('AAA is x') def test_b_not_mentioned(self): assert self.output_not_contains('BBB') class TestWithBar(RunApp): run_parameters = ['--bar'] def test_b_mentioned(self): assert self.output_contains('BBB') соответственно, run() видится как @pytest.fixture(autouse=True, scope='class'), которая запускается один раз для блока TestWithFoo и один раз для TestWithBar в крайнем случае — окей, если путест не могёт в такое наследование как у меня, когда все проверки определены в базовом классе, то сойдёт и возвращение проверяльщика из фикстуры, class TestWithFoo: def test_a_mentioned(self, app_output): assert.app_output.contains(...)

Igor Ivanov
абсолютно уверен, погляди внимательнее, там одинак...

Убери тогда аргумент из фикстуры и вешай декоратор на тест класс @pytest.mark.usefixtures('run_long_stuff')

Igor-Ivanov Автор вопроса
genya
Убери тогда аргумент из фикстуры и вешай декоратор...

если я уберу аргумент из фикстуры, как она узнает что в class TestWithFoo нужно запускаться с одними аргументами, а в class TestWithBar с другими?

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Карта сайта