执行字典操作函数测试用例时出现AssertionError的原因排查
字典球员添加函数测试AssertionError成因分析
你编写了三个操作字典的函数(实现球员信息查询、添加、删除),使用unittest框架测试时,add_player_to_dict函数的测试用例抛出AssertionError,实际返回的字典与预期结果不匹配。
完整代码
主程序与自定义函数
import unittest def main(): # initial roster brave_roster = { "Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273", "Ronald Acuna": "AB: 467, R: 71, H: 124, HR: 15, AVG: 0.266", } print("\t *** Braves Stats! ***\n") print("Welcome to My Braves Stats! What can I do for you?\n") print(" 1. Search for a player") print(" 2. Add a new player") print(" 3. Remove a player") name = brave_roster stats = brave_roster choice = input("Please type your choice number:") if (choice == "1"): name = input("Enter the name of the player you want to lookup:\n") new_roster = lookup_player(brave_roster, name) elif (choice == "2"): name = input("Enter the name of the player you want to add:\n") stats = input("Please add the player's stats:\n") new_play = add_player_to_dict(brave_roster,name,stats) else: (choice == "3") name = input("Enter the name of the player you want to remove:\n") delete_in_dict(brave_roster,name) # 自定义函数 def lookup_player(brave_roster,name): if name in brave_roster: print("Here are", [name], "'s stats:", brave_roster[name]) return brave_roster[name] else: print("The player doesn't exist in the roster") return "N/A" def add_player_to_dict(brave_roster,name,stats): if name not in brave_roster: brave_roster[name] = stats print("Here's the complete team roster:\n") for name, stats in brave_roster.items(): print(name, ':', stats) else: print("That player does not exist in our roster") return brave_roster def delete_in_dict(brave_roster, name): if name in brave_roster: del brave_roster[name] return brave_roster else: print("\n uh typo?", [name], "does not play for us") return brave_roster main()
测试代码
class TestDictFunctions(unittest.TestCase): def test_search_player_success(self): test_dict = { "Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273" } actual = test_dict["Austin Riley"] expected = lookup_player(test_dict, "Austin Riley") self.assertEqual(actual, expected) def test_search_player_no_result(self): test_dict = { "Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273" } actual = "N/A" expected = lookup_player(test_dict, "Ronald Acuna") self.assertEqual(actual, expected) def test_add_player_sucess(self): test_dict = { "Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273" } actual = { "Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273", "Ronald Acuna": "AB: 467, R: 71, H: 124, HR: 15, AVG: 0.266" } expected = add_player_to_dict(test_dict, "Ronald Acuna", "AB: 467, R: 71, H: 124, HR: 15, AVG: 0.266") self.assertEqual(actual, expected) def test_add_player_duplicate(self): test_dict = {"Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273"} actual = {"Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273", "Austin Riley(2)": "AB: 350, R: 20, H: 120, HR: 5, AVG: 0.214"} expected = add_player_to_dict(test_dict, "Austin Riley", "AB: 350, R: 20, H: 120, HR: 5, AVG: 0.214") self.assertEqual(actual, expected) def test_delete_player_sucess(self): test_dict = {"Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273"} expected = {} actual = delete_in_dict(test_dict, "Austin Riley") self.assertEqual(actual, expected) def test_delete_word_no_result(self): test_dict = {"Austin Riley": "AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273"} expected = test_dict actual = delete_in_dict(test_dict, "Shohei Ohtani") self.assertEqual(actual, expected) # uncomment to run tests unittest.main()
错误信息
self.assertEqual(actual, expected)
AssertionError: {'Aus[51 chars].273', 'Austin Riley(2)': 'AB: 350, R: 20, H: [19 chars]214'} != {'Aus[51 chars].273'}
- {'Austin Riley': 'AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273',
? ^- {'Austin Riley': 'AB: 615, R: 90, H: 168, HR: 38, AVG: 0.273'}
? ^- 'Austin Riley(2)': 'AB: 350, R: 20, H: 120, HR: 5, AVG: 0.214'}
成因分析
1. add_player_to_dict函数逻辑缩进错误
函数中的else块与for循环绑定,而非外层的if判断:
- 当添加新球员(
name不在字典中)时,执行完添加操作后,会遍历打印字典,随后触发for循环的else块(因为循环正常结束,没有break),错误打印"That player does not exist in our roster",逻辑完全混乱。 - 当添加重复球员时,
if name not in brave_roster不成立,跳过添加,直接进入for循环打印,然后同样触发else块,提示错误信息,且没有执行任何添加操作。
2. 测试用例与函数实际行为不匹配
test_add_player_duplicate测试用例预期添加重复名字时,会自动创建Austin Riley(2)的新键,但你的add_player_to_dict函数根本没有处理重复名字的逻辑——遇到已存在的名字时,不会修改字典,自然不会生成带序号的新键,这直接导致断言失败。
3. 函数副作用(次要问题)
函数直接修改传入的原字典,而非返回新字典,虽然测试用例是基于修改原字典的逻辑,但这种设计容易引发意外的状态变更,也是需要注意的点。
修复示例
处理重复名字的版本
def add_player_to_dict(brave_roster, name, stats): original_name = name counter = 1 # 循环检测名字是否存在,生成带序号的新名字 while name in brave_roster: counter += 1 name = f"{original_name}({counter})" # 添加球员 brave_roster[name] = stats print("Here's the complete team roster:\n") for player_name, player_stats in brave_roster.items(): print(player_name, ':', player_stats) return brave_roster
禁止重复添加的版本
def add_player_to_dict(brave_roster, name, stats): if name not in brave_roster: brave_roster[name] = stats print("Here's the complete team roster:\n") for player_name, player_stats in brave_roster.items(): print(player_name, ':', player_stats) else: print("That player already exists in our roster") return brave_roster
内容的提问来源于stack exchange,提问作者Pislibsco
相关产品推荐
相关产品推荐

