Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest - testing parser Error : Unrecognised arguments

I'm trying to test a very simple function (as a result of multiple failed attempts at testing a more complicated function which uses the argument parser as a parameter).

# from ./runfile.py

import argparse
import os


def get_input_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--priv_raw_name', default='private_data.csv', type=str,
                    help='Set raw private/source datafile name')
    args = parser.parse_args()
    return args

# from ./tests/test_args.py

import pytest
from runfile import get_input_args

def test_parser():
    parser = get_input_args()
    assert 1

When I run the script runfile.py all works as expected, however when I call pytest tests/test_args.py I get the unrecognised arguments error message below.

I've tried setting up a conftest.py file and using addoption but I just seem to be encountering more errors far beyond my experience to fix. Can anyone point me in the right direction of how to run the test using the default arguments from the core script but not have tests/test_args.py being called as an argument for the actual test itself?

    (Project_Cascade) ➜  Project_Cascade git:(WIP) ✗ pytest tests/test_args.py
========================================================================= test session starts =========================================================================
platform darwin -- Python 3.6.5, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
rootdir: /Users/davidmellor/Code/Spend_Network/Data_Projects/Project_Cascade, inifile:
collected 1 item

tests/test_args.py F                                                                                                                                            [100%]

============================================================================== FAILURES ===============================================================================
_____________________________________________________________________________ test_parser _____________________________________________________________________________

    def test_parser():
>       parser = get_input_args()

tests/test_args.py:5:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
runfile.py:50: in get_input_args
    args = parser.parse_args()
/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/argparse.py:1733: in parse_args
    self.error(msg % ' '.join(argv))
/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/argparse.py:2389: in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = ArgumentParser(prog='pytest', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
status = 2, message = 'pytest: error: unrecognized arguments: tests/test_args.py\n'

    def exit(self, status=0, message=None):
        if message:
            self._print_message(message, _sys.stderr)
>       _sys.exit(status)
E       SystemExit: 2

/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/argparse.py:2376: SystemExit
------------------------------------------------------------------------ Captured stderr call -------------------------------------------------------------------------
usage: pytest [-h] [--priv_raw_name PRIV_RAW_NAME]
pytest: error: unrecognized arguments: tests/test_args.py
like image 821
ML_Engine Avatar asked Mar 20 '19 11:03

ML_Engine


1 Answers

The problem comes from the parser.parse_args call which accepts an optional args argument. If this argument is not provided, args are taken from sys.argv.

When you execute pytest tests/test_args.py, sys.argv contains ['pytest', 'tests/test_args.py']. The first element of the list is the called program and the second is the first argument.

Thus, parser.parse_args called without its args argument considers tests/test_args.py as the value for the first declared argument of the parser. Fortunately, it is unable to parse it and an error occurs with the explicit message unrecognized arguments: tests/test_args.py.

To check it, you can add a breakpoint in your test before calling parser.parse_args and inspect sys.argv

Invoking pytest without specifying the file to run (just pytest) should pass with no problem.

Anyway, your test should pass whatever the manner it is ran. All you have to do for this is specifying explicit args for your parser.parse_args call in your test.

For example, passing an empty list will work:

parser.parse_args([])

But you will probably want to test it with values for the priv_raw_name option:

parser:parse_args(['--priv_raw_name', 'any/test/path'])
like image 182
Tryph Avatar answered Nov 10 '22 03:11

Tryph