【问题标题】:Python 3 Unit tests with user input带有用户输入的 Python 3 单元测试
【发布时间】:2017-12-07 07:45:22
【问题描述】:

我对 Python 单元测试完全陌生。我需要将它用于我必须提交的项目。我有点知道从哪里开始,看起来我们基本上将测试参数放入我们在程序中定义的函数中,然后输入预期的结果。如果输出了预期的结果,就OK了,否则就失败了,或者报错。

所以我的问题是我有多个用户输入存储在 for 循环或 while 循环内的变量中。我什至不知道从哪里开始为他们设置测试值。

这是我所有的代码:

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()

【问题讨论】:

    标签: python python-3.x unit-testing


    【解决方案1】:

    您可以使用 mocking,将函数或类替换为测试提供的版本。您可以使用unittest.mock() module 来执行此操作。

    在这种情况下,您可以修补模块中的input() 名称;将调用模拟对象而不是内置函数:

    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() decorator创建名称;现在这个input 将被使用而不是内置函数。

    side_effect attribute 允许您声明多个结果;每次调用模拟时,它都会返回该列表中的 下一个值。所以第一次返回'Albert Einstein',下一次返回'42.81',以此类推

    这让您可以模拟实际的用户输入。

    如果您正确地进行了测试,您会注意到您的函数中存在错误;当输入除done 或有效数值以外的任何内容时,float() 调用将引发 ValueError 异常。您需要重新编写代码以解决此问题。尝试使用mocked_input.side_effect = ['Albert Einstein', 'Not an expense', '42.81', 'done'] 触发错误。

    【讨论】:

    • 您好!首先,感谢@martijn 所以代码效果很好。我假设你打算让我做一些轻微的修改,我让它工作。我将“module_under_test”更改为我正在测试的文件的名称,然后它就起作用了。所以要清楚'side_effect'属性,无论我输入什么,它基本上都是从左到右读取并输入每个项目,就好像它是用户输入一样?您显示的错误是正确的!我现在看到我的代码并感谢您的洞察力!我现在可以看到这个单元测试有什么用处。
    • @Brystephor:是的,您没有指定模块名称,所以我使用了一个我希望作为占位符显而易见的名称。 side_effect 从列表中获取值,列表文字从左到右排序,是的。
    猜你喜欢
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多