[파이썬] pytest 비동기 코드 테스팅

Testing asynchronous code can be challenging, as traditional testing frameworks may not handle it effectively. Fortunately, pytest, a popular testing framework in Python, provides excellent support for testing asynchronous code. In this blog post, we will explore how to use pytest to test asynchronous code in Python.

Installing pytest

Before we get started, let’s make sure pytest is installed in your Python environment. You can install pytest using pip:

pip install pytest

Writing Asynchronous Test Cases

To write test cases for asynchronous code using pytest, we can make use of asyncio library and pytest-asyncio plugin. The asyncio library provides the necessary functionality to work with asynchronous code, while pytest-asyncio plugin extends pytest to handle asynchronous tests.

Let’s consider an example where we have an asynchronous function called fetch_data(), which fetches some data from an external API. Our goal is to test this function using pytest.

import asyncio
import pytest

async def fetch_data():
    # Simulate an asynchronous task
    await asyncio.sleep(5)
    return "Data fetched successfully"

@pytest.mark.asyncio
async def test_fetch_data():
    result = await fetch_data()
    assert result == "Data fetched successfully"

In the above code, we define an async function fetch_data(), which uses asyncio.sleep() to introduce a delay of 5 seconds. Then, we define a test case function test_fetch_data() and decorate it with @pytest.mark.asyncio to indicate that it is an asynchronous test case. Inside the test case function, we await the fetch_data() function and assert the result.

Running Asynchronous Tests

To run the asynchronous test cases, we simply need to execute the pytest command in the terminal:

pytest

By default, pytest will discover and run all the test cases in the current directory and its subdirectories. It will automatically recognize the asynchronous test cases decorated with @pytest.mark.asyncio and execute them properly.

Handling Asynchronous Exceptions

Sometimes, our asynchronous code may raise exceptions that need to be handled in our test cases. pytest provides a convenient way to handle exceptions in asynchronous code using the pytest.raises() context manager.

Let’s modify our previous example to handle exceptions:

import asyncio
import pytest

async def fetch_data():
    await asyncio.sleep(5)
    raise ValueError("Error occurred while fetching data")

@pytest.mark.asyncio
async def test_fetch_data_exception_handling():
    with pytest.raises(ValueError):
        await fetch_data()

In this modified code, we intentionally raise a ValueError inside the fetch_data() function. In the test case function, we use pytest.raises() to assert that the exception is raised.

Conclusion

In this blog post, we explored how to test asynchronous code using pytest in Python. We learned how to write asynchronous test cases, run them using pytest, and handle exceptions in asynchronous code. With pytest and the pytest-asyncio plugin, testing asynchronous code becomes intuitive and efficient.

Happy testing with pytest!