简体   繁体   English

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

[英]How to execute tests in a test suite in parallel

I have managed to run tests in parallel by using webdriver against a selenium hub and node. 我已经通过针对硒集线器和节点使用webdriver来并行运行测试。 This code called before the tests is run. 在运行测试之前调用此代码。

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()

In that way I can start multiple browsers by executing them manually from Eclipse. 这样,我可以通过从Eclipse手动执行多个浏览器来启动它们。 However I would like to do that automatically in a testsuite. 但是,我想在测试套件中自动执行此操作。 But in a test suite all tests are started in a sequence. 但是在测试套件中,所有测试都是按顺序开始的。 If anyone has an idea how to proceed it would be great. 如果有人知道如何进行,那将很棒。

Preliminaries 预赛

I prepared some sample tests for playing with. 我准备了一些用于测试的示例测试。 These are some simple page title checks. 这些是一些简单的页面标题检查。 We have one module test_google.py with two unit tests that check the titles of www.google.com and mail.google.com : 我们有一个模块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'

The second module is test_stackoverflow.py that contains one test that checks the title of stackoverflow.com : 第二个模块是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

Running the tests with the bare unittest runner yields: 使用裸露的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

Migration to pytest 迁移到pytest

Install pytest via pip : 通过pip安装pytest

$ pip install pytest

pytest supports unit tests out of the box, so we don't need to touch the tests, we can run them immediately. pytest支持单元测试,因此我们不需要进行测试,我们可以立即运行它们。 Trying out the pytest runner: 试用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 ================

Running tests in parallel 并行运行测试

This requires pytest-xdist plugin for pytest . 这需要pytest-xdist的插件pytest Install it via pip : 通过pip安装:

$ pip install pytest-xdist

The plugin is installed now, but won't be active by default, so if you run pytest again, you won't notice any difference. 该插件现已安装,但默认情况下不会处于活动状态,因此,如果再次运行pytest ,则不会发现任何差异。 Use the numprocesses key to parallelize the test execution. 使用numprocesses键来并行化测试执行。 This denotes the number of processes that are reserved to run the tests, here I use the auto value to spawn as many processes as many CPUs my machine has: 这表示保留用于运行测试的进程数,在这里,我使用auto值生成与我的计算机拥有的CPU数量一样多的进程:

$ 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 ================

You will see that all the three tests run in parallel by three chrome instances opened simultaneously. 您将看到,所有三个测试都是通过同时打开的三个chrome实例并行运行的。 Each test runs in own process, so they don't interfere with each other. 每个测试都在自己的过程中运行,因此它们不会互相干扰。 Also, notice that both test methods from the GoogleTests class also run in parallel, so this is not restricted to tests in different modules or classes. 另外,请注意,来自GoogleTests类的两个测试方法也可以并行运行,因此,这不仅限于不同模块或类中的测试。

Integration with setup.py setup.py集成

When I first started the migration to pytest , one of the conditions I had was that the command python setup.py test should still work so we don't need to memorize an extra pytest command to run the tests and so we also don't have to adapt all our utility scripts or build jobs on our integration server, so here are the steps to update your setup.py script: 当我第一次开始向pytest迁移时,我遇到的条件之一就是命令python setup.py test仍然可以运行,因此我们不需要记住额外的pytest命令来运行测试,因此我们也不必必须调整我们所有的实用程序脚本或在集成服务器上构建作业,因此以下是更新setup.py脚本的步骤:

  1. Add the following packages to test requirements: 添加以下软件包以测试需求:

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

     [aliases] test=pytest 
  3. Add a configuration section for pytest in setup.cfg : setup.cfgpytest添加一个配置部分:

     [tool:pytest] addopts=--verbose --numprocesses=auto 

Now, if you run python setup.py test , the correct runner will be invoked and the xdist plugin will be active by default. 现在,如果您运行python setup.py test ,则将调用正确的运行程序,并且默认情况下xdist插件将处于活动状态。

Additional notes 补充笔记

I personally really like pytest as it offers much more than a plain test execution - you can write tests as pure functions (no wrapping into TestCase classes required), collect tests without executing them, easily rerun only tests that failed recently, hook the code coverage measurement with multiple reports in different formats and many more. 我个人真的很喜欢pytest因为它提供的功能不仅仅包括简单的测试执行-您可以将测试编写为纯函数(无需包装到TestCase类中),无需执行即可收集测试,轻松地仅重新运行最近失败的测试,并覆盖代码覆盖范围多种格式不同的报告进行测量。 Refer to the official docs for more details, it is really worth the reading time! 有关更多详细信息,请参阅官方文档 ,这确实值得阅读!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM