8

I've written a python script that takes command line arguments and plays one round of Tic Tac Toe.
running it looks like this...

run ttt o#xo##x## x 0 1

If the move is legal it then prints the new board layout and whether anyone won the game

I have to write tests for it using unittest. I dont know how to test the whole script with various command line parameters, all the examples I've seen seem to just test individual functions within the script. Also the script uses argparse to parse the parameters

Thanks!

Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
Guye Incognito
  • 2,726
  • 6
  • 38
  • 72
  • 1
    [Writing unit tests in Python: How do I start?](http://stackoverflow.com/questions/3371255/writing-unit-tests-in-python-how-do-i-start) – Pedro Romano Oct 09 '12 at 23:44
  • @Pedro, yeah I have been reading that stuff, but it all seems to be about testing functions. I dont know if its even possible to test a whole script with command line parameters, can someone at least say if it is possible? – Guye Incognito Oct 10 '12 at 00:01
  • This one may be more in the vein of what you are looking for: [Testing Python Scripts](http://stackoverflow.com/questions/5974557/testing-python-scripts). – Pedro Romano Oct 10 '12 at 00:16

1 Answers1

14

Refactor your program so that its main action (minus the argparsing) happens in a "main" function:

def main(args):
    ...

if __name__ == '__main__':
    args = parse_args()
    main(args)

Then you can write tests for the behavior of main and parse_args.

PS. It is possible to use the subprocess module to call your program as an external process and then parse the output, but I think that would be uglier and unnecessary.

PPS. As an added benefit of writing your program this way, you will be able to import your program as a module, and call its main function in other scripts. That might be useful if, for example, you would one day like to build a GUI for it.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • This works if you have a script with only one commandline endpoint (which is the case for OP). If you have multiple endpoints you'd have to use a different strategy. – Niels Bom Dec 23 '13 at 15:32
  • Or preferably do not pass any variables to `main` method. Just in case you needed to use the main method as the entry point of a console script. Then inside main pass `sys.argv[1:]` to a second method, let's name it `core`. Now you can unit test the `core` method. – hpaknia Sep 14 '20 at 01:39