рд╕реБрдЭрд╛рдП рдЧрдП рдкрд░реАрдХреНрд╖рдг рдкреИрдЯрд░реНрди рдХреЗ рд▓рд┐рдП рдРрдк рдХреЛрдб рдХреЗ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рджреЛрд╣рд░рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рдпрд╣ рд╕реАрдзреЗ рдРрдк рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИред
https://docs.aiohttp.org/hi/stable/testing.html#pytest
рдореИрдВ рдЕрдкрдиреЗ рдРрдк рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдРрдк рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реАрдзреЗ test_client
рдкрд░ рдкрд╛рд╕ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ рдлреНрд▓рд╛рдИ рдкрд░ рд╣реИрдВрдбрд▓рд░ рд╕реЗ рдРрдк рдмрдирд╛рдирд╛ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВред рдЕрд╕рд▓реА app
рд╕реАрдзреЗ test_client
рдХрд░рдирд╛ рдкрд╣рд▓реА рдмрд╛рд░ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ "рд░рдирдЯрд╛рдЗрдо рдПрд░рд░: рд╡реЗрдмред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдЕрд▓рдЧ рд▓реВрдк рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░рдВрдн" рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред
# handler.py
async def foo():
return 'foo'
# app.py
from aiohttp import web
from .handler import foo
app = web.Application()
app.add_routes([web.get('/foo/', foo)])
# test.py
from .app import app
async def test_foo_status(test_client):
response = await client.get('/foo/')
assert response.status == 200
async def test_foo_body(test_client):
response = await client.get('/foo/')
body = await response.text()
assert body == 'foo'
рдореИрдВрдиреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рджреЗрдЦрдХрд░ рдФрд░ рддреНрд░реБрдЯрд┐ рдХрд╛ рдХрд╛рд░рдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдХреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЕрднреА рдХреЗ рд▓рд┐рдП рд╣реИрдХ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред
if self._loop is not None and self._loop is not loop:
raise RuntimeError(
"web.Application instance initialized with different loop")
https://github.com/aio-libs/aiohttp/blob/e561eaa/aiohttp/web_app.py#L134
рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рддреБрд░рдВрдд рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореБрдЭреЗ рдЧрд┐рдЯ рдЗрддрд┐рд╣рд╛рд╕ рдореЗрдВ рдХреЛрдИ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдореЗрд░реА рдЯреЗрд╕реНрдЯ рдХреНрд▓реАрдирдЕрдк рд╡рд┐рдзрд┐ рдореЗрдВ app._loop = None
рд╕реЗрдЯ рдХрд░рдирд╛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдирдХрд╛рд░рд╛рддреНрдордХ рджреБрд╖реНрдкреНрд░рднрд╛рд╡ рдХреЗ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдмрдЪрдиреЗ рд▓рдЧрддрд╛ рд╣реИред рдХреНрдпрд╛ рдпрд╣ рдХреЛрдб рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ? рдХреНрдпрд╛ рдЗрд╕ рд╕реБрдзрд╛рд░ рдХреЛ test_client
рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?
Application
рдПрдХ рд╕реНрдЯреЗрдЯрдлреБрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рдЗрд╕реЗ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рд╕реВрдЯ рд╕реЗ рд╣рд░ рдЯреЗрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдЬреАрд╡рдирдХрд╛рд▓ рдИрд╡реЗрдВрдЯ рд▓реВрдк рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рд╕реЗ рдЫреЛрдЯрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдВрдХреЗрдд: app.app
рдХреЛ async def app.make_app()
coroutine рд╕реЗ рдмрджрд▓реЗрдВ рдЬреЛ рд╣рд░ рдХреЙрд▓ рдкрд░ рдПрдХ рдирдпрд╛ рдРрдк рджреЗрддрд╛ рд╣реИред
def make_app()
рдХреЛ app.py
? рдпрд╣ рд╕рдордЭ рдЖрддрд╛ рд╣реИред
FWIW рдмрд╡рдВрдбрд░ рдЕрдкрдиреЗ рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ make_app()
рдкреИрдЯрд░реНрди рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрддрд╛ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдРрдк рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛рдирд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреИрдЯрд░реНрди рд╣реИред
рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдХрд┐рд╕реА рднреА aiohttp
рд╡рд╕реНрддреБ рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛рдирд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреИрдЯрд░реНрди рд╣реИ
рдЗрд╕ рдереНрд░реЗрдб рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд▓реЙрдХ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реБрдИ рд╣реИред рдХреГрдкрдпрд╛ рд╕рдВрдмрдВрдзрд┐рдд рдмрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ [рдирдпрд╛ рдореБрджреНрджрд╛] рдЦреЛрд▓реЗрдВред
рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдЪрд░реНрдЪрд╛ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдЙрди рдЕрдВрд╢реЛрдВ рдХреЛ рдЙрд╕ [рдирдП рдЕрдВрдХ] рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
Application
рдПрдХ рд╕реНрдЯреЗрдЯрдлреБрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рдЗрд╕реЗ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рд╕реВрдЯ рд╕реЗ рд╣рд░ рдЯреЗрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПредрдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдЬреАрд╡рдирдХрд╛рд▓ рдИрд╡реЗрдВрдЯ рд▓реВрдк рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рд╕реЗ рдЫреЛрдЯрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдВрдХреЗрдд:
app.app
рдХреЛasync def app.make_app()
coroutine рд╕реЗ рдмрджрд▓реЗрдВ рдЬреЛ рд╣рд░ рдХреЙрд▓ рдкрд░ рдПрдХ рдирдпрд╛ рдРрдк рджреЗрддрд╛ рд╣реИред