最近、pytest を使用して自動テスト スイートを実行し始めました。順次実行すると正常に完了していたテスト実行が、xdist を使用してスイートを並行して実行するとランダムに失敗するようになりました。次のように pytest を構成しました。
[pytest]
addopts = -nauto --rerun 3 -ra --timeout=180 --junit-xml=pyresult.xml
python_files=test*.py
ランダムにテストが Chromedriver の起動に失敗し、最終的にタイムアウトがスローされます。不安定な理由で失敗したテストの他のすべてのインスタンスについては、pytest は喜んでテストを再実行します。ただし、この例では、タイムアウトがスローされると、pytest はタイムアウトを出力してハングします。テストの実行が終わらないため、Jenkins は待っている結果を取得できません。pytest を終了させる唯一の方法は、手動でコントロール ブレークを送信することです。
私のドライバーは次のように開始されます (私のコードがここで問題になっているとは思わないことに注意してください)。
@classmethod
def open_browser(cls, browser_name, configuration, down_dir=""):
"""
Returns the driver for the required browser
"""
if browser_name == 'Chrome':
chrome_options = webdriver.ChromeOptions()
prefs = {"download.default_directory" : down_dir}
chrome_options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(
executable_path=configuration, chrome_options=chrome_options)
タイムアウト メッセージは次のとおりです。
~~~~~~~~~~~~~~~~~~~~~~~~~~ Stack of <unknown> (8460) ~~~~~~~~~~~~~~~~~~~~~~~~~~~
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 277, in _perform_spawn
reply.run()
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 213, in run
self._result = func(*args, **kwargs)
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 954, in _thread_receiver
msg = Message.from_io(io)
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 418, in from_io
header = io.read(9) # type 1, channel 4, payload 4
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 386, in read
data = self._read(numbytes-len(buf))
~~~~~~~~~~~~~~~~~~~~~~~~~ Stack of MainThread (12788) ~~~~~~~~~~~~~~~~~~~~~~~~~~
File "<string>", line 1, in <module>
File "<string>", line 7, in <module>
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 1534, in serve
SlaveGateway(io=io, id=id, _startcount=2).serve()
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 1047, in serve
self._execpool.integrate_as_primary_thread()
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 259, in integrate_as_primary_thread
self._perform_spawn(reply)
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 277, in _perform_spawn
reply.run()
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 213, in run
self._result = func(*args, **kwargs)
File "c:\python27\lib\site-packages\execnet\gateway_base.py", line 1072, in executetask
do_exec(co, loc) # noqa
File "<string>", line 1, in do_exec
File "<remote exec>", line 154, in <module>
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 724, in __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 338, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 333, in <lambda>
_MultiCall(methods, kwargs, hook.spec_opts).execute()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 596, in execute
res = hook_impl.function(*args)
File "c:\python27\lib\site-packages\_pytest\main.py", line 119, in pytest_cmdline_main
return wrap_session(config, _main)
File "c:\python27\lib\site-packages\_pytest\main.py", line 94, in wrap_session
session.exitstatus = doit(config, session) or 0
File "c:\python27\lib\site-packages\_pytest\main.py", line 125, in _main
config.hook.pytest_runtestloop(session=session)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 724, in __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 338, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 333, in <lambda>
_MultiCall(methods, kwargs, hook.spec_opts).execute()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 596, in execute
res = hook_impl.function(*args)
File "<remote exec>", line 58, in pytest_runtestloop
File "<remote exec>", line 74, in run_tests
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 724, in __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 338, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 333, in <lambda>
_MultiCall(methods, kwargs, hook.spec_opts).execute()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 595, in execute
return _wrapped_call(hook_impl.function(*args), self.execute)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 247, in _wrapped_call
call_outcome = _CallOutcome(func)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 264, in __init__
self.result = func()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 595, in execute
return _wrapped_call(hook_impl.function(*args), self.execute)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 247, in _wrapped_call
call_outcome = _CallOutcome(func)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 264, in __init__
self.result = func()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 596, in execute
res = hook_impl.function(*args)
File "c:\python27\lib\site-packages\pytest_rerunfailures.py", line 73, in pytest_runtest_protocol
reports = runtestprotocol(item, nextitem=nextitem, log=False)
File "c:\python27\lib\site-packages\_pytest\runner.py", line 76, in runtestprotocol
reports.append(call_and_report(item, "call", log))
File "c:\python27\lib\site-packages\_pytest\runner.py", line 120, in call_and_report
call = call_runtest_hook(item, when, **kwds)
File "c:\python27\lib\site-packages\_pytest\runner.py", line 138, in call_runtest_hook
return CallInfo(lambda: ihook(item=item, **kwds), when=when)
File "c:\python27\lib\site-packages\_pytest\runner.py", line 150, in __init__
self.result = func()
File "c:\python27\lib\site-packages\_pytest\runner.py", line 138, in <lambda>
return CallInfo(lambda: ihook(item=item, **kwds), when=when)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 724, in __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 338, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 333, in <lambda>
_MultiCall(methods, kwargs, hook.spec_opts).execute()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 595, in execute
return _wrapped_call(hook_impl.function(*args), self.execute)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 247, in _wrapped_call
call_outcome = _CallOutcome(func)
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 264, in __init__
self.result = func()
File "c:\python27\lib\site-packages\_pytest\vendored_packages\pluggy.py", line 596, in execute
res = hook_impl.function(*args)
File "c:\python27\lib\site-packages\_pytest\runner.py", line 91, in pytest_runtest_call
item.runtest()
File "c:\python27\lib\site-packages\_pytest\unittest.py", line 151, in runtest
self._testcase(result=self)
File "c:\python27\lib\unittest\case.py", line 393, in __call__
return self.run(*args, **kwds)
File "c:\python27\lib\unittest\case.py", line 320, in run
self.setUp()
File "C:\Users\rhoward\Documents\GitHub\ui-selenium-tests\ui_selenium_tests\test010_provider_application_accordia
n.py", line 94, in setUp
self.used_browser, self.browser_config)
File "C:\Users\rhoward\Documents\GitHub\ui-selenium-tests\ui_selenium_tests\general_functions.py", line 198, in o
pen_browser
executable_path=configuration, chrome_options=chrome_options)
File "c:\python27\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 67, in __init__
desired_capabilities=desired_capabilities)
File "c:\python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 91, in __init__
self.start_session(desired_capabilities, browser_profile)
File "c:\python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 173, in start_session
'desiredCapabilities': desired_capabilities,
File "c:\python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 231, in execute
response = self.command_executor.execute(driver_command, params)
File "c:\python27\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 395, in execute
return self._request(command_info[0], url, body=data)
File "c:\python27\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 426, in _request
resp = self._conn.getresponse()
File "c:\python27\lib\httplib.py", line 1136, in getresponse
response.begin()
File "c:\python27\lib\httplib.py", line 453, in begin
version, status, reason = self._read_status()
File "c:\python27\lib\httplib.py", line 409, in _read_status
line = self.fp.readline(_MAXLINE + 1)
File "c:\python27\lib\socket.py", line 480, in readline
data = self._sock.recv(self._rbufsize)
+++++++++++++++++++++++++++++++++++ Timeout ++++++++++++++++++++++++++++++++++++
理想的には、pytest にタイムアウトを記録してもらいたいのですが、テストを再実行して、通常どおりテストの実行を終了するだけです。