allure-python icon indicating copy to clipboard operation
allure-python copied to clipboard

Get "KeyError: None" On While Exwcuting with Pytest Command with Generating Allure Report

Open iachen opened this issue 2 years ago • 4 comments

I'm submitting a ...

  • [ ] bug report

What is the current behavior?

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

Hi I am beginner for the script programming and I got problem as mentioned in following.

I wrote a test script and would like to attach screenshot to the generated Allure report. This this the part of the code which include the allure.attach part

if d(resourceId="com.plumewifi.plume.dogfood:id/daily_sleep_summary_message_title").exists(timeout=3):
    print("-------------------- Sleep card found ---------------------------------")
    d.screenshot("./pic/Sleep-L1.png")
    allure.attach.file("./pic/L1.png", attachment_type=allure.attachment_type.PNG)

And it will get the error with exexuting the command pytest -vv --show-capture=all test-xxxx.py --alluredir=./result/1

collected 0 items / 1 error                                                                                                                               

========================================================================= ERRORS =========================================================================
_________________________________________________ ERROR collecting test-Android_HP_SleepL1(practice).py __________________________________________________
venv\lib\site-packages\_pytest\runner.py:341: in from_call
    result: Optional[TResult] = func()
venv\lib\site-packages\_pytest\runner.py:372: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
venv\lib\site-packages\_pytest\python.py:531: in collect
    self._inject_setup_module_fixture()
venv\lib\site-packages\_pytest\python.py:545: in _inject_setup_module_fixture
    self.obj, ("setUpModule", "setup_module")
venv\lib\site-packages\_pytest\python.py:310: in obj
    self._obj = obj = self._getobj()
venv\lib\site-packages\_pytest\python.py:528: in _getobj
    return self._importtestmodule()
venv\lib\site-packages\_pytest\python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
venv\lib\site-packages\_pytest\pathlib.py:567: in import_path
    importlib.import_module(module_name)
..\..\AppData\Local\Programs\Python\Python38\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
venv\lib\site-packages\_pytest\assertion\rewrite.py:186: in exec_module
    exec(co, module.__dict__)
test-Android_HP_SleepL1(practice).py:92: in <module>
    allure.attach.file("./pic/L1.png", attachment_type=allure.attachment_type.PNG)
venv\lib\site-packages\allure_commons\_allure.py:203: in file
    plugin_manager.hook.attach_file(source=source, name=name, attachment_type=attachment_type, extension=extension)
venv\lib\site-packages\pluggy\_hooks.py:493: in __call__
    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
venv\lib\site-packages\pluggy\_manager.py:115: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
venv\lib\site-packages\allure_pytest\listener.py:253: in attach_file
    self.allure_logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)
venv\lib\site-packages\allure_commons\reporter.py:158: in attach_file
    file_name = self._attach(uuid, name=name, attachment_type=attachment_type,
venv\lib\site-packages\allure_commons\reporter.py:153: in _attach
    self._items[last_uuid].attachments.append(attachment)
venv\lib\site-packages\allure_commons\reporter.py:33: in __getitem__
    return self.thread_context.__getitem__(item)
E   KeyError: None

The line d.screenshot("./pic/L1.png") which is with uiautomator2 command can work fine(screenshot is capured). And if I comment/remove the line allure.attach.file("./pic/L1.png", attachment_type=allure.attachment_type.PNG), the script can run without error.

Also, if I run the command without generating the allure report(pytest -vv --show-capture=all test-xxxx.py), the script can run and complete(so the error is caused with that line of "allure.attach.file").

I surveyed and checked with https://github.com/allure-framework/allure-python/issues/431 and https://github.com/allure-framework/allure2/issues/570, looks like there is no further discussion.

What is the expected behavior?

The attached work to Allure should work.

Please tell us about your environment:

  • Allure version: 2.25.0
  • Test framework: pytest-7.4.3
  • Allure adaptor: allure-pytest-2.13.2
  • OS: Windows 10

Other information

Please let me know if I need to provide more information.

iachen avatar Dec 05 '23 09:12 iachen

The testing code needs to be put in a test function:


def test_sleep_card():
    if d(resourceId="com.plumewifi.plume.dogfood:id/daily_sleep_summary_message_title").exists(timeout=3):
        print("-------------------- Sleep card found ---------------------------------")
        d.screenshot("./pic/Sleep-L1.png")
        allure.attach.file("./pic/L1.png", attachment_type=allure.attachment_type.PNG)

The function then gets executed by pytest, and Allure creates the test result from it. When you generate the report, the attachment can be found under that test result.

delatrie avatar Dec 05 '23 12:12 delatrie

@delatrie ,

The testing code needs to be put in a test function:

Thanks for the reply. Do you mean it cannot work "allure.attach.file" is outside the test function?

If so, is there any way to do the same thing? Since I'd like to take a screeshot before I start the test.

Thanks.

iachen avatar Dec 05 '23 13:12 iachen

@delatrie ,

The testing code needs to be put in a test function:

Thanks for the reply. Do you mean it cannot work "allure.attach.file" is outside the test function?

If so, is there any way to do the same thing? Since I'd like to take a screeshot before I start the test.

Thanks.

##Perhaps there are some decorators in your code, such as "@func_set_timeout", and you can try removing them and implementing them yourself `

import signal import allure #####from func_timeout import func_set_timeout

def func_set_timeout(timeout): """implementing by yourself""" def decorator(func): def wrapper(*args, **kwargs): signal.alarm(timeout) try: result = func(*args, **kwargs) except Exception as e: raise e finally: signal.alarm(0) return result return wrapper return decorator

@func_set_timeout(120) def send_command(cmd): allure.attach(...) pass`

SunChao3555 avatar Jan 20 '24 09:01 SunChao3555

Hello, I'm facing the same issue here, were you able to resolve it? @iachen

ashea avatar May 01 '24 13:05 ashea

Hello, I'm facing the same issue here, were you able to resolve it? @iachen

Hi @ashea Sorry for the late reply, it can work after moving "allure.attach.file" into test_func() like @delatrie mentioned.

iachen avatar Jul 16 '24 13:07 iachen