【问题标题】:Configure Selenium use pytest test database in django app so that CI is supported在 django 应用中配置 Selenium 使用 pytest 测试数据库,以便支持 CI
【发布时间】:2020-06-05 23:57:17
【问题描述】:

我正在运行一个 dockerized django 应用程序,并且我正在使用 pytest 运行 selenium 测试。

似乎 pytest 正在使用与我的开发应用程序不同的数据库来运行测试。这意味着我不能使用固定装置(因为固定装置是在不同的数据库中创建的)。

我在三个层面上感到困惑:

首先,我看到许多使用带有 selenium 和 pytest 的夹具的教程。这意味着 selenium 正在使用测试数据库。

其次,根据这个答案,pytest 必须使用与我开发的应用程序相同的测试数据库 (Django tests with selenium not loading fixtures)

第三,根据 django 文档https://docs.djangoproject.com/en/3.0/topics/testing/overview/,在每次测试运行之前创建一个测试数据库,然后将其销毁。

这给我带来了以下麻烦:我也在 CI 管道中运行我的 selenium 测试。所以我需要能够在执行期间在数据库中创建夹具或实例。我读过硒不应该用于模型测试。好的,但是我几乎所有的视图都受到保护,所以我需要登录,所以我需要一个用户,所以我需要一个模型。

因此,我的问题是:如何使用相同的数据库运行带有 selenium 的 pytest,以便支持固定装置,这也可以传输到自动管道?

我提供更清晰的代码(在这里创建用户是为了测试我的夹具是否真的有效):

我的测试:

    @pytest.mark.usefixtures("setup")
    def test_login(self):
        User = get_user_model()
        User.objects.create_superuser(username='admin',
                                      password='mylongpassword',
                                      )

        print(User.objects.count())

        browser.get('http://django:8000/admin')
        username_input = browser.find_element_by_name('username')
        pass_input = browser.find_element_by_name('password')
        username_input.send_keys('admin')
        pass_input.send_keys('mylongpassword')

        browser.find_element_by_xpath('//input[@value="Log in"]').click()
        assert browser.current_url == 'http://django:8000/admin/'

我的设置

    @pytest.fixture
    def setup(self):
        User = get_user_model()

        User.objects.create_superuser(username='admin2',
                                      password='mylongpassword2')
        global browser
        browser = webdriver.Remote(
         command_executor='http://selenium:4444/wd/hub',
         desired_capabilities=DesiredCapabilities.CHROME,
        )
        yield
        browser.quit()

最重要的是,如果我使用以下夹具并将其传递给我的测试,我仍然无法验证 即使我的用户已创建并且我正在连接到与我正在运行的应用程序相同的数据库(在终端打印它会得到与我的应用程序中的 shell 模式相同的用户输出):

    @pytest.fixture()
    def django_db_setup(self):
        settings.DATABASES['default'] = {
            'HOST': 'postgres',
            'NAME': 'mywebsite',  # my dedicated test database (!)
            'PORT': '5432',
            'USER':  'username',
            'PASSWORD': 'pass',
        }


【问题讨论】:

    标签: python django selenium pytest gitlab-ci


    【解决方案1】:

    您不必为您的测试制作 db 夹具,pytest 会为您完成。

    你只需要使用 pytest db 夹具就可以了

    如果您使用 pytest-django,Pytest 不支持您在生产/主数据库上运行测试。 有更好的方法来解决这个问题。

    • Pytest DB resolve method

    • 这表示,每当您使用标记 @pytest.mark.django_db 运行测试时,测试都会在另一个名为 test_your production_db_name 的新创建的数据库上运行。

    • 因此,如果您的数据库名称是hello,pytest 将创建一个名为test_hello 的新数据库并在其上运行测试

    【讨论】:

    • 感谢 Nithin 的回复!添加额外的配置来指定一个数据库是为了调试。问题是 pytest 和 selenium 使用不同的数据库。我通过运行我的测试而不是针对django:8000 而是使用live_server_url 解决了这个问题。像这个pytest和selenium使用相同的db
    猜你喜欢
    • 2019-08-19
    • 1970-01-01
    • 2019-02-08
    • 2018-06-14
    • 1970-01-01
    • 2012-06-16
    • 2019-03-06
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多