How to run a async http test in python using pytest aiohttp

1.7k Views Asked by At

I want to test a http call to an api that i don't own ( integration test ). I have created a class with an async function that makes a http call using aiohttp. I have then made a test case to run this function and assert the status of it.

test/test_coinbase.py:

import json
import os
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop

from src.coinbase import CoinbaseService

class CoinbaseTestCase():

    async def test_get_current_user(self):

        coinbase_service = CoinbaseService(os.getenv('COINBASE_APIURL'), os.getenv('COINBASE_APIKEY'), os.getenv('COINBASE_APISECRET'))

        status, user = await coinbase_service.show_current_user()

        assert status == 200

src/coinbase.py:

import json, hmac, hashlib, time
import aiohttp


class CoinbaseService:

    def __init__(self, API_URL, API_KEY, API_SECRET):
        self.API_URL = API_URL
        self.API_KEY = API_KEY
        self.API_SECRET = API_SECRET


    def generateHeaders(self, method, path_url, body = ''):
        timestamp = str(int(time.time()))
        message = timestamp + method + path_url + body
        signature = hmac.new(self.API_SECRET, message, hashlib.sha256).hexdigest()

        headers = {
            'CB-ACCESS-SIGN': signature,
            'CB-ACCESS-TIMESTAMP': timestamp,
            'CB-ACCESS-KEY': self.API_KEY
        }

        return headers

    async def show_current_user(self):

        path_url = 'user'

        headers = self.generateHeaders('GET', path_url)

        async with aiohttp.ClientSession() as session:
            async with session.get(path_url, headers=headers) as response:
                status = response.status
                user = await response.json()
                return status, user

When i run the following command in my root project i get the following.

platform darwin -- Python 3.7.4, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 rootdir: /Users/helloworld/Krypto plugins: aiohttp-0.3.0 collected 0 items

Packages

[packages]
aiohttp = "*"
backoff = "*"
requests = "*"
asyncio = "*"
vadersentiment = "*"
python-dateutil = "*"
pytest = "*"
pytest-aiohttp = "*"
1

There are 1 best solutions below

0
On
  1. CoinbaseTestCase doesn't match the default pytest naming rules to be considered a test class, see Conventions for Python test discovery. Either rename the class to smth like TestCoinbase, or define your own naming conventions.

  2. The vanilla pytest doesn't support running async tests. Install pytest-asyncio:

    $ pip install pytest-asyncio
    

    and mark the async tests with the asyncio marker:

    class TestCoinbase:
    
        @pytest.mark.asyncio
        async def test_get_current_user(self):
            await coinbase_service.show_current_user()
            ...