0

I'm trying to test the main function that if len (sys. argv) < 1 or len (sys. argv) < 4 it will run a function using pytest

this is my main fucntion

def main():
    if len(sys.argv) == 1:
        print(print_help())
    elif len(sys.argv) == 2 or len(sys.argv) == 3:
        if sys.argv[1] == 'help' or sys.argv[1] == 'h' or sys.argv[1] == 'H':
            print(print_help())
    else:
        print('no such command arguments try python project.py help')

def print_help:
    the_help = 'the help section'
    return the_help

if __name__ =='__main__':
    main()

How can I use pytest to test this main function if sys. argv < 1 that it will run the print_help function

or if sys.argv == 'help' or sys.argv == 'h' or sys.argv == 'H' it will run the same fucntion

zaki_zardo
  • 65
  • 8
  • 3
    Does this answer your question? [How do I set sys.argv so I can unit test it?](https://stackoverflow.com/questions/18668947/how-do-i-set-sys-argv-so-i-can-unit-test-it) – Jerzy Pawlikowski Jul 07 '22 at 14:27
  • in this question they use unittest, I hope that there is an answer using pytest – zaki_zardo Jul 07 '22 at 14:32
  • 2
    Does this answer your question? [how to handle sys.argv in pytest?](https://stackoverflow.com/questions/56110064/how-to-handle-sys-argv-in-pytest) – Michael Delgado Jul 07 '22 at 15:10
  • Thank you very much for responding, but if read the answer on that question it does not answer my question at all I want to assert that when I run `py project. py help` it sure run the help function and nothing else but in this question you sherd its another thing – zaki_zardo Jul 07 '22 at 17:30

2 Answers2

1

I find some kind of answer that helps a little bit I find it on this Github link

def test_main(capsys):

    from project import main
    sys.argv = ['h', 'H', 'help']
    main()
    out, err = capsys.readouterr()
    assert out.startswith("the help section") is True

it check if the output of the print_help is the same as entering one of the commands in sys.argv= ['h', 'H', 'help']

zaki_zardo
  • 65
  • 8
1

My preferred approach is make your main() function take its inputs from a variable instead of from sys.argv directly:

def main(args):
    if len(args) == 1:
        print(print_help())
    elif len(args) == 2 or len(args) == 3:
        if args[1] == 'help' or args[1] == 'h' or args[1] == 'H':
            print(print_help())
    else:
        print('no such command arguments try python project.py help')

def print_help:
    the_help = 'the help section'
    return the_help

if __name__ =='__main__':
    main(sys.argv)

Now you can use capsys in your test function to test the output, and can easily pass in whatever list of arguments you want to test without having to patch or mock anything.

Also, argparse does this sort of command line processing for you. I highly, highly recommend using it (or other similar libraries) instead of re-inventing the wheel.

Kirk Strauser
  • 30,189
  • 5
  • 49
  • 65
  • thank you, your approach is better that mine, and for the argparse I use al mot one command that's why I didn't use it my full code is here [link](https://github.com/zakari1231/final_project_cs50p/blob/main/project.py), Again, thank you for this useful approach – zaki_zardo Jul 07 '22 at 20:02