关于单元测试:在python 2的unittest模块中模拟raw_input()

simulating raw_input() in unittest module of python 2

我试图了解如何使用python的unittest框架

我有一段看起来像这样的代码 -

1
2
3
4
5
6
7
while True:
    filename = raw_input('Enter file')
    if os.path.exists(filename):
        break
    else:
        print"That file does not exist"
return filename

有人可以帮助我开发unittest模块来测试这个。 我问这个问题是为了学习如何使用单元测试(我正在尝试学习TTD:测试驱动开发)

到目前为止,我已经想出了这个
...
进口单位测试
import os.path

class TestFunctions(unittest.TestCase):

1
2
3
4
5
6
7
8
9
10
11
def setUp(self):
    self.prompt = 'Enter filename: '

def test_get_file(self):

    # TODO make sure empty filename argument requests for new filename
    filename = find_author.get_valid_filename(self.prompt)
    self.assertTrue(<EXPRESSION?>)

    # TODO make sure valid filename returns the"filename"
    # TODO make sure invalid filename prompts that file does not exit and requests new filename

如果name =="main":
unittest.main()


一种简单的方法是使用猴子补丁raw_input

例如,在您的测试模块中(因为您应该将您的测试人员和测试人员分成不同的文件),您可能会:

1
2
import module_being_tested
... run tests ...

在运行测试之前,您可以简单地执行以下操作:

1
2
3
4
5
6
7
8
import module_being_tested

def mock_raw_input(s):
    return 'data.txt'

module_being_tested.raw_input = mock_raw_input

... run tests ....

现在,当您的测试人员模块调用raw_input时,它实际上将调用mock_raw_input,并且将始终返回'data.txt'


扩展vgel对这个问题的回答,我需要模拟不同的连续输入,所以总是返回相同的字符串是不够的。 这就是我解决它的方式:

1
2
3
4
5
6
7
8
9
10
11
import module_being_tested

mock_raw_input_counter = 0
mock_raw_input_values = []
def mock_raw_input(s):
    global mock_raw_input_counter
    global mock_raw_input_values
    mock_raw_input_counter += 1
    return mock_raw_input_values[mock_raw_input_counter - 1]

module_being_tested.raw_input = mock_raw_input

然后在测试中你想使用这个多输入功能:

1
2
3
4
5
6
7
def test_interactive_sequence_selection_dummy_2_99_0_Z_1(self):
    global mock_raw_input_counter
    global mock_raw_input_values
    mock_raw_input_counter = 0
    mock_raw_input_values = ["2","99","0","Z","1",""]
    new_sequences = module_being_tested.interactive_sequence_selection(["A","B","C"], [None])
    self.assertEqual(new_sequences, ["C","A","B"])

这将模拟以下值的输入:

1
2
3
4
5
6
2[ENTER]
99[ENTER]
0[ENTER]
Z[ENTER]
1[ENTER]
[ENTER] (no input, just pressing Enter)

(interactive_sequence_selection中的代码使用while s !="":循环要求用户输入各种值并以空Enter按下终止