0

I'm using pytest (version 7.1.2) to test a function foo() written in Python 3.9. I'd like to add assertions within foo() that depend on which test_foo() function is calling foo(). Something like this:

def foo(a):
    ...
    if my_caller() == 'test_foo_1':
        assert a == 0
    elif my_caller() == 'test_foo_2':
        assert a > 0
    ...

def test_foo_1():
    assert foo(0)

def test_foo_2():
    assert not foo(4)

Is there a more elegant solution than the following (perhaps using marks) that allows foo() to identify its caller?

import inspect

def my_caller():
    return inspect.stack()[2][3]
Viraj
  • 1

1 Answers1

0

You should not rely on where a function is called from. Code to be tested should be written in such a way that it doesn't matter who the caller is. That means for example that required dependencies should be "injected", i.e. passed in as parameters. All assertions should be located in the test code and work with the return values of the function. This way, you achieve a clean separation between production and test code.

An example for illustration:

def foo(a):
    if some_condition(a):
        return 47
    else:
        return 11

def test_foo_1():
    result = foo(0)
    assert result == 47

def test_foo_2():
    result = foo(1)
    assert result != 47
Jan Wilamowski
  • 3,308
  • 2
  • 10
  • 23
  • Yes, I do recognize that I'm violating the separation between production and test code, so I understand if pytest does not support this. (I'm interested in doing this in a particular educational context.) – Viraj May 12 '22 at 09:47
  • If you really want to go down that path, have a look at https://stackoverflow.com/questions/2654113/how-to-get-the-callers-method-name-in-the-called-method – Jan Wilamowski May 12 '22 at 09:49
  • Thanks, Jan. I managed to get that approach to work (original post)... I will use that if there isn't a cleaner way. – Viraj May 12 '22 at 09:55