Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statically call other tests for test reuse / chain testing #49

Open
nyoma-diamond opened this issue Feb 17, 2025 · 0 comments
Open

Statically call other tests for test reuse / chain testing #49

nyoma-diamond opened this issue Feb 17, 2025 · 0 comments

Comments

@nyoma-diamond
Copy link

Currently I am unaware of any intended/documented functionality enabling the ability to call other pre-existing tests to in order to reuse existing test behavior and/or to validate chained functionality. For example, it may be easy or useful to validate the output of a function by passing it to the output of another existing test. If the output of one function that's being tested can be validated using another existing this would make developing tests much easier. This is trivial to implement using pytest's base Class methodology, but doesn't quite seem to align with describe-blocks.

For example:

Class TestFoo:
    test_foo(self, fixture1, arg1):
        foo_result = foo(fixture1, arg1)
        assert foo_result

Class TestBar:
    test_bar(self, fixture1, fixture2, arg1, arg2):
        bar_result = bar(fixture2, arg1, arg2)
        assert bar_result
        TestFoo().test_foo(fixture1, bar_result)

However using pytest-describe it isn't clear how to achieve similar functionality, if preservation of this feature has been intentionally designed in at all.

I recognize that this edge-case could be resolved by extracting the shared functionality out into a globally accessible function, but I find this to be a deeply inelegant solution and go against the essence of describe-blocks and test groups.

E.g.,

# Extracting functionality to test `foo` here is very clunky and defeats the entire point of describe-blocks / test groups
def shared_test_foo(fixture1, arg1):
    foo_result = foo(fixture1, arg1)
    assert foo_result

Class TestFoo:
    test_foo(self, fixture1, arg1):
        shared_test_foo(fixture1, arg1)

Class TestBar:
    test_bar(self, fixture1, fixture2, arg1, arg2):
        bar_result = bar(fixture2, arg1, arg2)
        assert bar_result
        shared_test_foo(fixture1, bar_result)

make_module_from_function?

The make_module_from_function function in plugin.py kind of makes this possible, but is not documented anywhere publicly. Additionally, when called statically from another test I am unaware of how it interacts with the behaves_like functionality and other features like fixtures applied to the enclosing block via pytest.mark.usefixtures and what behavior is preserved or breaks.

For example:

from pytest_describe.plugin import make_module_from_function

def describe_foo():
    test_foo(fixture1, arg1):
        foo_result = foo(fixture1, arg1)
        assert foo_result

def describe_bar():
    test_bar(fixture1, fixture2, arg1, arg2):
        bar_result = bar(fixture2, arg1, arg2)
        assert bar_result
        make_module_from_function(describe_foo).test_foo(fixture1, bar_result)

This works from my testing, but I don't entirely understand its potential repercussions.

Potential solutions:

I think make_module_from_function gets most of the way to a functional solution to this problem. However, it is currently not listed in pytest_describe.__all__ thus requiring manual import from plugin.py, and there is no documentation about it so it is unclear how it behaves when called inside another test. This may be an easy workaround to get similar functionality with minimal effort, but it needs analysis and documentation.

Alternatively, it would be convenient if it were possible for describe-blocks to be automatically evaluated to accessible modules at runtime somehow, potentially through a fixture? This would be a much cleaner solution if it enabled the ability to reference tests via something like describe_foo.test_foo(...), but I recognize this may be a much more difficult solution to implement.

@nyoma-diamond nyoma-diamond changed the title Statically call other tests for test reuse / chain testing? Statically call other tests for test reuse / chain testing Feb 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant