8

在阅读了有关在 Python 中测试私有方法的信息后,特别是参考了这个接受的答案,看来最好只测试公共接口。但是,我的课看起来像这样:

class MyClass:

  def __init__(self):
    # init code

  def run(self):
    self.__A()
    self.__B()
    self.__C()
    self.__D()

  def __A(self):
    # code for __A

  def __B(self):
    # code for __B

  def __C(self):
    # code for __C

  def __D(self):
    # code for __D

本质上,我创建了一个类来通过函数管道处理一些输入数据。在这种情况下,依次测试每个私有函数而不将它们暴露为公共函数会很有帮助。如果单元测试无法执行私有功能,该怎么办?

4

4 回答 4

32

当 Python 将实际执行的代码放在一起时,它会进行一些名称修改。因此,如果您有一个私有方法__Aon MyClass,则需要在单元测试中像这样运行它:

from unittest import TestCase

class TestMyClass(TestCase):
    def test_private(self):
        expected = 'myexpectedresult'
        m = MyClass()
        actual = m._MyClass__A
        self.assertEqual(expected, actual)

问题是关于由单个下划线划分的所谓“受保护”值。这些方法名称没有被破坏,可以简单地显示:

from unittest import TestCase

class A:

    def __a(self):
        return "myexpectedresult"

    def _b(self):
        return "a different result"


class TestMyClass(TestCase):

    def test_private(self):
        expected = "myexpectedresult"
        m = A()
        actual = m._A__a()
        self.assertEqual(expected, actual)

    def test_protected(self):
        expected = "a different result"
        m = A()
        actual = m._b()
        self.assertEqual(expected, actual)
        # actual = m._A__b() # Fails
        # actual = m._A_b()  # Fails
于 2018-05-03T22:15:03.710 回答
15

首先,你可以访问“私人”的东西,不是吗?(或者我在这里遗漏了什么?)

>>> class MyClass(object):
...     def __init__(self):
...             pass
...     def __A(self):
...             print('Method __A()')
... 
>>> a=MyClass()
>>> a
<__main__.MyClass object at 0x101d56b50>
>>> a._MyClass__A()
Method __A()

但是MyClass如果你必须测试内部的东西,你总是可以写一个测试函数:

class MyClass(object):
    ...
    def _method_for_unit_testing(self):
        self.__A()
        assert <something>
        self.__B()
        assert <something>
        ....

当然,这不是最优雅的方式,但它只是类底部的几行代码。

于 2013-03-16T19:28:27.600 回答
0

可能您应该只测试该run()方法。大多数类都有内部方法——在这种情况下,是否所有代码都在__A(),__B()和中并不重要。如果您怀疑或发现问题,那么您可能希望切换到调试器方面并测试私有方法。__C,()__D()run()

于 2013-03-16T19:03:03.707 回答
-2

抱歉,如果您发现这有点无法回答(我认为没有任何普遍有效/无效的决定),但您应该首先决定要遵循哪种通用测试范例单元测试或功能测试?

你决定了单元测试?

  • 然后按照解决方案测试私有 python 方法(您提到的其他已发布问题)

您决定改为功能测试?

  • 然后run按照您的描述测试您的
于 2021-08-12T19:16:32.870 回答