0

I'm trying to setup regression testing for an app before refactoring. The function is one long mess, starting with parsing user input and performing numerous operations before giving an output. I want to test expected values given a set of inputs (including defaults), but am not sure how to simulate a user's shell input inside a test module. Here's an example of how input is taken at the start of the file:

def function():
    parser = ArgumentParser()
    parser.add_argument("-a", "--term-a", type=float, default=0.5, help="a term relevant to output")
    parser.add_argument("-b", "--term-b", type=float, default=0.05, help="a term relevant to output")
    parser.add_argument("-c", "--term-c", type=int, default=2, help="a term relevant to output")
    parser.add_argument("-f", "--file-a", type=str, required=True,
                     help="Input file required for output")
    args = parser.parse_args()

    ...
AJG
  • 129
  • 7
  • Possible duplicate: [how to pass command line argument from pytest to code](https://stackoverflow.com/q/54071312/2650249) – hoefling Oct 26 '20 at 23:27

1 Answers1

2

parse_args() can take an arbitrary list of arguments rather than reading from sys.argv, So just pass it the arguments you want to simulate a user having passed in, like this:

parser.parse_args(['--term-a', '7.5', '--file-a', '/tmp/data.txt'])

You could refactor your function, or just have it take an optional parameter, like this:

def function(args=None):
    parser = ArgumentParser()
    parser.add_argument("-a", "--term-a", type=float, default=0.5, help="a term relevant to output")
    parser.add_argument("-b", "--term-b", type=float, default=0.05, help="a term relevant to output")
    parser.add_argument("-c", "--term-c", type=int, default=2, help="a term relevant to output")
    parser.add_argument("-f", "--file-a", type=str, required=True,
                     help="Input file required for output")
    args = parser.parse_args(args)

so it would still act like it does now, but you could also pass it canned test data, like this:

function(['--term-a', '7.5', '--file-a', '/tmp/data.txt'])
CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • Ah I see, thanks. If I were to refactor and pull out the parser as a separate function say “function2”, could the test referencing “function([canned parameters])” stay unchanged? So the test gives “function” a set of parameters, and “function” calls the newly refactored “function2” which and passes said set of parameters. Would both “function” and “function2” need ‘args=None’? – AJG Oct 27 '20 at 01:12
  • what was `function` becomes `function2`, right? Then `function` contains just the equivalent of that one line of code I gave you above, yes? - so the test can just call `function()`. – CryptoFool Oct 27 '20 at 01:15
  • Function would contain all the other content involved in generating the output (the “...” in the code snippet), fuction2 would contain the code above the ellipsis, so just the parsing. – AJG Oct 27 '20 at 01:20