使用 self 与 cls 访问单元测试中的变量

alv*_*vas 2 python unit-testing self class-method

假设我有一个简单的类对象,看起来像某种Counter(当然它还有其他功能,但超出了这个问题的范围):

from collections import Counter

class Vocabulary:
    def __init__(self, words):
        self.vocab = Counter(words)
Run Code Online (Sandbox Code Playgroud)

并将Vocabulary类添加到单元测试中,我可以setUpClass这样使用类方法:

import unittest

class VocabularyTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.vocab = Vocabulary(["z", "a", "b", "c", "f", "d", "e", "g", "a", "d", "b", "e", "w"])


    def test_counts_set_correctly(self):
        self.assertEqual(cls.vocab["a"], 2)
Run Code Online (Sandbox Code Playgroud)

或者我可以只使用self

class VocabularyTests(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(VocabularyTests, self).__init__(*args, **kwargs)
        self.vocab = Vocabulary(["z", "a", "b", "c", "f", "d", "e", "g", "a", "d", "b", "e", "w"])

    def test_counts_set_correctly(self):
        self.assertEqual(self.vocab["a"], 2)
Run Code Online (Sandbox Code Playgroud)

以上两者都可以正常工作。但是如果我有一种非Pythonic 模式怎么办:

import unittest

class VocabularyTests(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.vocab = Vocabulary(["z", "a", "b", "c", "f", "d", "e", "g", "a", "d", "b", "e", "w"])


    def test_counts_set_correctly(self):
        self.assertEqual(self.vocab["a"], 2)
Run Code Online (Sandbox Code Playgroud)

根据Python 类中“cls”变量的用途是什么?,这只是一个编码约定,但是单元测试的第三个版本与@classmethod使用self.vocab和前两个更惯用的测试之间有什么区别吗?

wim*_*wim 5

对于unittest.TestCase子类,不要在__init__. 那不是它的目的。如果您希望每个测试方法执行一次设置,请将其放在这里:

def setUp(self):
    ...
Run Code Online (Sandbox Code Playgroud)

如果您希望每个测试类执行一次安装程序,请将其放在这里:

@classmethod
def setUpClass(cls):
    ...
Run Code Online (Sandbox Code Playgroud)

最后我们要纠正一个错误的观念。从技术上讲,这之间没有区别:

@classmethod
def setUpClass(cls):
    ...
Run Code Online (Sandbox Code Playgroud)

和这个:

@classmethod
def setUpClass(self):
    ...
Run Code Online (Sandbox Code Playgroud)

第二个只是第一个的更令人困惑/糟糕的编写方式。