nose2 icon indicating copy to clipboard operation
nose2 copied to clipboard

When I use generator tests, setUp() doesn't get run before the test

Open fasaxc opened this issue 11 years ago • 12 comments

I wrote a test like this:

def test_rcv_request(self):
    def do_rcv_fanout_test(type, function_name):
        ...
    yield do_rcv_fanout_test, "create", "create_it"
    yield do_rcv_fanout_test, "create", "create_it"

The tests are detected and run but self.setUp() doesn't get run before either test.

fasaxc avatar May 08 '13 21:05 fasaxc

I can't reproduce this. With this test module:

from nose2.compat import unittest

class Test(unittest.TestCase):
    def setUp(self):
        print "setup!"

    def test_rcv_request(self):
        def do_rcv_fanout_test(type, function_name):
            print type, function_name
        yield do_rcv_fanout_test, "create", "create_it"
        yield do_rcv_fanout_test, "create", "create_it"

I get this output:

$ nose2 -v
test_rcv_request:1
'create', 'create_it' (test.Test) ... setup!
create create_it
ok
test_rcv_request:2
'create', 'create_it' (test.Test) ... setup!
create create_it
ok

----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

jpellerin avatar May 09 '13 13:05 jpellerin

Ah, looks like setup is being run but on the wrong instance:

class Test(unittest.TestCase):
    def setUp(self):
        print "setup! instance: ", id(self)
        self.foo = "Bar"

    def test_rcv_request(self):
        def do_rcv_fanout_test(type, function_name):
            print "Test instance: ", self, id(self)
            print type, function_name, self.foo
        yield do_rcv_fanout_test, "create", "create_it"
        yield do_rcv_fanout_test, "create", "create_it"

Gives

setup! instance: 3073307340 Test instance: test_rcv_request (src.meta.switchmgr.test.testswitchmgr.Test) 3073306764 Ecreate create_it setup! instance: 3071367884 Test instance: test_rcv_request (src.meta.switchmgr.test.testswitchmgr.Test) 3073306764 E

Note the different ID numbers between the setUp and test being run.

fasaxc avatar May 09 '13 16:05 fasaxc

That's correct behavior, actually. The generator tests are generated as real test cases, so just like normal test case methods each one is run in a new instance of the test case class.

On Thu, May 9, 2013 at 12:15 PM, Shaun Crampton [email protected]:

Ah, looks like setup is being run but on the wrong instance:

class Test(unittest.TestCase): def setUp(self): print "setup! instance: ", id(self) self.foo = "Bar"

def test_rcv_request(self):
    def do_rcv_fanout_test(type, function_name):
        print "Test instance: ", self, id(self)
        print type, function_name, self.foo
    yield do_rcv_fanout_test, "create", "create_it"
    yield do_rcv_fanout_test, "create", "create_it"

Gives

setup! instance: 3073307340 Test instance: test_rcv_request (src.meta.switchmgr.test.testswitchmgr.Test) 3073306764 Ecreate create_it setup! instance: 3071367884 Test instance: test_rcv_request (src.meta.switchmgr.test.testswitchmgr.Test) 3073306764 E

Note the different ID numbers between the setUp and test being run.

— Reply to this email directly or view it on GitHubhttps://github.com/nose-devs/nose2/issues/80#issuecomment-17673329 .

jpellerin avatar May 09 '13 16:05 jpellerin

But shouldn't the setUp also be run on the same generated test case? I was expecting a generated test to behave just as if I'd added multiple extra test methods to my class. Right now, the code above hits an exception when it tries to access self.foo because self points to a different instance to the setUp.

fasaxc avatar May 09 '13 16:05 fasaxc

Ah, I see what you're saying now. Sorry I misunderstood. That does seem like a bug.

On Thu, May 9, 2013 at 12:49 PM, Shaun Crampton [email protected]:

But shouldn't the setUp also be run on the same generated test case? I was expecting a generated test to behave just as if I'd added multiple extra test methods to my class. Right now, the code above hits an exception when it tries to access self.foo because self points to a different instance to the setUp.

— Reply to this email directly or view it on GitHubhttps://github.com/nose-devs/nose2/issues/80#issuecomment-17675198 .

jpellerin avatar May 09 '13 16:05 jpellerin

The parameterize plugin looks like it behaves correctly, so the fix is probably to make the generator plugin work more like parameterize. Which would be a good thing anyway.

On Thu, May 9, 2013 at 12:55 PM, jason pellerin [email protected] wrote:

Ah, I see what you're saying now. Sorry I misunderstood. That does seem like a bug.

On Thu, May 9, 2013 at 12:49 PM, Shaun Crampton [email protected]:

But shouldn't the setUp also be run on the same generated test case? I was expecting a generated test to behave just as if I'd added multiple extra test methods to my class. Right now, the code above hits an exception when it tries to access self.foo because self points to a different instance to the setUp.

— Reply to this email directly or view it on GitHubhttps://github.com/nose-devs/nose2/issues/80#issuecomment-17675198 .

jpellerin avatar May 09 '13 17:05 jpellerin

Ah, the parametrize plugin looks like it'll be nicer for my use case anyway. I'll switch to that.

fasaxc avatar May 09 '13 18:05 fasaxc

Parameterize is better for almost all cases, I think. But I should still fix generators. :)

On Thu, May 9, 2013 at 2:48 PM, Shaun Crampton [email protected]:

Ah, the parametrize plugin looks like it'll be nicer for my use case anyway. I'll switch to that.

— Reply to this email directly or view it on GitHubhttps://github.com/nose-devs/nose2/issues/80#issuecomment-17682164 .

jpellerin avatar May 09 '13 19:05 jpellerin

I'm also having this issue, but cannot use parameters because they are randomized values. Is there a quick fix?

trilogysci avatar Jun 05 '13 18:06 trilogysci

Maybe:

@params(*random_value_generator())
def test ...

... as far as fixing in nose2 itself, no, it won't be quick. The generators plugin needs a pretty major rewrite.

On Wed, Jun 5, 2013 at 2:03 PM, trilogysci [email protected] wrote:

I'm also having this issue, but cannot use parameters because they are randomized values. Is there a quick fix?

— Reply to this email directly or view it on GitHubhttps://github.com/nose-devs/nose2/issues/80#issuecomment-18995662 .

jpellerin avatar Jun 05 '13 18:06 jpellerin

This bug make impossibile to run tests on a data loaded for an external file or db

lucagiove avatar Jan 19 '18 15:01 lucagiove

I made the fixture working by adding the variables in the class directly instead of creating them in setUpClass method

eg:

class TestAvro(unittest.TestCase):

    products = json.load(open('products.json'))
    contents = json.load(open('contents.json'))

    @classmethod
    def setUpClass(cls):
        pass

    def test_with_yield(self):

lucagiove avatar Jan 24 '18 18:01 lucagiove