Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Propagating fixtures to test class attribute

See original GitHub issue

Issue Description

Hi there.

I’d like to share my thought about using fixture in tests classes and maybe ask some advise. Current issue is related to two useful methods for newcomers from setuptools: (mark.usefixture and autouse - option for fixture) and using this stuff in Test classes.

First thing - (mark.usefixture) allows to define fixtures fro whole test class, but it does not provide ability to get access to this fixture from the test. For this purposes I have to define fixtures as parameters of test methods, like:

class TestExample():                  
    def test_one(self, param):               
        param.return_value = 100

honestly it’s not a big deal, when you have couple of the test. However for huge numbers of the test, where I have the same fixtures, I’d like to hide avoid using fixture parameter. So I have to do it in the such way:

class TestExample():                  
    def init_fixture(param1, param2):
        self.param1 = param1         
        self.param2 = param2         

    def test_one(self):               
        self.param1.return_value = 100
        self.param2.return_value = 200

So the main idea -to hide explicitly mentioned fixtures of the function and providing them as class attribute. It’s also can be useful, when you port some test from testscenario extension, where parameters are available as class attributes.

I suppose, that it can be done by improving “mark.usefixtures” decorator, where it allows to add fixtures as class attributes. So potentially decorator can have syntax, like: mark.usefixtures(*args, as_attrs=False), where *args - is list of fixtures, as previously and as_attrs is a flag (defailt is False), which save fixtures as class attributes. In case if function has not class it may be ignored or raise warning message.

Finally I suppose, that it can be done by adding minimal logic here:

def pytest_pyfunc_call(pyfuncitem):                 
    testfunction = pyfuncitem.obj                   
+   if pyfuncitem.cls:
+         for k, v in pyfuncitem.funcargs:
+             setattr(pyfuncitem.cls, k, v) 
    if pyfuncitem._isyieldedfunction():             
        funcargs = pyfuncitem.funcargs              
        testargs = {}                               
        for arg in pyfuncitem._fixtureinfo.argnames:
            testargs[arg] = funcargs[arg]           
    return True        

Please correct me if I wrong somewhere or share your opinion about such change in the project.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:26 (18 by maintainers)

github_iconTop GitHub Comments

nicoddemuscommented, Jul 28, 2017

@skraynev great, glad it worked out.

Can I persuade you to write a short post about this to the pytest-tricks blog? 😉

cc @hackebrot

nicoddemuscommented, Jul 26, 2017

yes, imho a explicit class level fixture that sets the attribute is waaaaay more transparent and already supported directly without anyhacks

Indeed it might be better to support this using something else other than pytest.mark.usefixtures, I don’t know for certain until we see some working code though.

But not sure how much more transparent using something else other than pytest.mark.usefixtures would be, to be honest.

Instead of:

@pytest.mark.usefixtures('tmpdir', 'foobar', as_attrs=True)
class Test:

It would be some other construct at the class level anyway, perhaps:

@pytest.fixtures_as_attrs('tmpdir', 'foobar')
class Test:

Why would be the first be more transparent than the second, from a user’s point of view?

Unless your point is that using marks for this would be problematic from an implementation POV, but that’s a different discussion.

from my pov usefixtures is a unfortunate hack and we should completely remove the need to have it

I’m curious, was @pytest.mark.usefixtures added with the intent of making it easy for groups of tests to “auto use” fixtures without declaring them explicitly? Because for a single test case I don’t see much value in mark.usefixtures as you can just declare that parameter there, but for marking tests in classes and modules it makes more sense. Just curious because I don’t know pytest for so long. 😁

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fixtures as class attributes - pytest-tricks
The first approach uses a new decorator for test classes. This decorator injects an autouse fixture in the decorated class; this fixture ......
Read more >
Understand 5 Scopes of Pytest Fixtures | by Xiaoxu Gao
Pytest fixtures have five different scopes: function, class, module, ... This special decorator adds the fixture to a test class, and the fixture...
Read more >
Testing Change Detection • Angular -
By using the ATB and fixtures we can inspect the component's view through fixture.debugElement and also trigger a change detection run by calling...
Read more >
Pytest fixture for a class through self not as method argument
I would like to be able to access the fixture by giving the fixture as an attribute of the test class. In this...
Read more >
Component testing scenarios - Angular
To simulate user input, find the input element and set its value property. You will call fixture.detectChanges() to trigger Angular's change detection. But ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Post

No results found

github_iconTop Related Hashnode Post

No results found