使用用户输入进行 Python 3 单元测试 [英] Python 3 Unit tests with user input
问题描述
我对 Python 单元测试完全陌生.我需要将它用于我必须提交的项目.我有点知道从哪里开始,看起来我们基本上将测试参数放入我们在程序中定义的函数中,然后我们输入了预期的结果.如果输出的是预期结果,我们就OK,否则我们就会Failure,或者一个错误.
I'm absolutely brand new to Python unit test. I need to use it for a project I have to submit. I sort of have an idea of where to begin, it looks like we basically put in test parameters to functions we have defined in our program and we enter the expected result. If the expected result is output, we get OK, otherwise we will get Failure, or an error.
所以我的问题是我有多个用户输入存储在 for 循环或 while 循环内的变量中.我什至不知道从哪里开始为他们设置测试值.
So my problem is that I have multiple user inputs stored into variables that are within for loops or while loops. I don't know where to even begin with this to set test values in for them.
这是我所有的代码:
studentTripExpenses = {}
def dictCreate(studentAmount):
for i in range(0, studentAmount):
studentName = input("What is the name of the student? ")
expenseList = []
print("Enter 'done' to move to the next student.")
while True:
expense = input("What is the cost of this expense? ")
if expense.lower() == 'done':
break
elif (float(expense) >= 0) or (float(expense) < 0):
expenseList.append(float(expense))
elif not expense.isdigit():
print("Please enter a number or enter 'done' to move on.")
studentTripExpenses[studentName] = expenseList
return studentTripExpenses
def studentCost(dct):
for i in dct:
#Variable for individual costs of student
personalCost = 0
#Determines the total cost for each student
for x in dct[i]:
personalCost = personalCost + x
#Sets each students value to their total cost to two decimal places
dct[i] = float("%.2f" % personalCost)
return dct
def amountsDue(expenseLst, studentAvgPrice):
#Runs through the dictionary of students and individual total trip costs
for key in expenseLst:
maxPerson = max(expenseLst, key=expenseLst.get)
costDifference = 0
#Determines who owes who how much money
if max(expenseLst.values()) > expenseLst[key]:
costDifference = studentAvgPrice-expenseLst[key]
if (costDifference < 0):
costDifference = costDifference * -1
print("%s owes %s $%.2f" % (key, maxPerson, costDifference))
def main():
numOfStudents = int(input("How many students are going on the trip? "))
studentCostDict = dictCreate(numOfStudents)
studentTripExpenses = studentCost(studentCostDict)
totalCost = 0
#Gets the total cost for all students
for key in (studentTripExpenses):
totalCost = totalCost + studentTripExpenses[key]
#Changes the total cost to 2 decimal places
totalCost = float("%.2f" % totalCost)
#Determines the average amount spent per student
avgCost = float("%.2f" % (totalCost/len(studentTripExpenses)))
amountsDue(studentTripExpenses, avgCost)
main()
推荐答案
您可以使用 mocking,在这里您可以使用测试提供的版本替换函数或类.您可以使用 unittest.mock()
模块执行此操作.
You can use mocking, where you replace a function or class with a test-supplied version. You can do this with the unittest.mock()
module.
在这种情况下,您可以修补模块中的 input()
名称;将调用模拟对象而不是内置函数:
In this case, you can patch the input()
name in your module; instead of the built-in function, the mock object will be called:
from unittest import mock
from unittest import TestCase
import module_under_test
class DictCreateTests(TestCase):
@mock.patch('module_under_test.input', create=True)
def testdictCreateSimple(self, mocked_input):
mocked_input.side_effect = ['Albert Einstein', '42.81', 'done']
result = dictCreate(1)
self.assertEqual(result, {'Albert Einstein': [42.81]})
因为 input
在你的模块中不存在(它是一个内置函数),我告诉 mock.patch()
装饰器 来创建名称;现在将使用这个 input
而不是内置函数.
Because input
doesn't exist in your module (it is a built-in function), I told the mock.patch()
decorator to create the name; now this input
will be used instead of the built-in function.
side_effect
属性 允许你声明多个结果;每次调用模拟时,它都会返回该列表中的下一个值.所以第一次返回'Albert Einstein'
,下次返回'42.81'
,依此类推
The side_effect
attribute lets you state multiple results; each time the mock is called, it'll return the next value in that list. So the first time 'Albert Einstein'
is returned, the next time '42.81'
, etc.
一起,这可以让您模拟实际的用户输入.
Together, this lets you simulate actual user inputs.
如果你的测试正确,你会注意到你的函数有一个错误;当输入除 done
或有效数值以外的任何内容时,float()
调用将抛出 ValueError
异常.您需要重新编写代码来解决这个问题.尝试使用 mocked_input.side_effect = ['Albert Einstein', 'Not avenue', '42.81', 'done']
来触发错误.
If you do your test right, you'll notice that there is a bug in your function; the float()
call will throw a ValueError
exception when anything other than done
or a valid numeric value is entered. You need to rework your code to account for that. Try with mocked_input.side_effect = ['Albert Einstein', 'Not an expense', '42.81', 'done']
to trigger the bug.
这篇关于使用用户输入进行 Python 3 单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!