如何使用assert、actual变量及siminput为时间转换代码编写unittest测试用例
先改造生产代码(为了可测试)
原代码直接耦合了输入输出逻辑,没法单独验证转换功能。先把核心转换逻辑和交互逻辑拆分,这样测试起来更方便:
def convert_hours_to_mins(hours): return hours * 60 def convert_mins_to_hours(mins): return mins / 60 def conversion(): print('Would you like to convert hours to mins, or mins to hours?') choice = input().strip() if choice == 'hours to mins': hours = int(input('How many hours? ')) mins = convert_hours_to_mins(hours) print(f"{mins} Minutes") elif choice == 'mins to hours': mins = int(input('How many minutes? ')) hours = convert_mins_to_hours(mins) print(f"{hours} Hours") else: print('An error has occurred') if __name__ == "__main__": conversion()
编写unittest测试代码
用unittest框架,结合unittest.mock模拟输入、捕获输出,再用assert验证结果:
import unittest from unittest.mock import patch # 替换成你的生产代码文件名 from your_script_name import convert_hours_to_mins, convert_mins_to_hours, conversion class TestTimeConversion(unittest.TestCase): # 测试核心转换函数 def test_hours_to_mins(self): actual = convert_hours_to_mins(2) self.assertEqual(actual, 120) actual = convert_hours_to_mins(0) self.assertEqual(actual, 0) actual = convert_hours_to_mins(1.5) self.assertEqual(actual, 90) def test_mins_to_hours(self): actual = convert_mins_to_hours(120) self.assertEqual(actual, 2.0) actual = convert_mins_to_hours(30) self.assertEqual(actual, 0.5) actual = convert_mins_to_hours(0) self.assertEqual(actual, 0.0) # 测试完整交互流程 @patch('builtins.input') @patch('builtins.print') def test_conversion_hours_to_mins(self, mock_print, mock_input): # 模拟用户依次输入的内容 mock_input.side_effect = ['hours to mins', '3'] conversion() # 验证输出是否符合预期 mock_print.assert_any_call('Would you like to convert hours to mins, or mins to hours?') mock_print.assert_any_call('180 Minutes') @patch('builtins.input') @patch('builtins.print') def test_conversion_mins_to_hours(self, mock_print, mock_input): mock_input.side_effect = ['mins to hours', '180'] conversion() mock_print.assert_any_call('Would you like to convert hours to mins, or mins to hours?') mock_print.assert_any_call('3.0 Hours') @patch('builtins.input') @patch('builtins.print') def test_conversion_invalid_choice(self, mock_print, mock_input): mock_input.return_value = 'invalid option' conversion() mock_print.assert_any_call('Would you like to convert hours to mins, or mins to hours?') mock_print.assert_any_call('An error has occurred') if __name__ == '__main__': unittest.main()
关键说明
- 拆分核心逻辑:把转换计算单独抽成函数,直接用
actual变量接收函数返回值,再通过self.assertEqual(actual, 预期值)验证结果。 - 模拟输入:用
@patch('builtins.input')替换系统的input函数,side_effect可以按顺序提供模拟的用户输入内容。 - 捕获输出:用
@patch('builtins.print')捕获print的调用,通过断言验证输出内容是否正确。
内容的提问来源于stack exchange,提问作者noisoyhermando
相关产品推荐
相关产品推荐

