Using arg parser in python in another class
<p>I'm trying to write a test in Selenium using python,</p>

<p>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.</p>

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

<pre><code>    app_url= (args['base_url'])
NameError: global name 'args' is not defined
</code></pre>

<p>How can I get args to be defined inside the Selenium class?</p>

<p>This is my code:</p>

<pre><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 &gt; 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()
</code></pre>

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

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

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

<pre><code>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.
</code></pre>

<p>And in other scripts which you want to import it into, do </p>

<pre><code>from selenium_tests import get_parsed_args

if __name__ == '__main__':
    args = get_parsed_args()
    # etc.
</code></pre>

python selenium argparse