4

I am working on automated test framework (using pytest) to test multiple flavors of an application. The test framework should be able to parse common (to all flavors) command line args and args specific to a flavor. Here is how the code looks like:

parent.py:

import argparse
ARGS = None
PARSER = argparse.ArgumentParser()
PARSER.add_argument('--arg1', default='arg1', type=str, help='test arg1')
PARSER.add_argument('--arg2', default='arg2', type=str, help='test arg2')

def get_args():
    global ARGS
    if not ARGS:
        ARGS = PARSER.parse_args()
    return ARGS

MainScript.py:

import pytest
from parent import PARSER

ARGS = None
PARSER.conflict_handler = "resolve"
PARSER.add_argument('--arg3', default='arg3', type=str)


def get_args():
    global ARGS
    if not ARGS:
        ARGS = PARSER.parse_args()
    return ARGS

get_args()


def main():
    pytest.main(['./Test_Cases.py', '-v'])

if __name__ == "__main__":
    main()

Test_Cases.py

from MainScript import get_args

ARGS = get_args()


def test_case_one():
    pass

Executing MainScript.py fails with following error:

E ArgumentError: argument --arg3: conflicting option string(s): --arg3

3
  • 2
    No repro. MainScript.py executes just fine. Also, TestCase.py is never used. Please post a minimal reproducible example. Commented Jun 29, 2018 at 15:10
  • Where's your mywork module defined? Is main ever called in MainScript.py? Commented Jun 29, 2018 at 15:25
  • Sorry. Modified the code. @Aran-Fey it should execute now. Commented Jun 29, 2018 at 15:32

1 Answer 1

3

So the problem is that you have declared

PARSER.add_argument('--arg3', default='arg3', type=str)

in a global scope inside MainScript.py. That means that that line of code will be executed every time you import it like you do in Test_Cases.py hence why you get the conflict error, you're adding arg 3 to your argparse twice.

Easiest solution is to move PARSER.add_argument('--arg3', default='arg3', type=str) into your main() function as that will only get called once.

def main():
    PARSER.add_argument('--arg3', default='arg3', type=str)
    pytest.main(['./Test_Cases.py', '-v'])

But doing that causes another problem stemming from your multiple definition of get_args(). When you call get_args() before your main() it only has the two defined arguments from parent.py so it's missing arg3. If you move the call down into your main() or at least after your main() gets called it will work.

Personally I just removed both the definition and the call of get_args() from MainScript.py and it worked just fine.

Sign up to request clarification or add additional context in comments.

3 Comments

Right. But shouldn't following code resolve the conflict? PARSER.conflict_handler = "resolve"
@piyush Not in the way you declared it. You need to set the conflict_handler in the constructor: PARSER = argparse.ArgumentParser(conflict_handler='resolve') before it starts to play nicely. But regardless, why would you chose to force a conflict to be resolved instead of avoiding the conflict in the first place? Will it work? Sure. But I feel like it'll bite you later on in your development.
Thanks, worked for me as I had defined one of the argument twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.