I just added a unit test for project PTable(PreetyTable) which works directly but failed with nose

183 views Asked by At

Project source is here: https://github.com/kxxoling/PTable/tree/develop

I added a new test file test_utils into tests dir. When I move it out of that dir(because of importation) I can run the unit tests direct.

It is said that there is no error with my tests. But something goes wrong when I run all the tests together with nose: nosetests --with-coverage --cover-package=prettytable --cover-min-percentage=75 will get an error:

TypeError: _() takes exactly 1 argument (0 given)

Very strange. My test file is like this:

import unittest
from prettytable.prettytable import _char_block_width

fixtures = {
    'normal': (1, u'12345qwerljk/.,WESD'),
    'chs': (2, u'石室诗士施氏嗜狮誓食十狮'),
    'jp': (2, u'はじめまして'),
    'hangul': (2, u'우리글자언문청'),
    'full_width_latin': (2, u'XYZ[\]^_xyz{|}~⦅'),
}

def _width_test_factory(width, words):
    def _(self):
        map(lambda x: self.assertEqual(width, _char_block_width(ord(x))),
            list(words))
    return _


class CharBlockWidthTest(unittest.TestCase):
    pass

for name in fixtures:
    test_name = 'test_%s' % name
    test_func = _width_test_factory(*fixtures[name])
    test_func.__name__ = test_name
    print test_func
    setattr(CharBlockWidthTest, test_name, test_func)
1

There are 1 answers

8
Freek Wiekmeijer On

Method _(self) can only be executed inside the context of a class instance (which will supply the implicit parameter self. Not when nose is importing the modules and parsing them to find test functions.

The "nose-way" would be to simply move the test functions into the CharBlockWidthTest class. The three-layered composite function which is added to the class dynamically with setattr is simply a bit too complex for the testcase discovery mechanism.

I believe the following code should be a nose-friendly equivalent (not tested).

class CharBlockWidthTest(unittest.TestCase):

    def test_fixtures(self):
        for name, val in fixtures.items():
            width, words = val
            for x in words:
                self.assertEqual(width, _char_block_width(ord(x)),
                                 "Error on fixture %s: word %s" % \
                                 (name, word))