Python unittest, правильно устанавливающий глобальную переменную - PullRequest
0 голосов
/ 01 мая 2020

У меня есть простой метод, который устанавливает для глобальной переменной значение True или False в зависимости от параметра метода.

Эта глобальная переменная называется feedback и имеет значение по умолчанию False.

Когда я вызываю setFeedback('y'), глобальная переменная изменится на feedback = True. Когда я вызываю setFeedback('n'), глобальная переменная будет изменена на feedback = False.

Теперь я пытаюсь проверить это с помощью unittest в Python:

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

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Вам не нужно ничего издеваться; Вам просто нужно убедиться, что глобальная переменная находится в известном состоянии, прежде чем запускать каждый тест. Кроме того, использование from main import * создает в вашем тестовом модуле новое глобальное имя feedback, отличное от main.feedback, которое setFeedback модифицирует.

import main

class TestMain(unittest.TestCase):

    def setUp(self):
        main.feedback = False

    def test_setFeedback(self):

        self.assertFalse(feedback)
        main.setFeedback('y')
        self.assertTrue(feedback)
1 голос
/ 01 мая 2020

Есть две проблемы с вашим тестом.

Во-первых, вы используете input в вашей функции feedback, которая будет останавливать тест, пока вы не введете ключ. Вы, вероятно, должны издеваться input. Также вы можете учитывать, что вызов input не относится к setFeedback (см. Комментарий @chepner).

Во-вторых, from main import * здесь не будет работать (за исключением того, что плохой стиль ), поскольку таким образом вы создаете копию своей глобальной переменной в тестовом модуле - изменения в самой переменной не будут распространяться на копию. Вместо этого вы должны импортировать модуль, чтобы получить доступ к переменной в модуле.

В-третьих (это взято из ответа @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)
...