如何为Python任务管理器函数编写有效单元测试?
问题:Python任务管理器单元测试无效,全部通过但无法验证结果
我写了一个Python任务管理器程序,开发完成后要给所有函数写单元测试。这些函数互相关联还涉及文件处理,而且几乎没有返回值,没法用断言验证结果。不管测试内容写得多离谱,所有测试全通过,我怀疑测试根本没起到作用。下面是我的任务管理器代码和已写的测试代码,求帮忙解决。
任务管理器程序代码
import datetime def user_information(ussnm, pssd): name = input("Enter your name: ") address = input("Enter your address: ") age = input("Enter your age: ") ussnm_ = f"{ussnm}'s tasks.txt" with open(ussnm_, 'a') as f: f.write(pssd) f.write(f"\nName: {name}\n") f.write(f"Address: {address}\n") f.write(f"Age: {age}\n") f.write("\n") def signup(): print("Create a new account") username = input("Enter your Username: ") password = "" #input("Enter your Password: ") while True: if len(password) < 8: print("Password too short. Try again.") password = input("Enter your Password: ") else: user_information(username, password) print("Account created successfully. Log in to your account") login() def login(): user_name = input("Enter your username: ") pass_word = input("Enter the password: ") try: usernm = f"{user_name}'s tasks.txt" with open(usernm, 'r') as f: #p is the saved password #list index out of range p = f.readlines(0)[0] if pass_word.strip() == p.strip(): print("Log in successful!") response = input("Choose: \n1 To view your list of tasks \n2 To add task \n3 To update task status \n4 View task status \n") #To view list of task if response == '1': view_data(usernm) #To add task elif response == '2': task_information(usernm) elif response == '3': task_update(usernm) elif response == '4': task_update_viewer(usernm) else: print("No such option. Try again") login() else: print("Your username or password is incorrect") login() except Exception as e: print(e) login() #To view list of task def view_data(username): with open(username, 'r') as v: print(v.read()) #To add task def task_information(username): no_of_task = int(input("How many tasks do you want to add? ")) with open(username, 'a') as t: #doesn't keep asking for tasks for the number of times inputted, only asks once for i in range(1, no_of_task+1): task = input("Enter a new task: ") target = input("How much time do you want to use on this task? ") tas = f"Task {str(i)}:" tar = f"Target {str(i)}:" t.write(f"{tas} {task} \n") t.write(f"{tar} {target} \n") #to stop adding tasks stop = input("Press space bar to stop adding tasks. Otherwise, press enter: ") if stop == " ": print("Task(s) added") break #To update tasks def task_update(username): #adding a weird name (mayo's tasks.txt's tasks) username = f"{username}'s tasks.txt" task_completed = input("Enter completed tasks: ") task_pending = input("Enter pending tasks: ") task_ongoing = input("Enter ongoing tasks: ") with open(username, 'a') as up: date = str(datetime.datetime.now()) up.write(f"{date} \n") up.write(f"COMPLETED TASK: \n{task_completed} \n") up.write(f"ONGOING TASK: \n{task_ongoing} \n") up.write(f"PENDING TASKS: \n{task_pending} \n") def task_update_viewer(username): username = f"{username}'s tasks.txt" with open(username, 'r') as up_view: print(up_view.read()) if __name__ == '__main__': print("Welcome to your task manager") try: a = int(input("Create new account? Type 0 \nAlready a member? Type 1\n")) if a == 0: signup() elif a == 1: login() else: print("No such option") except ValueError: print("Not a number")
已编写的测试代码
import os.path from project import user_information from project import signup from project import login from project import view_data from project import task_information from project import task_update from project import task_update_viewer def test_user_information(): def user_information(ussnm, pssd): if ussnm == "mayo" and pssd == "mayomikun": assert os.path.exists("mayo's tasks.txt") == True def test_signup(): def signup(): username = input("Enter your Username: ") password = input("Enter your Password: ") if username == "mayo" and len(password) == 4: assert signup() == login() def test_login(): def login(): user_name = input("Enter your Username: ") pass_word = input("Enter your Password: ") if user_name == "mayo" and pass_word == "mayomikun": assert login() == "Log in successful!"
问题原因及修复方案
1. 测试函数的核心错误
你写的测试里,每个测试函数内部都重新定义了和原函数同名的函数,但从未调用过真正的业务函数,相当于测试函数是空执行,自然全部通过。比如test_user_information里定义了一个新的user_information,但根本没调用导入的user_information,断言也不会触发。
2. 无返回值函数的测试思路
这类函数的行为体现在文件修改、输入输出交互上,需要通过模拟输入、检查文件内容、捕获输出来验证。可以用Python的unittest.mock模块模拟input和print,用临时文件避免污染真实文件。
3. 修复后的测试示例(以user_information为例)
import os import tempfile from unittest.mock import patch from project import user_information def test_user_information(): # 创建临时目录,避免影响真实文件 with tempfile.TemporaryDirectory() as tmpdir: original_cwd = os.getcwd() os.chdir(tmpdir) try: # 模拟用户输入的姓名、地址、年龄 with patch('builtins.input', side_effect=["Mayo", "123 Street", "25"]): user_information("mayo", "mayomikun") # 检查文件是否创建 file_path = "mayo's tasks.txt" assert os.path.exists(file_path) # 检查文件内容是否正确 with open(file_path, 'r') as f: content = f.read() assert "mayomikun" in content assert "Name: Mayo" in content assert "Address: 123 Street" in content assert "Age: 25" in content finally: # 恢复原工作目录 os.chdir(original_cwd)
4. 其他函数的测试要点
signup:模拟用户名和密码输入(符合长度要求/不符合),检查是否调用user_information,是否触发登录。login:模拟用户名密码输入,用临时文件模拟已存在的用户文件,验证登录成功/失败的输出,验证菜单选项的分支是否正确执行。- 文件操作函数:统一使用临时文件,测试前后清理,避免残留文件影响后续测试。
5. 原程序的小问题(影响测试)
login里的f.readlines(0)[0]是错误用法,readlines的参数是缓冲区大小,不是行数,应该改成f.readline()来读取第一行密码。task_update里重复拼接文件名,导致路径错误(比如传入mayo's tasks.txt后,会变成mayo's tasks.txt's tasks.txt),需要修正逻辑。
内容的提问来源于stack exchange,提问作者Mayo
相关产品推荐
相关产品推荐

