'Pytest - Extract data generated by test run to a file/ fixture in conftest?

I am using Pytest framwork for testing a web applications. While the tests run, it generates data and store them into variables.

Example:

@pytest.mark.usefixture("test_setup")
class TestArticleCreation:
    def test_new_article_creation(self):
        art = ArticleCreation(self.driver)
        art.create_new_article()
        article_id = art.get_new_article_id()
        assert art.verify_article_created_in_db(article_id)

I want to extract article_id, and store it so i can delete it later, but i do not want the ids extraction process to be part of the test itself, even tho i cannot think/ know of any other way to do that beside adding a function to the test, that will write article_id value to a file. Does Pytest provide solution for this?

I use conftest.py to build configurations, and the project is built with POM design pattern if thats help somehow.

Thanks in advance.



Solution 1:[1]

I have found a nice solution, not sure its the best.. It is possible to extract variables from module level,

So above the TestClass i declared a new variable, type(list). When a test generating an id, i can add it to the list above,

# tests/test_sanity.py
article_ids = []

@pytest.mark.usefixtures("test_setup")  # USE "test_setup"   FIXTURE with scope=class
class TestSanity:

    def test_global_var(self):
        art_id = '12321342154'
        global article_ids  # Declare the in module var as global
        article_ids.append(art_id)  # Add id generated in test run
        assert article_id == '12321342154'


# conftest.py

@pytest.mark.hookwrapper  # Add hook wrapper to tests teardown
def pytest_runtest_teardown(item):
    yield
    print(item.module.article_ids)  # By this access the global var decalred in our test module

Only problem i face right now is the hook wrapper called each test and not per session.

Edit:

Found another way to do so:

@pytest.fixture(scope="session")
def ids():
    ids = []
    yield ids
    print(ids)


@pytest.fixture(scope="class")
def api_setup(request, ids):
    request.cls.ids = ids

@pytest.mark.usefixtures("api_setup") 
class TestSome:
    def test_something(self):
        global article_ids
        art_id = '123'
        self.ids.append(art_id)
        assert art_id == '123'

This way it does add each id generated to the list, but does not call conftest.py at the end of each test

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1