Python 导入并使用模块时出现单元测试属性错误

Python 导入并使用模块时出现单元测试属性错误,python,unit-testing,Python,Unit Testing,下面是我的自动化目录,其中包含三个文件,我试图通过导入Base.py来运行unittest文件test_page.py。 Base.py包含浏览器设置和分解,它接受用户参数(浏览器、用户名和密码)并登录到站点。 但是,当我运行test_page.py时,会出现一些错误。 问题是我需要从Base.py获取浏览器实例,但我无法获取该实例。我尝试将Browser().Browser分配给一个变量,但这会打开一个新实例。我需要使用Base.py正在使用的浏览器实例 Automation

下面是我的自动化目录,其中包含三个文件,我试图通过导入Base.py来运行unittest文件test_page.py。 Base.py包含浏览器设置和分解,它接受用户参数(浏览器、用户名和密码)并登录到站点。 但是,当我运行test_page.py时,会出现一些错误。 问题是我需要从Base.py获取浏览器实例,但我无法获取该实例。我尝试将Browser().Browser分配给一个变量,但这会打开一个新实例。我需要使用Base.py正在使用的浏览器实例

    Automation
       __init__.py
         Base.py
         test_page.py
Base.py

        import sys
        import argparse
        from selenium import webdriver
        import datetime

        parser = argparse.ArgumentParser()
        parser.add_argument('browser', default='chrome', help='Types of browser:chrome, firefox, ie')
        parser.add_argument('username', help='This is the  username')
        parser.add_argument('password', help='This is the  password')
        args = parser.parse_args()

        setup_parameters = sys.argv[1:]


        class Browser(object):

            url = 'https:someurl'
            start_time = datetime.datetime.today()


            def __init__(self):
                self.username = setup_parameters[1]
                self.password = setup_parameters[2]
                if setup_parameters[0] == 'chrome':
                    self.browser = webdriver.Chrome('C:\Python37\chromedriver.exe')
                    print("Running tests on Chrome browser on %s" % self.start_time)


                elif setup_parameters[0] == 'ie':
                    self.browser = webdriver.Ie()
                    print("Running tests on Internet Explorer browser on %s" % self.start_time)


                elif setup_parameters[0] == 'firefox':
                    self.browser = webdriver.Firefox()
                    print("Running tests on Firefox browser on %s" % self.start_time)


                elif setup_parameters[0] == 'None':
                    print('No browser type specified.... continuing with the default browser')
                    self.browser = webdriver.Chrome()

            def login(self):
                # Method used to log in to the site
                self.browser.get(self.url)
                self.browser.implicitly_wait(10)
                self.browser.maximize_window()
                self.browser.find_element_by_id("Username").send_keys(self.username)
                self.browser.find_element_by_id("Password").send_keys(self.password)
                self.browser.find_element_by_id("btnLogin").click()

            def close(self):
                # Closing the browser window and terminating the test
                self.browser.close()
                print("Test(s) ended on {} at {}".format(setup_parameters[0], datetime.datetime.today()))


        if __name__ == '__main__':
            Browser().login()
            Browser().close()
test_page.py

    from unittest import TestSuite
    from unittest import TestCase
    from selenium import webdriver
    import time
    import sys
    import Base
    from Base import Browser

    class TestHomePage(unittest.TestCase):

        def setUp(self):
            self.driver = Browser().browser
            self.login = Browser().login()

        def test_links(self):
            self.driver.find_elements_by_link_text('click this link').click()

        def tearDown(self):
            self.close = Browser().close()


    if __name__ == '__main__':
        unittest.main()

    When I run test_page.py, I get the following error

    C:\Users\Projects\PortalAutomation>python test_page.py chrome username password

    EEE
    ======================================================================
    ERROR: chrome (unittest.loader._FailedTest)
    ----------------------------------------------------------------------
    AttributeError: module '__main__' has no attribute 'chrome'

    ======================================================================
    ERROR: 1EADMIN (unittest.loader._FailedTest)
    ----------------------------------------------------------------------
    AttributeError: module '__main__' has no attribute 'username'

    ======================================================================
    ERROR: password1 (unittest.loader._FailedTest)
    ----------------------------------------------------------------------
    AttributeError: module '__main__' has no attribute 'password'

    ----------------------------------------------------------------------
    Ran 3 tests in 0.000s

    FAILED (errors=3)

您正在调用
Base.py
文件中的
argparse
。不要那样做。将这些行移到另一个文件中,或者在以下情况下将它们包装到

if __name__ == __main__
    parser = argparse.ArgumentParser()
    parser.add_argument('browser', default='chrome', help='Types of browser:chrome, firefox, ie')
    parser.add_argument('username', help='This is the  username')
    parser.add_argument('password', help='This is the  password')
    args = parser.parse_args()
如果不将这些行放在另一个文件或
的内部,如果uuuu name uuuu==“uuuuuu main uuuu”
,则在导入时将运行该部分代码,而不是在从命令行调用
test_page.py
时运行

您也不希望将
argparse
unittest
结合使用。使用
unittest
测试
Base.py
,并在
setup
中为类设置可能需要的参数。我建议您将
用户名
密码
传递到
浏览器
对象的构造函数中,以便您可以轻松编写使用固定用户名/pw的测试。您可以这样做:

class Browser(object):

    url = 'https:someurl'
    start_time = datetime.datetime.today()

    def __init__(self, driver, username, password):
        self.driver = driver
        self.username = username
        self.password = password
        if self.driver == 'chrome':
        ...
然后您可以编写如下测试:

def setUp(self):
    browser_obj = Browser('chrome', 'some_username', 'some_password')
    self.driver = browser_obj.browser
    self.login = browser_obj.login()

def test_links(self):
    self.driver.find_elements_by_link_text('click this link').click()

def tearDown(self):
    browser_obj.close()
然后用一个简单的
python test\u page.py调用单元测试(不需要参数)

在prod中运行时,可以使用参数调用
Base.py
,如
Base.py chrome username password
。通常人们根本不会彻底测试他们的argparse逻辑:因为将参数传递给现有的类/函数并不完全是量子物理


请注意,最初的测试是生成多个浏览器对象,而不是使用同一个。你可能不想要这个。

谢谢@Matt Messersmith。我会试试你的方法。但是我使用argparse背后的原因是,我需要针对各种浏览器测试网站。用户名和密码也因用户的访问类型而异。@DevBin是的,您需要各种浏览器以及用户名和密码。但是,不管如何将参数传递到主脚本中,您仍然应该将它们传递到
浏览器
类中。这将允许您单独有效地测试
浏览器
类,而不必担心“main”方法以及如何从命令行提取参数。这种类型的可测试性也将为您的程序带来更好的局部性(即,您可以在本地而不是在全局对决策进行推理)。我使用您的方法对其进行了测试。代码运行良好,但问题是,单元测试似乎没有在这里运行测试。它运行安装和删除(Base.py中的登录和关闭函数)。您确定测试没有运行吗?您是否尝试过执行
self.assertEqual(0,1)
或其他操作以确保失败?您是否按照定义将其包装在
TestHomePage
类中(我只是给出了一个片段)?