如何正确地对链表进行单元测试(使用 Python)?
How to properly unit-test a linked list (using Python)?
我是 TDD 新手。我已经创建了所有主要功能(插入、搜索、删除等)。这是我的 insert_beginning() 函数:
def insert_beginning(self, node):
'''
Inserts a Node to the beginning of the list.
'''
node.set_next(self.head)
self.head = node
我的问题是,如何正确地对该函数进行单元测试?我能想到的唯一方法是:
class ListFunctionsTest(unittest.TestCase):
def setUp(self):
self.list1 = LinkedList()
self.node1 = Node(1)
def test_insert_beginning(self):
self.list1.insert_beginning(self.node1)
self.assertEqual(self.list1.__str__(), "1")
但是 test_insert_beginning() 函数依赖于我的
__str__() # string representation of my linked list
函数。我感觉我测试它的方式不正确(因为当我决定改变我的链接列表的表示方式时,我最终不得不重写我的测试用例)。有没有一种方法可以在不依赖于我创建/自定义的另一个函数的情况下测试我的 insert_beginning() 函数?
编辑:对于那些想知道的人,目前,我的链表的字符串表示只是我的节点的字符串表示,用逗号分隔。例如,具有节点 1、2 和 "a" 的链表将表示为:
1, 2, "a"
但是,我正计划更改链表的字符串表示形式(计划更改 __ str __() 函数)。这是我意识到我进行单元测试的方式可能不正确的时候。
编辑 2(一条评论建议我创建一个函数来帮助我在链表中找到一个项目的索引):假设存在一个名为 index_of(self, item) 的函数,并且这个函数查找项目的索引。假设这是 index_of(self, item) 的单元测试,并假设测试用例成功通过。
def test_index_of(self):
myList = LinkedList()
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
myList.head = node1
node1.next = node2
node2.next = node3
self.assertEqual(self.myList.index_of(1), 0)
self.assertEqual(self.myList.index_of(2), 1)
self.assertEqual(self.myList.index_of(3), 2)
现在,我可以依靠 index_of(self, item) 函数来确定 insert_beginning(self, node) 是否正常工作吗?换句话说,如果我的 test_insert_beginning() 函数是:
可以吗?
class ListFunctionsTest(unittest.TestCase):
def setUp(self):
self.list1 = LinkedList()
self.node1 = Node(1)
def test_insert_beginning(self):
self.list1.insert_beginning(self.node1)
self.assertEqual(self.list1.index_of(1), 0)
你说得很好。您不想将自己绑定到列表的任意 String 表示形式,这可能会改变。检查这个的“正确”方法是检查列表中的 values。也就是说,您应该单独检查所有 post 条件,而不是检查字符串表示形式:
第一个值为1
之前的值不存在(出错时做任何你想发生的事情)
下一个值与上一个值相同
大小为1
...
当然,对于支持此方法的方法,您必须进行单独的单元测试。
我是 TDD 新手。我已经创建了所有主要功能(插入、搜索、删除等)。这是我的 insert_beginning() 函数:
def insert_beginning(self, node):
'''
Inserts a Node to the beginning of the list.
'''
node.set_next(self.head)
self.head = node
我的问题是,如何正确地对该函数进行单元测试?我能想到的唯一方法是:
class ListFunctionsTest(unittest.TestCase):
def setUp(self):
self.list1 = LinkedList()
self.node1 = Node(1)
def test_insert_beginning(self):
self.list1.insert_beginning(self.node1)
self.assertEqual(self.list1.__str__(), "1")
但是 test_insert_beginning() 函数依赖于我的
__str__() # string representation of my linked list
函数。我感觉我测试它的方式不正确(因为当我决定改变我的链接列表的表示方式时,我最终不得不重写我的测试用例)。有没有一种方法可以在不依赖于我创建/自定义的另一个函数的情况下测试我的 insert_beginning() 函数?
编辑:对于那些想知道的人,目前,我的链表的字符串表示只是我的节点的字符串表示,用逗号分隔。例如,具有节点 1、2 和 "a" 的链表将表示为:
1, 2, "a"
但是,我正计划更改链表的字符串表示形式(计划更改 __ str __() 函数)。这是我意识到我进行单元测试的方式可能不正确的时候。
编辑 2(一条评论建议我创建一个函数来帮助我在链表中找到一个项目的索引):假设存在一个名为 index_of(self, item) 的函数,并且这个函数查找项目的索引。假设这是 index_of(self, item) 的单元测试,并假设测试用例成功通过。
def test_index_of(self):
myList = LinkedList()
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
myList.head = node1
node1.next = node2
node2.next = node3
self.assertEqual(self.myList.index_of(1), 0)
self.assertEqual(self.myList.index_of(2), 1)
self.assertEqual(self.myList.index_of(3), 2)
现在,我可以依靠 index_of(self, item) 函数来确定 insert_beginning(self, node) 是否正常工作吗?换句话说,如果我的 test_insert_beginning() 函数是:
可以吗?class ListFunctionsTest(unittest.TestCase):
def setUp(self):
self.list1 = LinkedList()
self.node1 = Node(1)
def test_insert_beginning(self):
self.list1.insert_beginning(self.node1)
self.assertEqual(self.list1.index_of(1), 0)
你说得很好。您不想将自己绑定到列表的任意 String 表示形式,这可能会改变。检查这个的“正确”方法是检查列表中的 values。也就是说,您应该单独检查所有 post 条件,而不是检查字符串表示形式:
第一个值为1
之前的值不存在(出错时做任何你想发生的事情)
下一个值与上一个值相同
大小为1
...
当然,对于支持此方法的方法,您必须进行单独的单元测试。