Question

I have a working test suite that runs with Nose.

I recently realized I needed to add things to my overall setUp(), as triggered by a variable found in each individual test (the variable gets updated by our version control system).

I have added an __init__() to my BaseTest.py and my individual test. However, I get ValueError: no such test method in <class 'my_test.check_error_test'>: runTest

From googling, it looks like this has to do with a unittest loader. But Nose always took care of all of the loaders before.

I'm guessing this has to do with the fact that I am touching the methodName attribute after Nose sets it, but I cannot figure out what I should be setting it to, ESPECIALLY since I use various Nose Plugins. Or perhaps there's a better way. What do I need to do differently?

BaseTest.py

import unittest

class BaseTest(unittest.TestCase):
    def __init__(self, methodName='runTest', p4rev=None):
        super(BaseTest, self).__init__(methodName)
        self.p4rev = p4rev

    def setUp(self):
        triggerSomething(p4rev)

My_test.py

from BaseTest import BaseTest

rev = '12345'

class CheckError_Test(BaseTest):
    def __init__(self, rev):
        super(CheckError_Test, self).__init__(p4rev=rev)

    dosomething()

NOTE: If I don't have use super(BaseTest, self).__init__(methodName) I get an error: Attribute error: 'check_error_test' object has no attribute '_testMethodName'. Hence its inclusion

To Clarify: One comment suggests duplicate post, however linked post is about how to run tests in general, while this post asks how to access specific variables within a given test at runtime.

Was it helpful?

Solution

I would just use built in attributes plugin to pass the information down:

in my_test.py:

from base_test import BaseTest
from nose.plugins.attrib import attr

rev = '12345'

@attr(rev=rev)
class CheckError_Test(BaseTest):
    def test_me(self):
        assert self.rev == rev

in base_test.py:

import unittest

def triggerSomething(text):
    print "revision was set to",  text

class BaseTest(unittest.TestCase):
    def setUp(self):
        p4rev = getattr(self, 'rev')
        triggerSomething(p4rev)

shell output:

$ nosetests my_test.py --pdb -s

revision was set to 12345
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK

OTHER TIPS

You could make BaseTest an abstract class which requires instances of derived classes to have self.p4rev set.

class BaseTest(unittest.TestCase):

    # Note: subclasses must provide the p4rev attribute
    def setUp(self):
        triggerSomething(self.p4rev)

Then in your test script

from BaseTest import BaseTest

rev = '12345'

class CheckError_Test(BaseTest):
    def setUp(self):
        self.p4rev = rev
        BaseTest.setUp(self)  # Or use super() if you like

You could optionally use the ABCMeta class to mark BaseTest as an abstract class more clearly, and define p4rev as an abstract property.

I'm pretty sure there are ways to make nose use a customer TestLoader to instantiate your tests, but this seems to me a simpler alternative.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top