Using arg parser in python in another class
Question: I'm trying to write a test in Selenium using python,

I managed to run the test and it passed, But now I want add arg parser so I
can give the test a different URL as an argument.

The thing is that my test is inside a class, So when I'm passing the argument
I get an error:

    
    
        app_url= (args['base_url'])
    NameError: global name 'args' is not defined
    

How can I get args to be defined inside the Selenium class?

This is my code:

    
    
    from selenium.common.exceptions import NoSuchElementException
    from selenium.common.exceptions import NoAlertPresentException
    from selenium import webdriver
    import unittest, time, re
    import os
    import string
    import random
    import argparse
    
    
    def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
        return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8))
    agmuser = id_generator()
    
    class Selenium(unittest.TestCase):
        def setUp(self):
            chromedriver = "c:\chromedriver.exe"
            os.environ["webdriver.chrome.driver"] = chromedriver
            self.driver = webdriver.Chrome(chromedriver)
            app_url = (args['base_url'])
            #app_url= "http://myd-vm16635.fufu.net:8080/"
            print "this is the APP URL:" + ' ' + app_url
            self.base_url = app_url
            self.verificationErrors = []
            self.accept_next_alert = True
    
    def test_selenium(self):
    
        #id_generator.user = id_generator()
        driver = self.driver
        driver.get(self.base_url + "portal/")
        driver.find_element_by_css_selector("span").click()
        driver.find_element_by_id("j_loginName").clear()
        driver.find_element_by_id("j_loginName").send_keys(agmuser)
        driver.find_element_by_id("btnSubmit").click()
        driver.find_element_by_link_text("Login as" + ' ' + agmuser).click()
        driver.find_element_by_css_selector("#mock-portal-Horizon > span").click()
        # driver.find_element_by_id("gwt-debug-new-features-cancel-button").click()
        # driver.find_element_by_xpath("//table[@id='gwt-debug-module-dropdown']/tbody/tr[2]/td[2]").click()
        # driver.find_element_by_id("gwt-debug-menu-item-release-management").click()
    
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
    
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
    
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
    
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)
    
    if __name__ == "__main__":
        #####################******SCRIPT PARAMS****;**###################################
        # these values can be changed type 'python selenium_job.py --help' for assistance
        ##################################################################################
        parser = argparse.ArgumentParser(description='DevOps team - Sanity test')
        parser.add_argument('-b', '--base_url', help='base_url', default="http://myd-vm16635.fufu.net:8080/")
        args = vars(parser.parse_args())
        unittest.main()
    


Answer: Put the `parser = argparse.ArgumentParser(...)` and `parser.add_argument()`
outside `if __name__ == "__main__":` so that it always gets created but not
evaluated. Keep `args = vars(parser.parse_args())` inside `__main__`.

That way you can import it from the file like `from selenium_tests import
parser` and then in your other script, do `parser.parse_args()`.

And a cleaner way to do it is to create a function which returns the parser,
like:

    
    
    def get_parsed_args():
        parser = argparse.ArgumentParser(...)
        parser.add_argument(...)
        # etc.
        args = parser.parse_args()
        return args
        # or just...
        return parser.parse_args()
    
    #and then call that in the main program:
    
    if __name__ == '__main__':
        args = get_parsed_args()
        # etc.
    

And in other scripts which you want to import it into, do

    
    
    from selenium_tests import get_parsed_args
    
    if __name__ == '__main__':
        args = get_parsed_args()
        # etc.
    

