我在
conftest
文件中有此代码(使用 pytest
+ selenium
运行自动化):
import os
from urllib import request
import pytest
from selenium.webdriver.chrome.options import Options
import allure
from selenium import webdriver
@pytest.fixture(autouse=True)
def setup(request):
global driver
options = Options()
options.add_experimental_option("detach", True)
options.add_argument("--headless")
# options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
# options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
request.cls.driver = driver
driver.maximize_window()
driver.get("https://magento.softwaretestingboard.com/")
yield
driver.quit()
def pytest_exception_interact(report):
if report.failed:
allure.attach(body=driver.get_screenshot_as_png(), name="screenshot",
attachment_type=allure.attachment_type.PNG)
def pytest_sessionfinish() -> None:
environment_properties = {
'browser': driver.name,
'driver_version': driver.capabilities['browserVersion']
}
allure_env_path = os.path.join("allure-results", 'environment.properties')
with open(allure_env_path, 'w') as f:
data = '\n'.join([f'{variable}={value}' for variable, value in environment_properties.items()])
f.write(data)
并行运行 pytest 时会出现问题(
pytest -n 5 --dist loadgroup --alluredir=allure-results --reruns 2 --reruns-delay 2
)。这是由于 pytest_sessionfinish
在 allure 报告中添加了环境变量(例如浏览器和浏览器版本)。运行时出现错误:
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Scripts\pytest.exe\__main__.py", line 7, in <module>
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\config\__init__.py", line 198, in console_main
code = main()
^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\config\__init__.py", line 175, in main
ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_hooks.py", line 493, in __call__
return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_manager.py", line 115, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 113, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 77, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\main.py", line 320, in pytest_cmdline_main
return wrap_session(config, _main)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\main.py", line 308, in wrap_session
config.hook.pytest_sessionfinish(
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_hooks.py", line 493, in __call__
return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_manager.py", line 115, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 113, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 96, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\logging.py", line 861, in pytest_sessionfinish
return (yield)
^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 96, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\terminal.py", line 854, in pytest_sessionfinish
result = yield
^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 96, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\_pytest\warnings.py", line 138, in pytest_sessionfinish
return (yield)
^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\.venv\Lib\site-packages\pluggy\_callers.py", line 77, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\benik\PycharmProjects\pythonAutomationStore\tests\conftest.py", line 48, in pytest_sessionfinish
driver = session.config._driver
^^^^^^^^^^^^^^^^^^^^^^
当 pytest 运行多个进程(或并行测试)时,我还尝试将环境变量添加到 allure 报告中。
您可以使用https://github.com/seleniumbase/SeleniumBase(selenium + pytest的完整框架)来解决您的多线程问题: 在
pip install seleniumbase
之后,您可以使用 pytest
运行以下命令:
(
allure-pytest
单独安装。激活:pytest --alluredir=allure_results
:
from seleniumbase import BaseCase
class BaseTestCase(BaseCase):
def setUp(self):
super().setUp()
self.driver.get("https://magento.softwaretestingboard.com/")
def tearDown(self):
self.save_teardown_screenshot() # If test fails, or if "--screenshot"
if self.has_exception():
pass # <<< Run custom code if the test failed. >>>
else:
pass # <<< Run custom code if the test passed. >>>
# <<< Run custom tearDown() code BEFORE the super().tearDown() >>>
super().tearDown()
class MyTests(BaseTestCase):
def test_1(self):
self.click('''span:contains("What's New")''')
self.sleep(1)
def test_2(self):
self.type("#search", "Tees and Tops\n")
self.sleep(1)
def test_3(self):
self.hover_and_js_click('span:contains("Gear")', 'span:contains("Bags")')
self.sleep(1)
def test_4(self):
self.hover_and_js_click('span:contains("Gear")', 'span:contains("Watches")')
self.sleep(1)
def test_5(self):
self.click('''span:contains("Sale")''')
self.sleep(1)
您可以自定义
setUp()
和 tearDown()
,但请确保保留 super()
部分。如果测试失败,屏幕截图会自动保存到 ./latest_logs/
文件夹中。如果您想使用 Allure 保存屏幕截图,请添加到 tearDown()
部分。
Headless Selenium 模式可以通过 pytest 激活:
pytest --headless
。