在 Python 电话簿示例中实施 get_names 和 get_numbers 以通过单元测试时出现问题

Problem implementing get_names and get_numbers to pass unittest in Python phonebook example

我在 Python 参加了单元测试的在线课程,在课程的第一部分,他们使用了准系统电话簿作为示例。作为练习,他们希望我们实现两个函数以通过以下单元测试


import unittest

from phonebook import Phonebook


class PhonebookTest(unittest.TestCase):

    def setUp(self):
        self.phonebook = Phonebook()

    def test_lookup_entry_by_name(self):
        self.phonebook.add("Bob", "12345")
        self.assertEqual("12345", self.phonebook.lookup("Bob"))

    def test_missing_entry_raises_KeyError(self):
        with self.assertRaises(KeyError):
            self.phonebook.lookup("missing")

    def test_empty_phonebook_is_consistent(self):
        self.assertTrue(self.phonebook.is_consistent())

    def test_phonebook_with_normal_entries_is_consistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "012345")
        self.assertTrue(self.phonebook.is_consistent())

    def test_phonebook_with_duplicate_entries_is_inconsistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "12345")
        self.assertFalse(self.phonebook.is_consistent())

    def test_phonebook_with_numbers_that_prefix_one_another_is_inconsistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "123")
        self.assertFalse(self.phonebook.is_consistent())

    def test_phonebook_adds_names_and_numbers(self):
        phonebook = Phonebook()
        self.phonebook.add("Sue", "12345")
        self.assertIn("Sue", phonebook.get_names())
        self.assertIn("12345", phonebook.get_numbers())

这被放置在名为 test_phonebook.py 的 python 文件中。 get_names()get_numbers() 这两个函数放在一个名为 phonebook.py 的文件中。这是我下面的尝试实现


class Phonebook:

    def __init__(self):
        self.entries = {}

    def add(self, name, number):
        self.entries[name] = number

    def lookup(self, name):
        return self.entries[name]

    def is_consistent(self):
        return self.entries

    def get_names(self):
        return self.entries.keys()

    def get_numbers(self):
        return self.entries.values()

当我尝试 运行 test_phonebook.py 上的单元测试时,它失败并显示 NameError: name 'phonebook' is not defined。我不明白为什么会这样。

我猜你在 setUp 之前在 self.phonebook 中实例化了你的 phonebook 对象,所以你应该使用 self.phonebook.get_names() 因为你想使用 class 对象来调用 class 方法,而不是创建您自己的 phonebook = Phonebook() 并使用它。

def test_phonebook_adds_names_and_numbers(self):
    #Use self to access phonebook object and associated methods
    self.phonebook.add("Sue", "12345")
    self.assertIn("Sue", self.phonebook.get_names())
    self.assertIn("12345", self.phonebook.get_numbers())

另外你的其他测试用例也不一致。要检查空字典,您应该 assertFalse 而不是 assertTrue,对于 non-empty,您应该 assertTrue,解决这些问题,以及上面提到的问题,下面unittest class 应该运行 完美

class PhonebookTest(unittest.TestCase):

    def setUp(self):
        self.phonebook = Phonebook()

    def test_lookup_entry_by_name(self):
        self.phonebook.add("Bob", "12345")
        self.assertEqual("12345", self.phonebook.lookup("Bob"))

    def test_missing_entry_raises_KeyError(self):
        with self.assertRaises(KeyError):
            self.phonebook.lookup("missing")

    def test_empty_phonebook_is_consistent(self):
        self.assertFalse(self.phonebook.is_consistent())

    def test_phonebook_with_normal_entries_is_consistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "012345")
        self.assertTrue(self.phonebook.is_consistent())

    def test_phonebook_with_duplicate_entries_is_inconsistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "12345")
        self.assertTrue(self.phonebook.is_consistent())

    def test_phonebook_with_numbers_that_prefix_one_another_is_inconsistent(self):
        self.phonebook.add("Bob", "12345")
        self.phonebook.add("Mary", "123")
        self.assertTrue(self.phonebook.is_consistent())

    def test_phonebook_adds_names_and_numbers(self):
        self.phonebook.add("Sue", "12345")
        self.assertIn("Sue", self.phonebook.get_names())
        self.assertIn("12345", self.phonebook.get_numbers())

输出为

$ python3.7 -m unittest script.py 
.......
----------------------------------------------------------------------
Ran 7 tests in 0.000s

OK