如何并行执行测试套件中的测试

时间:2017-11-22 16:03:49

标签: python selenium python-multiprocessing

我已经设法通过使用webdriver对抗selenium hub和节点来并行运行测试。在运行测试之前调用此代码。

cls.driver = webdriver.Remote(
   command_executor="http://localhost:4444/wd/hub",
   desired_capabilities={
        "browserName": "chrome",
        })

    cls.driver.maximize_window()
    cls.driver.get(cls.serverUrl)
    p = multiprocessing.Process(target=cls.driver.get(cls.serverUrl), args=())
    p.start()
    p.join()

通过这种方式,我可以通过从Eclipse手动执行它们来启动多个浏览器。但是我想在测试套件中自动执行此操作。但是在测试套件中,所有测试都按顺序启动。如果有人知道如何继续下去会很棒。

1 个答案:

答案 0 :(得分:0)

预赛

我准备了一些样本测试。这些是一些简单的页面标题检查。我们有一个模块test_google.py,其中包含两个单元测试,用于检查www.google.commail.google.com的标题:

# test_google.py

import unittest
from selenium import webdriver


class GoogleTests(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()

    def tearDown(self):
        self.driver.close()


    def test_google_page_title(self):
        self.driver.get('https://www.google.com')
        assert self.driver.title == 'Google'

    def test_gmail_page_title(self):
        self.driver.get('https://mail.google.com')
        assert self.driver.title == 'Gmail'

第二个模块是test_stackoverflow.py,其中包含一个检查stackoverflow.com标题的测试:

# test_stackoverflow.py

import unittest
from selenium import webdriver


class StackoverflowTests(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()

    def tearDown(self):
        self.driver.close()


    def test_so_page_title(self):
        self.driver.get('https://stackoverflow.com')
        assert 'Stack Overflow' in self.driver.title

使用裸unittest跑步者运行测试产生:

$ python setup.py test
running test
running egg_info
...
running build_ext
test_gmail_page_title (test_google.GoogleTests) ... ok
test_google_page_title (test_google.GoogleTests) ... ok
test_so_page_title (test_stackoverflow.StackoverflowTests) ... ok

----------------------------------------------------------------------
Ran 3 tests in 11.657s

OK

迁移到pytest

通过pytest安装pip

$ pip install pytest

pytest支持开箱即用的单元测试,因此我们无需触摸测试,我们可以立即运行它们。试用pytest跑步者:

$ pytest -v
================ test session starts ================
platform darwin -- Python 3.6.3, pytest-3.2.5, py-1.5.2, pluggy-0.4.0 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-47439103, inifile:
collected 3 items                                                                                                                                                                                   

test_google.py::GoogleTests::test_gmail_page_title PASSED
test_google.py::GoogleTests::test_google_page_title PASSED
test_stackoverflow.py::StackoverflowTests::test_so_page_title PASSED

================ 3 passed in 13.81 seconds ================

并行运行测试

这需要pytest-xdist的{​​{1}}插件。通过pytest

安装
pip

该插件现已安装,但默认情况下不会处于活动状态,因此如果您再次运行$ pip install pytest-xdist ,则不会发现任何差异。使用pytest键并行化测试执行。这表示为运行测试而保留的进程数,这里我使用numprocesses值来生成与我的机器具有的CPU数量一样多的进程:

auto

您将看到所有三个测试由三个同时打开的chrome实例并行运行。每个测试都在自己的过程中运行,因此它们不会相互干扰。另外,请注意$ pytest -v --numprocesses=auto ================ test session starts ================ platform darwin -- Python 3.6.3, pytest-3.2.5, py-1.5.2, pluggy-0.4.0 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6 cachedir: .cache rootdir: /Users/hoefling/projects/private/stackoverflow/so-47439103, inifile: plugins: xdist-1.20.1, forked-0.2 [gw0] darwin Python 3.6.3 cwd: /Users/hoefling/projects/private/stackoverflow/so-47439103 [gw1] darwin Python 3.6.3 cwd: /Users/hoefling/projects/private/stackoverflow/so-47439103 [gw2] darwin Python 3.6.3 cwd: /Users/hoefling/projects/private/stackoverflow/so-47439103 [gw3] darwin Python 3.6.3 cwd: /Users/hoefling/projects/private/stackoverflow/so-47439103 [gw0] Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) -- [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] [gw1] Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) -- [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] [gw2] Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) -- [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] [gw3] Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) -- [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] gw0 [3] / gw1 [3] / gw2 [3] / gw3 [3] scheduling tests via LoadScheduling test_google.py::GoogleTests::test_google_page_title test_stackoverflow.py::StackoverflowTests::test_so_page_title test_google.py::GoogleTests::test_gmail_page_title [gw0] PASSED test_google.py::GoogleTests::test_gmail_page_title [gw1] PASSED test_google.py::GoogleTests::test_google_page_title [gw2] PASSED test_stackoverflow.py::StackoverflowTests::test_so_page_title ================ 3 passed in 7.81 seconds ================ 类中的两个测试方法也是并行运行的,因此不限于不同模块或类中的测试。

GoogleTests

集成

当我第一次开始迁移到setup.py时,我遇到的一个条件是命令pytest应该仍然有效,所以我们不需要记住额外的python setup.py test命令运行测试,因此我们也不必在我们的集成服务器上调整所有实用程序脚本或构建作业,因此以下是更新pytest脚本的步骤:

  1. 将以下包添加到测试要求中:

    setup.py
  2. from setuptools import setup setup( ... tests_require=[ 'pytest', 'pytest-runner', # this one is needed to install distutils command for pytest 'pytest-xdist' ], ) 添加别名:

    setup.cfg
  3. [aliases] test=pytest 中添加pytest的配置部分:

    setup.cfg
  4. 现在,如果您运行[tool:pytest] addopts=--verbose --numprocesses=auto ,则会调用正确的跑步者,默认情况下python setup.py test插件将处于活动状态。

    附加说明

    我个人非常喜欢xdist,因为它提供的不仅仅是简单的测试执行 - 您可以将测试编写为纯函数(不需要包装到pytest类中),在不执行测试的情况下收集测试,轻松仅重新运行最近失败的测试,将代码覆盖率测量与不同格式的多个报告挂钩等等。有关详细信息,请参阅official docs,这非常值得阅读!