Блок внутри pytest.raises не запускает контекстный менеджер - PullRequest
0 голосов
/ 09 марта 2020

Я писал токенизатор для небольшого языка, который я разрабатываю в свободное время, и я хочу протестировать его с отрицательным вводом. Мой код может вызывать два вида Exception s, IndentationError и SyntaxError, и это выглядит примерно так:

class Tokenizer:
    def __init__(self, source:str) -> None:
        self.source = source
        ...

    def get_next_token(self) -> Token:
        """Returns the next token and advances the position pointer into self.source"""
        ...

    def tokenize(self) -> Generator[Token, None, None]:
        """Calls get_next_token until all of self.source has been scanned"
        ...

Затем в тестах у меня есть списки со всеми видами ввода , Например:

SYNTAX_ERROR_SOURCES = ["(}", "[}", "{]", "a@b"] # Note that @ is not a supported operand

И тогда одна из тестовых функций выглядит следующим образом:

@pytest.mark.parametrize("source", SYNTAX_ERROR_SOURCES)
def test_tokenize_fail_syntax_error(source: str) -> None:
    with pytest.raises(SyntaxError):
        Tokenizer(source).tokenize()

Проблема в том, что tokenize никогда не вызывается внутри диспетчера контекста, и я не уверен почему. Я могу подтвердить это, запустив код под отладчиком. Когда он достигает линии, где вызывается tokenize, он напрямую переходит к некоторому коду pytest, и после этого тест завершается неудачно с Failed: DID NOT RAISE <class 'SyntaxError'>, даже не входя в tokenize.

Кроме того, если я выполните tokenizer.py как скрипт с python tokenizer.py "a@b", тогда все в порядке, и программа завершается с SyntaxError, как и ожидалось.

Кто-нибудь когда-нибудь сталкивался с чем-то подобным?

...