allure-framework / allure-python

Allure integrations for Python test frameworks
https://allurereport.org/
Apache License 2.0
713 stars 233 forks source link

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

Open iachen opened 7 months ago

iachen commented 7 months ago

I'm submitting a ...

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:

Other information

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

delatrie commented 7 months ago

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.

iachen commented 7 months ago

@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.

SunChao3555 commented 5 months ago

@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`

ashea commented 2 months ago

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