In the previous post about Python Unittest, I wrote about the basic steps needed for setting up unit testing for your Python program with the unittest module. In this post, I’ll discuss about handling the command line parameters that your program need while you’re using Python unittest.
Unit testing is meant for testing basic functionality of the application. The target of Unit testing is expected to be each function of your program. When your program has command line arguments, ideally the unit tests should not accept arguments from the command line because unit tests are supposed to be very specific and not testing on the Integration level (i.e. across multiple functions in your program).
So the way I use to handle the command line arguments can be summarized as:
Refactor your program to have the arguments parsing as a function
Refactor your program to handle the arguments parsing differently when doing unit testing
In the unit tests, set the arguments and pass them directly to the functions under test
The following is a demo Python project I built to demonstrate handling command line arguments when using unittest.
#!/usr/bin/env pythonimportsys,os.path,reimportargparseclassmyApp():EXIT_PASS,EXIT_FAIL=0,1def__init__(self,mode='normal',test_param=None):# Validate and process argument optionsself.parse_args(mode,test_param)# Initialize database connectionself.app_name=self.get_app_name(self.name)defparse_args(self,mode,test_param):ifmode=='unittest':iftest_paramisNone:print("Missing test param")self.app_exit('fail')self.name=test_param['app_name']self.verbose=test_param['verbose']else:parser=argparse.ArgumentParser(description='myApp: A demo project')parser.add_argument('-n','--name',help='Name of myApp',required=True)parser.add_argument('--verbose',action='store_true',help='Verbose mode with more information printed')args=parser.parse_args()self.name=args.nameself.verbose=args.verbosedefapp_exit(self,status):ifstatus.lower()=='pass':print("** App Exit Status: PASS \n")exit(self.EXIT_PASS)elifstatus.lower()=='skip':print("** App Exit Status: SKIP \n")exit(self.EXIT_PASS)else:print("** App Exit Status: FAIL \n")exit(self.EXIT_FAIL)defget_app_name(self):app_name=self.namereturnapp_nameif__name__=='__main__':app=myApp()