In the last chapter, a hole was left at the end to be filled, and the question was this:

As far as we can see from official documentation

We have to be careful though, because pytest will run that finalizer once it’s been added, 
even if that fixture raises an exception after adding the finalizer. 
Copy the code

Once a finalizer is added, PyTest is executed.

However, when I tried throwing errors in the Setup code, the finalizer code didn’t execute. I tried to search the Internet but didn’t get effective help temporarily, so I had to propose issue to Pytest on GitHub, which is a pit to be solved later.

1. Review of problems

In fact, in the final analysis, I did not understand the right, maybe at that time I was in doubt will inevitably fall into a loop, and later on Github after others mention points before awakening. Let’s take a look at the code where I tried to demonstrate the above result: the setup code threw something wrong, but the finalizer code didn’t execute.

The code is split into two parts, one for the fixture function and the other for the test case. The code can not be directly copied out of the run, is I in the project use case for transformation, here only to help illustrate the meaning.

# content of conftest.py @pytest.fixture() def init_data_allot_task(request): query_sql = """ SELECT id FROM `sm_purchase_allot` WHERE `status`! =5 """ db = DB() data = db.fetch_one(query_sql) db.close() def demo_finalizer(): print("running finalizer code..." ) request.addfinalizer(demo_finalizer) return dataCopy the code
# content of testcase
...
def test_allot_detail(init_data_allot_task):
    """

    """
    payload = {
          "allotId": init_data_allot_task[0]
        }
    r = requests.post(QA_URL + API_URL, json=payload, headers=HEADER)
    result = r.json()

    assert result["result"] == "ok"
    assert result["errmsg"] == "success"
    assert len(result["row"]["taskListOfPage"]["resultData"]) > 0
Copy the code

The first thing I wanted to do was to have db = db () throw a mysql connection timeout error in my fixture function, and then see the “Running Finalizer code…” in the console. The output.

However, I did not see the expected output after the setup code was thrown, indicating that the addFinalizer code was not executed.

Finally, after advice from github friends, I found that I had misunderstood myself.

Second, problem solving

Here’s the official text:

We have to be careful though, because pytest will run that finalizer once it’s been added, 
even if that fixture raises an exception after adding the finalizer. 
Copy the code

Pytest will execute the Finalizer once it has been added. Even the fixture function throws an exception after finalizer is added.

With that understanding, I have a problem with the code in my fixture function. The db = db () code was thrown before request.addFinalizer (demo_finalizer), so the code that added the finalizer was not executed.

I finally figured it out, so I reordered the code to put Request. addfinalizer(demo_finalizer) first, and then attached the code for the fixture:

# content of conftest.py @pytest.fixture() def init_data_allot_task(request): query_sql = """ SELECT id FROM `sm_purchase_allot` WHERE `status`! =5 """ def demo_finalizer(): print("running finalizer code..." ) request.addfinalizer(demo_finalizer) print("running setup code..." ) db = DB() data = db.fetch_one(query_sql) db.close() return dataCopy the code

In this case, we will first see “running setup code…” You can still see “running setup code…” The output.

Run the code to verify:

There you go.