You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行字典操作函数测试用例时出现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:12:00