0

The code looks something like:

def check():
    if 'connector' in someMap:
        print("proceed")
    else:
        raise Exception('Positive vibes only')
    return 1

Pytest that I am trying looks like:

def test_check():
    e = 'negative test case for else block'
    with pytest.raises(e) as exc:  # pycharm shows e as Expected type 'Union[Tuple[Any, ...] Any]' (matched generic type 'Union[Type[E], Tuple[Type[E], ...]]') got 'str' instead
        res = check()
    assert res == e
layman
  • 79
  • 10
  • there are built in exception calls to python... such as ValueError....https://docs.python.org/3/tutorial/errors.html – thejahcoop Jan 11 '23 at 19:48
  • A pytest code snipped will be helpful. – layman Jan 11 '23 at 19:52
  • 1
    Your test makes no sense. `raises` takes an exception as an argument, not an arbitrary string. The string `e` appears nowhere in the definition of `check`: it's not a return value, it's not written to standard output (or any other stream), and it's not the message in the exception that `check` could raise. What exactly do you *want* to test? – chepner Jan 11 '23 at 20:00
  • I want coverage for the exception handling part. So, I wish to know, if there is a way to write pytest for the else block, which holds a string value only. I have just started learning pytests, so please suggest a way. The pytest block that I have written is something that I was just trying for starters. – layman Jan 11 '23 at 20:27
  • 1
    I don't understand what is your desired output... does it follow this logic: 1. if environ variables contain 'connector' then we don't pass the text 2. if environ variables do not contain 'connector' we raise an exception, and pass the test? – CodeCop Jan 11 '23 at 21:43
  • Does this answer your question? [How to properly assert that an exception gets raised in pytest?](https://stackoverflow.com/questions/23337471/how-to-properly-assert-that-an-exception-gets-raised-in-pytest) – Gino Mempin Jan 12 '23 at 03:39
  • 1
    Specifically, read the pytest docs on [Assertions about expected exceptions](https://docs.pytest.org/en/stable/how-to/assert.html#assertions-about-expected-exceptions) – Gino Mempin Jan 12 '23 at 03:40
  • Yes, that is correct @no_hex – layman Jan 12 '23 at 08:37
  • @GinoMempin - it does not. I want to understand about how to assert an exception when the value is string. – layman Jan 12 '23 at 08:38

1 Answers1

1

you would need to capture the exception, and the way is

 with pytest.raises(Exception) as exc_info:   # exc_info will strore the exception throw from check
        check()

once an exception is captured, you can get its string value by exc_info.value.args[0]}, for more detail, refer the pytest docs.

so the code would be(comments added for clarity)

import pytest
import os
def check():
    if 'connector' in os.environ:
        print("proceed")
    else:
        raise Exception('Positive vibes only')
    return 1

#check()

def test_check():
    e = 'negative test case for else block'
    with pytest.raises(Exception) as exc_info:   # exc_info will strore the exception throw from check
        check()
    print(f"type is:{exc_info.type} and value is {exc_info.value.args[0]}") # exc_info.type contain Exception and exc_info.value contains the value throw by exception, in this case 'Positive vibes only'
    assert e == exc_info.value.args[0] # this will fail as 'negative test case for else block' is compared with 'Positive vibes only'

def test_check_pass():
    e = 'negative test case for else block'
    with pytest.raises(Exception) as exc_info:   # exc_info will strore the exception throw from check
        check()
    assert 'Positive vibes only' == exc_info.value.args[0] # this will be a pass
simpleApp
  • 2,885
  • 2
  • 10
  • 19
  • One doubt though. By printing with and without args[0], the printed value is coming as same. But, without args[0] the test is failing. What exactly does args[0] do? – layman Jan 12 '23 at 08:48
  • 1
    if you try `type(exc_info.value)` , will find that its type is `class 'Exception'` so as type of str and class, it fails, when we use print behind the scene if the class method has `__str__` it get called. try reading `__str__ vs __repr__` – simpleApp Jan 12 '23 at 13:50