Python unittest正确设置了全局变量

问题描述 投票:0回答:2

我有一个简单的方法,可以根据方法参数将全局变量设置为True或False。

此全局变量称为feedback,默认值为False

当我调用setFeedback('y')时,全局变量将更改为feedback = True。当我调用setFeedback('n')时,全局变量将更改为feedback = False

现在我正在尝试在Python中使用unittest对此进行测试:

class TestMain(unittest.TestCase):

    def test_setFeedback(self):

        self.assertFalse(feedback)
        setFeedback('y')
        self.assertTrue(feedback)

[运行此测试时,出现以下错误:AssertionError: False is not true

由于我知道该方法可以正常工作,因此我假定全局变量已通过某种方式重置。但是,由于我对Python环境还很陌生,所以我不知道自己在做什么错。

我已经在这里阅读了有关模拟的文章,但是由于我的方法更改了全局变量,所以我不知道模拟是否可以解决这个问题。

我将非常感谢您的建议。

这里是代码:

main.py:

#IMPORTS
from colorama import init, Fore, Back, Style
from typing import List, Tuple

#GLOBAL VARIABLE
feedback = False

#SET FEEDBACK METHOD
def setFeedback(feedbackInput):
    """This methods sets the feedback variable according to the given parameter.
       Feedback can be either enabled or disabled.

    Arguments:
        feedbackInput {str} -- The feedback input from the user. Values = {'y', 'n'}
    """

    #* ACCESS TO GLOBAL VARIABLES
    global feedback

    #* SET FEEDBACK VALUE
    # Set global variable according to the input
    if(feedbackInput == 'y'):

        feedback = True
        print("\nFeedback:" + Fore.GREEN + " ENABLED\n" + Style.RESET_ALL)
        input("Press any key to continue...")

        # Clear the console
        clearConsole()

    else:
        print("\nFeedback:" + Fore.GREEN + " DISABLED\n" + Style.RESET_ALL)
        input("Press any key to continue...")

        # Clear the console
        clearConsole()

test_main.py:

import unittest
from main import *

class TestMain(unittest.TestCase):

    def test_setFeedback(self):

        self.assertFalse(feedback)
        setFeedback('y')
        self.assertTrue(feedback)


if __name__ == '__main__':
    unittest.main()
python python-3.x unit-testing python-unittest python-unittest.mock
2个回答
1
投票

您的测试有两个问题。

首先,您在input功能中使用feedback,这将使测试停止,直到您输入密钥。您可能应该模拟input。另外,您可能会认为对input的调用不属于setFeedback(请参阅@chepner的评论)。

第二,from main import *在这里不起作用(除了bad style以外),因为这样可以在测试模块中创建全局变量的副本-变量本身的更改不会传播到该副本。相反,您应该导入模块,以便您可以访问模块中的变量。]​​>

第三(这是从@chepner的答案中摘录的,我错过了),您必须确保变量在测试开始时处于已知状态。

这是应该起作用的地方:

import unittest
from unittest import mock

import main  # importing the module lets you access the original global variable


class TestMain(unittest.TestCase):

    def setUp(self):
        main.feedback = False  # make sure the state is defined at test start

    @mock.patch('main.input')  # patch input to run the test w/o user interaction
    def test_setFeedback(self, mock_input):
        self.assertFalse(main.feedback)
        main.setFeedback('y')
        self.assertTrue(main.feedback)

1
投票

您无需嘲笑任何东西;您只需要在运行每个测试之前确保全局变量处于已知状态即可。另外,使用from main import *在测试模块中创建一个名为feedbacknew

© www.soinside.com 2019 - 2024. All rights reserved.