如何测试python模块privates?

时间:2015-03-05 07:35:58

标签: python python-2.7 unit-testing

在python 2.7中,是否可以测试模块私有化?

跑完后:

import unittest

__private_stuff = 1 # if it would have single underscore, it would not be a problem.

class ComplexTestCase(unittest.TestCase):
    def test_internal_symbol(self):
        self.assertEqual(__private_stuff, 1)

unittest.main(__name__)

结果是:

E
======================================================================
ERROR: test_internal_symbol (__main__.ComplexTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\files\y.py", line 7, in test_internal_symbol
    self.assertEqual(__private_stuff, 1)
NameError: global name '_ComplexTestCase__private_stuff' is not defined

----------------------------------------------------------------------

有什么办法吗?
(不修改我想添加测试的代码)

替代品(我想避免)

一种方法是重命名方法。
其他方式是添加额外的重命名符号private_stuff = __private_stuff

但这很快变得非常乏味。
Codebase使用这些' __ xyz'作为公共符号(从其他模块使用),并且有很多这些符号。
总是存在' _xyz'和' xyz'符号。

(试图找到"为什么"的答案,找出唯一合理的解释 是领先的下划线用于标记"修改"正如在数学公式中那样#" prime"用来。 例如xx'相似,但不一样)

2 个答案:

答案 0 :(得分:3)

__private_stuff实际定义在哪里?因为我怀疑它是否在您的测试用例模块中定义。如果确实如此,那么这将有效:

import unittest

__private_stuff = 1 # if it would have single underscore, it would bot be a problem.

class ComplexTestCase(unittest.TestCase):
    def test_internal_symbol(self):
        private_stuff = globals()['__private_stuff']
        self.assertEqual(private_stuff, 1)

unittest.main(__name__)

否则,如果它在某个其他模块中,这应该有效,尽管我没有测试它:

import unittest
import other_module

__private_stuff = 1 # if it would have single underscore, it would bot be a problem.

class ComplexTestCase(unittest.TestCase):
    def test_internal_symbol(self):
        private_stuff = getattr(other_module, '__private_stuff')
        self.assertEqual(private_stuff, 1)

unittest.main(__name__)

答案 1 :(得分:0)

有几种方法可以防止python在你的类中调用名称修改算法

使用getattr检索受测试属性的值(根据1.618的答案):

class ComplexTestCase(unittest.TestCase):
    def test_internal_symbol(self):
        private_stuff = getattr(module_under_test, '__private_stuff')
        self.assertEqual(private_stuff, 1)

将测试方法写在类之外:

def test_internal_symbol(self):
    self.assertEqual(module_under_test.__private_stuff, 1)

class ComplexTestCase(unittest.TestCase):
    test_internal_symbol = test_internal_symbol

将私有属性名称重构为以3个下划线结尾:

class ComplexTestCase(unittest.TestCase):
    def test_internal_symbol(self):
        self.assertEqual(module_under_test.__private_stuff___, 1)