Testing subscriptions using graphene.test in Python Graphene

Question:

What is the idiomatic approach for testing subscriptions in graphene-python? It seems that the client.execute option in graphene.test is only appropriate for Query testing.

P.S. There is a subscription execution example in the documentation but it does not seem to be part of the testing library (https://docs.graphene-python.org/en/latest/execution/subscriptions/).

Asked By: Peteris

||

Answers:

The pre-release version of graphene (3) supports subscriptions in this way:

import asyncio
from datetime import datetime
from graphene import ObjectType, String, Schema, Field

class Query(ObjectType):
    hello = String()

    def resolve_hello(root, info):
        return 'Hello, world!'

class Subscription(ObjectType):
    time_of_day = Field(String)

    async def resolve_time_of_day(root, info):
        while True:
            yield datetime.now().isoformat()
            await asyncio.sleep(1)

schema = Schema(query=Query, subscription=Subscription)

async def main():
    subscription = 'subscription { timeOfDay }'
    result = await schema.execute_async(subscription)
    async for item in result:
        print(item)

asyncio.run(main())

Source: https://github.com/graphql-python/graphene/issues/1099.

Answered By: Peteris

This is how you do it in 2022 with Graphene 3:

pip install pytest pytest-asyncio

import pytest
from main.schema import schema

@pytest.mark.asyncio
async def test_realtime_updates():
    q = 'subscription { count }'
    result = await schema.subscribe(q)
    
    async for item in result:
        print(item)

    pytest.fail(pytrace=False)

If you don’t have any app, here’s a minimal example with subscriptions:

pip install graphene graphene_starlette3

# Graphene Subscriptions demo

import graphene
from graphene import ResolveInfo
from starlette_graphene3 import GraphQLApp, make_playground_handler


class Query(graphene.ObjectType):
    hello = graphene.String()

class Subscription(graphene.ObjectType):
    count = graphene.Float()

    async def subscribe_count(_, info: ResolveInfo):
        for i in range(10):
            yield i


# GraphQL Schema
schema = graphene.Schema(
    query=Query,
    subscription=Subscription,
)


# ASGI application
# You'll probably want to mount it to a Starlette application
app = GraphQLApp(
    schema=schema,
    on_get=make_playground_handler(),
)

Run it:

$ uvicorn run main:app --reload
Answered By: kolypto
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.