nose-devs / nose

nose is nicer testing for python
http://readthedocs.org/docs/nose/en/latest/
1.36k stars 395 forks source link

setup() fixture not called for generators which depend on setup #734

Open fophillips opened 11 years ago

fophillips commented 11 years ago

How to reproduce

from nose.tools import *

class TestSomeStuff:
    def setup(self):
        print("\nSetting up...\n")
        self.foo = "bar"
        self.n = 10

    def test_one_thing(self):
        assert_equal(self.foo, "bar")

    def test_five_things(self):
        for _ in range(5):
            yield(self.check_one_thing)

    def test_n_things(self):
        for _ in range(self.n):
            yield(self.check_one_thing)

    def check_one_thing(self):
        assert_equal(self.foo, "bar")

Expected behaviour All tests pass

Actual behaviour

% nosetests -sv nose_setup_generator.py
nose_setup_generator.TestSomeStuff.test_five_things ...
Setting up...

ok
nose_setup_generator.TestSomeStuff.test_five_things ...
Setting up...

ok
nose_setup_generator.TestSomeStuff.test_five_things ...
Setting up...

ok
nose_setup_generator.TestSomeStuff.test_five_things ...
Setting up...

ok
nose_setup_generator.TestSomeStuff.test_five_things ...
Setting up...

ok
Failure: AttributeError ('TestSomeStuff' object has no attribute 'n') ... ERROR
nose_setup_generator.TestSomeStuff.test_one_thing ...
Setting up...

ok

======================================================================
ERROR: Failure: AttributeError ('TestSomeStuff' object has no attribute 'n')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/nose-1.3.0-py3.3.egg/nose/failure.py", line 38, in runTest
    raise self.exc_val.with_traceback(self.tb)
  File "/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/nose-1.3.0-py3.3.egg/nose/loader.py", line 287, in generate
    for test in g():
  File "/Users/fophillips/Code/testing/nose_setup_generator.py", line 17, in test_n_things
    for _ in range(self.n):
AttributeError: 'TestSomeStuff' object has no attribute 'n'

----------------------------------------------------------------------
Ran 7 tests in 0.013s

FAILED (errors=1)

Platform and version OS X 10.8.4

% nosetests -V
nosetests version 1.3.0
% python3 -V
Python 3.3.2

More information https://gist.github.com/fophillips/6719447

jszakmeister commented 10 years ago

The issue here is that setup is not called until the check function from the generator is going to be run. What you're suggesting is that nose should call setup() before running the generator, and I don't think that's wise. Generators need to be iterated through to get test counts and formulate test cases.

If you want to variables like self.n, you should put it into setupClass():

from nose.tools import *

class TestSomeStuff:
    @classmethod
    def setupClass(cls):
        cls.n = 10

    def setup(self):
        self.foo = "bar"

    def test_one_thing(self):
        assert_equal(self.foo, "bar")

    def test_five_things(self):
        for _ in range(5):
            yield(self.check_one_thing)

    def test_n_things(self):
        for _ in range(self.n):
            yield(self.check_one_thing)

    def check_one_thing(self):
        assert_equal(self.foo, "bar")

This will work as expected.

drem-darios commented 8 years ago

What about for the tearDown method?

jszakmeister commented 8 years ago

What about for the tearDown method?

I don't understand what you are asking for.