Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I test beginner student Python programs that use input() (maybe with unittest?)?

I'm a grader for a beginning programming class using Python. My python-fu is not so strong myself, but I would like to try to automate some of the grading.

Looking online, I like the PyUnit testing suite, though it probably is a bit overpowered for what I want.

My problem is that I'm not sure how to pass the test inputs I want to the student's functions, since they are not using command line arguments or even multiple functions yet, but getting user input through the input() function.

A silly example:

#/usr/bin/python3.1
# A silly example python program
def main():
    a = int(input("Enter an integer: "))
    b = int(input("Enter another integer: "))
    c = a+b
    print("The sum is %d" % c)

if __name__ == '__main__'
    main()

For my silly example, how would I write a unit test that could check the output for several different inputs? (ie, if I pass 2 and 3 to the input, the output string should be "The sum is 5")

like image 778
Jason Avatar asked Feb 01 '11 16:02

Jason


Video Answer


2 Answers

Edit: Only proposing this since the example isn't unittest-able (and I'm assuming the beginner students will just be confused by the constraint)

If you are just concerned with the output matching what you are looking for, why not just use some "silly" bash? Something like:

echo -e "2\n3" | python test.py | grep -q "The sum is 5" && echo "Success"

If you are doing relatively trivial programs like this, then this should be a sufficient, or good enough, solution that requires little effort.

like image 169
Mark Loeser Avatar answered Oct 09 '22 18:10

Mark Loeser


You can't really unit-test that. One of the things about writing unit tests is you often need to write your code differently to allow it to be unit-tested. So in this case, you would need to factor out the calls to input into a separate function, which you can then patch.

def my_input(prompt):
    return input(prompt)

def main():
    a = int(eval(my_input("Enter an integer: "))

etc. Now your test can monkey-patch myscript.my_input to return the values you want.

like image 39
Daniel Roseman Avatar answered Oct 09 '22 17:10

Daniel Roseman