简体   繁体   中英

Emulating user input in python for testing

I have written a simple python program that takes user input, with the use of input(). There are some different commands available.

I want to make sure that all available commands function as intended and that the program catches invalid commands. Since there are quite a few different commands, this is very time-consuming to do manually (ie, start the program, and enter all commands, one by one). (I have separate test functions for the actual execution of all commands, but I'm struggling to find a nice way to test this functionality together with the input() loop.)

How can I automate the process of giving (predetermined) user inputs, without messing up the rest of the code? In addition to using this to test the program, it would also serve as an example to the user, in order to see the possible usage of the program.

My current solution is that I have two versions of the main() function, which is basically just an infinite loop that takes inputs until an exit command is given. The first version, "main()", is the version intended for use and takes inputs from input(), until the user decides to quit. The second version, "main_test()" is only used for testing, and takes the inputs from a predetermined list, specified in the code. This does the job, but I do not want the main_test() code in the final version. I also do not want to "pollute" main() by adding things only used for testing.

def main():
    while True:
        user_input = input()
        ...
def main_test():
    test_input = [...]
    test_iter = 0
    while True:
        user_input = test_input[test_iter]
        test_iter += 1
        ...

I have not been able to find a nice way to do this in python, although I'm sure there must be a smart way. I'd prefer a way that does not need any additional imports. But if there is a nice way to do it with additional imports, I'm all ears.

Anyway, striking out with python, my next thought was to specify the commands in a Makefile, where I would start the program and feed the program text input, emulating the user. The main benefit of this is that I would only need the "main()" function, and I would not have to change anything in the python code. The disadvantage is that the example/test is specified outside of the *.py files, which may confuse the user.

If you are looking to confirm that X input results in Y output, then what you are looking for is called unit testing ; this methodology allows you to define functions that assess the result of your function against your expected results.

Module options:
- pytest
- unittest

First of all, I would like to point out that there are many methods for testing your code and some are better practice than others, while each one can be preferred by the programmer for different reasons. You should study how to test your code using the existing ways. Depending on the structure of your code, patterns that can be exploited, and your implementation principles that you follow (dependency injections, mvc, mvvm, etc).

As for your specific case, I would recommend to unittest your fraction of the code that uses the user input and define a collection of cases with predefined outputs that your can assert. Then, use the same code (maybe add cases) whenever you edit this fraction, in order to be sure that your program continues to work fluently.

Using Python's Unittest package you can implement a nice script that checks your code consistently and incorporate it to your project. See also Wikipedia page about unit testing to learn more about the principles you have to follow. You can also check Tensorflow's testing page for directions on how to incorporate this kind of testing in a bigger project, and use these ideas in yours.

Good luck!

The answer from here should work if you don't mind importing unittest, python mocking raw input in unittests .

The main_test() part can then be removed from you projects and taken care of in the testing script. The "return_values" then correspond to you mock inputs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM