Я пишу тестовый скрипт с использованием pywinauto и pytest для автоматизации взаимодействия с приложением. Сценарий открывает первое диалоговое окно, вводит путь к файлу в текстовое поле и нажимает кнопку «ОК», чтобы перейти ко второму диалоговому окну. Вот мой код:
Когда я запускаю тест, он успешно выполняется в моем приложении. Первое диалоговое окно закроется, а второе откроется с правильной информацией, как и ожидалось. Однако сам тест завершается неудачно и выдает такую ошибку:
An error has occurred in testops-pytest plugin.
Testing session starts here
================================================================== test session starts ===================================================================
platform win32 -- Python 3.12.4, pytest-7.4.0, pluggy-1.5.0
rootdir: C:\Sim\Pytest_Automation
configfile: pytest.ini
plugins: html-reporter-0.2.9
collected 1 item
Test setup
TestSuite started: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py
self =
criteria = [{'app': , 'backend': 'uia'}, {'control_type': 'Window...t from OpenAPI/ Swagger', 'top_level_only': False}, {'control_type': 'Button', 'title': 'OK', 'top_level_only': False}]
timeout = 5.0, retry_interval = 0.09
def __resolve_control(self, criteria, timeout=None, retry_interval=None):
"""
Find a control using criteria
* **criteria** - a list that contains 1 or 2 dictionaries
1st element is search criteria for the dialog
2nd element is search criteria for a control of the dialog
* **timeout** - maximum length of time to try to find the controls (default 5)
* **retry_interval** - how long to wait between each retry (default .2)
"""
if timeout is None:
timeout = Timings.window_find_timeout
if retry_interval is None:
retry_interval = Timings.window_find_retry
try:
> ctrl = wait_until_passes(
timeout,
retry_interval,
self.__get_ctrl,
(findwindows.ElementNotFoundError,
findbestmatch.MatchError,
controls.InvalidWindowHandle,
controls.InvalidElement),
criteria)
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\application.py:250:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
timeout = 5.0, retry_interval = 0.09
func =
exceptions = (, , , )
args = ([{'app': , 'backend': 'uia'}, {'control_type': 'Windo...from OpenAPI/ Swagger', 'top_level_only': False}, {'control_type': 'Button', 'title': 'OK', 'top_level_only': False}],)
kwargs = {}, start = 4855.270656, time_left = -0.1260935000000245, err = TimeoutError()
def wait_until_passes(timeout,
retry_interval,
func,
exceptions=(Exception),
*args, **kwargs):
"""
Wait until ``func(*args, **kwargs)`` does not raise one of the exceptions
* **timeout** how long the function will try the function
* **retry_interval** how long to wait between retries
* **func** the function that will be executed
* **exceptions** list of exceptions to test against (default: Exception)
* **args** optional arguments to be passed to func when called
* **kwargs** optional keyword arguments to be passed to func when called
Returns the return value of the function
If the operation times out then the original exception raised is in
the 'original_exception' attribute of the raised exception.
e.g. ::
try:
# wait a maximum of 10.5 seconds for the
# window to be found in increments of .5 of a second.
# P.int a message and re-raise the original exception if never found.
wait_until_passes(10.5, .5, self.Exists, (ElementNotFoundError))
except TimeoutError as e:
print("timed out")
raise e.
"""
start = timestamp()
# keep trying until the timeout is passed
while True:
try:
# Call the function with any arguments
func_val = func(*args, **kwargs)
# if no exception is raised then we are finished
break
# An exception was raised - so wait and try again
except exceptions as e:
# find out how much of the time is left
time_left = timeout - (timestamp() - start)
# if we have to wait some more
if time_left > 0:
# wait either the retry_interval or else the amount of
# time until the timeout expires (whichever is less)
time.sleep(min(retry_interval, time_left))
else:
# Raise a TimeoutError - and put the original exception
# inside it
err = TimeoutError()
err.original_exception = e
> raise err
E pywinauto.timings.TimeoutError
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\timings.py:458: TimeoutError
During handling of the above exception, another exception occurred:
katApp =
@pytest.mark.P1
@pytest.mark.Smoke
def test_Importing_OpenApiFile_Without_Genenerating_TC(katApp):
btnImportOpenApiIcon = katApp.child_window(title="Import from OpenAPI/ Swagger", control_type="Button")
btnImportOpenApiIcon.click_input()
dlgImportOpenApi = katApp.child_window(title="Import REST request from OpenAPI/ Swagger", control_type="Window")
txtFileInput = dlgImportOpenApi.child_window(control_type="Edit")
btnOk = dlgImportOpenApi.child_window(title="OK", control_type="Button")
txtFileInput.type_keys(GlobalVariables.g_OpenAPI3File + "~",with_spaces=True)
> btnOk.click_input()
TestCases\ApiTestGeneration\test_Api_Testcase_Generation.py:73:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\application.py:379: in __getattribute__
ctrls = self.__resolve_control(self.criteria)
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\application.py:261: in __resolve_control
raise e.original_exception
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\timings.py:436: in wait_until_passes
func_val = func(*args, **kwargs)
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\application.py:222: in __get_ctrl
ctrl = self.backend.generic_wrapper_class(findwindows.find_element(**ctrl_criteria))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
kwargs = {'backend': 'uia', 'control_type': 'Window', 'parent': , 'title': 'Import REST request from OpenAPI/ Swagger', ...}
elements = []
def find_element(**kwargs):
"""
Call find_elements and ensure that only one element is returned
Calls find_elements with exactly the same arguments as it is called with
so please see :py:func:`find_elements` for the full parameters description.
"""
elements = find_elements(**kwargs)
if not elements:
> raise ElementNotFoundError(kwargs)
E pywinauto.findwindows.ElementNotFoundError: {'title': 'Import REST request from OpenAPI/ Swagger', 'control_type': 'Window', 'top_level_only': False, 'parent': , 'backend': 'uia'}
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\findwindows.py:87: ElementNotFoundError
FTestCase finished: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py::test_Importing_OpenApiFile_Without_Genenerating_TC
TestSuite started: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py
Test teardown
Test case: test_Importing_OpenApiFile_Without_Genenerating_TC failed, so restart App
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 270, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 324, in _main
INTERNALERROR> config.hook.pytest_runtestloop(session=session)
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_hooks.py", line 513, in __call__
INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_manager.py", line 120, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 182, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_result.py", line 100, in get_result
INTERNALERROR> raise exc.with_traceback(exc.__traceback__)
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 103, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 349, in pytest_runtestloop
INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_hooks.py", line 513, in __call__
INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_manager.py", line 120, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 182, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_result.py", line 100, in get_result
INTERNALERROR> raise exc.with_traceback(exc.__traceback__)
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 103, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> File "C:\Sim\Pytest_Automation\TestCases\conftest.py", line 38, in pytest_runtest_protocol
INTERNALERROR> im.save("{}\\{}.jpg".format(GlobalVariables.g_ScreenShootCaptureFolder,item.name))
INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\PIL\Image.py", line 2563, in save
INTERNALERROR> fp = builtins.open(filename, "w+b")
INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INTERNALERROR> FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Sim\\Pytest_Automation\\ScreenshotCapture\\test_Importing_OpenApiFile_Without_Genenerating_TC.jpg'
Processing test result...
Uploading report to TestOps...
TestOps Configuration:
{
"api_key": "*",
"baseline_collection_id": -1,
"build_label": null,
"build_url": null,
"project_id": 918299,
"proxy_information": {
"host": null,
"password": "",
"port": -1,
"protocol": "http",
"username": ""
},
"report_folder": "report",
"server_url": "https://testops.katalon.io"
}
Testing session ends here
Не могли бы вы помочь мне определить, где в моем коде может быть проблема? Спасибо!
Я пишу тестовый скрипт с использованием pywinauto и pytest для автоматизации взаимодействия с приложением. Сценарий открывает первое диалоговое окно, вводит путь к файлу в текстовое поле и нажимает кнопку «ОК», чтобы перейти ко второму диалоговому окну. Вот мой код: [code]def test_Importing_OpenApiFile_Without_Genenerating_TC(katApp): btnImportOpenApiIcon = katApp.child_window(title="Import from OpenAPI/ Swagger", control_type="Button") btnImportOpenApiIcon.click_input() dlgImportOpenApi = katApp.child_window(title="Import REST request from OpenAPI/ Swagger", control_type="Window") txtFileInput = dlgImportOpenApi.child_window(control_type="Edit") btnOk = dlgImportOpenApi.child_window(title="OK", control_type="Button")
txtFileInput.type_keys(GlobalVariables.g_OpenAPI3File + "~",with_spaces=True) btnOk.click_input() [/code] Когда я запускаю тест, он успешно выполняется в моем приложении. Первое диалоговое окно закроется, а второе откроется с правильной информацией, как и ожидалось. Однако сам тест завершается неудачно и выдает такую ошибку: [code]An error has occurred in testops-pytest plugin. Testing session starts here ================================================================== test session starts =================================================================== platform win32 -- Python 3.12.4, pytest-7.4.0, pluggy-1.5.0 rootdir: C:\Sim\Pytest_Automation configfile: pytest.ini plugins: html-reporter-0.2.9 collected 1 item Test setup TestSuite started: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py self = criteria = [{'app': , 'backend': 'uia'}, {'control_type': 'Window...t from OpenAPI/ Swagger', 'top_level_only': False}, {'control_type': 'Button', 'title': 'OK', 'top_level_only': False}] timeout = 5.0, retry_interval = 0.09
def __resolve_control(self, criteria, timeout=None, retry_interval=None): """ Find a control using criteria
* **criteria** - a list that contains 1 or 2 dictionaries
1st element is search criteria for the dialog
2nd element is search criteria for a control of the dialog
* **timeout** - maximum length of time to try to find the controls (default 5) * **retry_interval** - how long to wait between each retry (default .2) """ if timeout is None: timeout = Timings.window_find_timeout if retry_interval is None: retry_interval = Timings.window_find_retry
def wait_until_passes(timeout, retry_interval, func, exceptions=(Exception), *args, **kwargs): """ Wait until ``func(*args, **kwargs)`` does not raise one of the exceptions
* **timeout** how long the function will try the function * **retry_interval** how long to wait between retries * **func** the function that will be executed * **exceptions** list of exceptions to test against (default: Exception) * **args** optional arguments to be passed to func when called * **kwargs** optional keyword arguments to be passed to func when called
Returns the return value of the function If the operation times out then the original exception raised is in the 'original_exception' attribute of the raised exception.
e.g. ::
try: # wait a maximum of 10.5 seconds for the # window to be found in increments of .5 of a second. # P.int a message and re-raise the original exception if never found. wait_until_passes(10.5, .5, self.Exists, (ElementNotFoundError)) except TimeoutError as e: print("timed out") raise e. """ start = timestamp()
# keep trying until the timeout is passed while True: try: # Call the function with any arguments func_val = func(*args, **kwargs)
# if no exception is raised then we are finished break
# An exception was raised - so wait and try again except exceptions as e:
# find out how much of the time is left time_left = timeout - (timestamp() - start)
# if we have to wait some more if time_left > 0: # wait either the retry_interval or else the amount of # time until the timeout expires (whichever is less) time.sleep(min(retry_interval, time_left))
else: # Raise a TimeoutError - and put the original exception # inside it err = TimeoutError() err.original_exception = e > raise err E pywinauto.timings.TimeoutError
kwargs = {'backend': 'uia', 'control_type': 'Window', 'parent': , 'title': 'Import REST request from OpenAPI/ Swagger', ...} elements = []
def find_element(**kwargs): """ Call find_elements and ensure that only one element is returned
Calls find_elements with exactly the same arguments as it is called with so please see :py:func:`find_elements` for the full parameters description. """ elements = find_elements(**kwargs)
if not elements: > raise ElementNotFoundError(kwargs) E pywinauto.findwindows.ElementNotFoundError: {'title': 'Import REST request from OpenAPI/ Swagger', 'control_type': 'Window', 'top_level_only': False, 'parent': , 'backend': 'uia'}
C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pywinauto\findwindows.py:87: ElementNotFoundError FTestCase finished: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py::test_Importing_OpenApiFile_Without_Genenerating_TC TestSuite started: TestCases/ApiTestGeneration/test_Api_Testcase_Generation.py Test teardown
Test case: test_Importing_OpenApiFile_Without_Genenerating_TC failed, so restart App INTERNALERROR> Traceback (most recent call last): INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 270, in wrap_session INTERNALERROR> session.exitstatus = doit(config, session) or 0 INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 324, in _main INTERNALERROR> config.hook.pytest_runtestloop(session=session) INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_hooks.py", line 513, in __call__ INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_manager.py", line 120, in _hookexec INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 182, in _multicall INTERNALERROR> return outcome.get_result() INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_result.py", line 100, in get_result INTERNALERROR> raise exc.with_traceback(exc.__traceback__) INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 103, in _multicall INTERNALERROR> res = hook_impl.function(*args) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\_pytest\main.py", line 349, in pytest_runtestloop INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_hooks.py", line 513, in __call__ INTERNALERROR> return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_manager.py", line 120, in _hookexec INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 182, in _multicall INTERNALERROR> return outcome.get_result() INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_result.py", line 100, in get_result INTERNALERROR> raise exc.with_traceback(exc.__traceback__) INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\pluggy\_callers.py", line 103, in _multicall INTERNALERROR> res = hook_impl.function(*args) INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> File "C:\Sim\Pytest_Automation\TestCases\conftest.py", line 38, in pytest_runtest_protocol INTERNALERROR> im.save("{}\\{}.jpg".format(GlobalVariables.g_ScreenShootCaptureFolder,item.name)) INTERNALERROR> File "C:\Users\sim.tran\AppData\Roaming\Python\Python312\site-packages\PIL\Image.py", line 2563, in save INTERNALERROR> fp = builtins.open(filename, "w+b") INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ INTERNALERROR> FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Sim\\Pytest_Automation\\ScreenshotCapture\\test_Importing_OpenApiFile_Without_Genenerating_TC.jpg' Processing test result... Uploading report to TestOps... TestOps Configuration: { "api_key": "*", "baseline_collection_id": -1, "build_label": null, "build_url": null, "project_id": 918299, "proxy_information": { "host": null, "password": "", "port": -1, "protocol": "http", "username": "" }, "report_folder": "report", "server_url": "https://testops.katalon.io" } Testing session ends here
[/code] Не могли бы вы помочь мне определить, где в моем коде может быть проблема? Спасибо!
Я создаю новые модульные тесты для приложения и застрял, потому что KeyHolder не возвращает действительный объект.
Для контекста, вот мои классы :
Класс ScriptDao:
@Repository
public class ScriptDao extends DefaultDao {
Я использую платформу Codeception и среду IDE Netbeans для автоматизации тестирования с использованием PHP.
Я хотел бы запустить 2 теста один за другим в группе, где сначала будет запущен тест API, а после успешного запуска теста API следующим...
После создания нового модуля приложения («design-kit») в новом проекте Android я пытаюсь связать свое приложение с новым модулем, добавив в зависимость следующее:
implementation project( :design-kit )
Я пытаюсь использовать API C# для взаимодействия с VeriStand на основе официального руководства.
Я развернул демонстрационную версию Engine на шлюзе на локальном хосте.
На основе руководства , я написал свой код:
using...
Я пытаюсь использовать C# API (.NET Core 8) для взаимодействия с VeriStand.
На основе официального руководства я написал свой код:
using NationalInstruments.VeriStand.ClientAPI;
class Program
{
static void Main(string[] args)
{
string gatewayIp =...