]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Add Korean translation for `docs/ko/docs/advanced/async-test.md` (#12918)
authorviva-douner <douner@adoc.co.kr>
Tue, 10 Dec 2024 11:03:16 +0000 (20:03 +0900)
committerGitHub <noreply@github.com>
Tue, 10 Dec 2024 11:03:16 +0000 (11:03 +0000)
docs/ko/docs/advanced/async-tests.md [new file with mode: 0644]

diff --git a/docs/ko/docs/advanced/async-tests.md b/docs/ko/docs/advanced/async-tests.md
new file mode 100644 (file)
index 0000000..37dfe29
--- /dev/null
@@ -0,0 +1,108 @@
+# λΉ„동기 ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±
+
+이전 μž₯μ—μ„œ  `TestClient` λ₯Ό μ΄μš©ν•΄ **FastAPI** μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•˜λŠ” λ²•을 λ°°μš°μ…¨μ„ν…λ°μš”.
+μ§€κΈˆκΉŒμ§€λŠ” `async` ν‚€μ›Œλ“œ μ‚¬μš©μ—†μ΄ λ™κΈ° ν•¨μˆ˜μ˜ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” λ²•λ§Œ μ΅ν˜”μŠ΅λ‹ˆλ‹€.
+
+ν•˜μ§€λ§Œ λΉ„동기 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” κ²ƒμ€ λ§€μš° μœ μš©ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+예λ₯Ό λ“€λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ— λΉ„λ™κΈ°λ‘œ μΏΌλ¦¬ν•˜λŠ” κ²½μš°λ₯Ό μƒκ°ν•΄λ΄…μ‹œλ‹€.
+FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μš”청을 λ³΄λ‚΄κ³ , λΉ„동기 λ°μ΄ν„°λ² μ΄μŠ€ λΌμ΄λΈŒλŸ¬λ¦¬λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°±μ—”λ“œκ°€ λ°μ΄ν„°λ² μ΄μŠ€μ— μ˜¬λ°”λ₯΄κ²Œ λ°μ΄ν„°λ₯Ό κΈ°λ‘ν–ˆλŠ”μ§€ ν™•μΈν•˜κ³  μ‹Άμ„ λ•Œκ°€ μžˆμ„ κ²λ‹ˆλ‹€.
+
+이런 κ²½μš°μ˜ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ–΄λ–»κ²Œ λΉ„λ™κΈ°λ‘œ μž‘μ„±ν•˜λŠ”μ§€ μ•Œμ•„λ΄…μ‹œλ‹€.
+
+## pytest.mark.anyio
+
+μ•žμ—μ„œ μž‘μ„±ν•œ ν…ŒμŠ€νŠΈ ν•¨μˆ˜μ—μ„œ λΉ„동기 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  μ‹Άλ‹€λ©΄, ν…ŒμŠ€νŠΈ μ½”λ“œλ„ λΉ„동기 ν•¨μˆ˜μ—¬μ•Όν•©λ‹ˆλ‹€.
+AnyIOλŠ” νŠΉμ • ν…ŒμŠ€νŠΈ ν•¨μˆ˜λ₯Ό λΉ„동기 ν•¨μˆ˜λ‘œ ν˜ΈμΆœ ν•  μˆ˜ μžˆλŠ” κΉ”λ”ν•œ ν”ŒλŸ¬κ·ΈμΈμ„ μ œκ³΅ν•©λ‹ˆλ‹€.
+
+
+## HTTPX
+
+**FastAPI** μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄  `async def` λŒ€μ‹  `def` ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ”라도, λ‚΄λΆ€μ μœΌλ‘œλŠ” μ—¬μ „νžˆ `비동기` μ• ν”Œλ¦¬μΌ€μ΄μ…˜μž…λ‹ˆλ‹€.
+
+`TestClient`λŠ” pytest ν‘œμ€€μ„ μ‚¬μš©ν•˜μ—¬ λΉ„동기 FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μΌλ°˜μ μΈ `def` ν…ŒμŠ€νŠΈ ν•¨μˆ˜ λ‚΄μ—μ„œ ν˜ΈμΆœν•  μˆ˜ μžˆλ„둝 λ‚΄λΆ€μ—μ„œ λ§ˆμˆ μ„ λΆ€λ¦½λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄ λ§ˆμˆ μ€ λΉ„동기 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  λ•ŒλŠ” λ” μ΄μƒ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν…ŒμŠ€νŠΈλ₯Ό λΉ„λ™κΈ°λ‘œ μ‹€ν–‰ν•˜λ©΄, λ” μ΄μƒ ν…ŒμŠ€νŠΈ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ `TestClient`λ₯Ό μ‚¬μš©ν•  μˆ˜ μ—†μŠ΅λ‹ˆλ‹€.
+
+`TestClient`λŠ” <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>λ₯Ό κΈ°λ°˜μœΌλ‘œ ν•˜κ³  μžˆμœΌλ©°, λ‹€ν–‰νžˆ μ΄λ₯Ό μ§μ ‘ μ‚¬μš©ν•˜μ—¬ APIλ₯Ό ν…ŒμŠ€νŠΈν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+## μ˜ˆμ‹œ
+
+κ°„λ‹¨ν•œ μ˜ˆμ‹œλ₯Ό μœ„ν•΄ [더 ν° μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ λ§Œλ“€κΈ°](../ko/tutorial/bigger-applications.md){.internal-link target=_blank} μ™€ [ν…ŒμŠ€νŠΈ](../ko/tutorial/testing.md){.internal-link target=_blank}:μ—μ„œ λ‹€λ£¬ νŒŒμΌ κ΅¬μ‘°μ™€ λΉ„μŠ·ν•œ ν˜•νƒœλ₯Ό ν™•μΈν•΄λ΄…μ‹œλ‹€:
+
+```
+.
+β”œβ”€β”€ app
+β”‚Β Β  β”œβ”€β”€ __init__.py
+β”‚Β Β  β”œβ”€β”€ main.py
+β”‚Β Β  β””── test_main.py
+```
+
+ `main.py`λŠ” μ•„λž˜μ™€ κ°™μ•„μ•Ό ν•©λ‹ˆλ‹€:
+
+{* ../../docs_src/async_tests/main.py *}
+
+`test_main.py` νŒŒμΌμ€ `main.py`에 λŒ€ν•œ ν…ŒμŠ€νŠΈκ°€ μžˆμ„ ν…λ°, λ‹€μŒκ³Ό κ°™μ„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€:
+
+{* ../../docs_src/async_tests/test_main.py *}
+
+## μ‹€ν–‰ν•˜κΈ°
+
+μ•„λž˜μ˜ λͺ…λ Ήμ–΄λ‘œ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:
+
+<div class="termy">
+
+```console
+$ pytest
+
+---> 100%
+```
+
+</div>
+
+## μžμ„Ένžˆ λ³΄κΈ°
+
+`@pytest.mark.anyio` λ§ˆμ»€λŠ” pytestμ—κ²Œ μ΄ ν…ŒμŠ€νŠΈ ν•¨μˆ˜κ°€ λΉ„λ™κΈ°λ‘œ ν˜ΈμΆœλ˜μ–΄μ•Ό ν•¨μ„ μ•Œλ €μ€λ‹ˆλ‹€:
+
+{* ../../docs_src/async_tests/test_main.py hl[7] *}
+
+/// tip | νŒ
+
+ν…ŒμŠ€νŠΈ ν•¨μˆ˜κ°€ μ΄μ œ `TestClient`λ₯Ό μ‚¬μš©ν•  λ•Œμ²˜λŸΌ λ‹¨μˆœνžˆ `def`κ°€ μ•„λ‹ˆλΌ `async def`둜 μž‘μ„±λœ μ μ— μ£Όλͺ©ν•΄μ£Όμ„Έμš”.
+
+///
+
+κ·Έ λ‹€μŒμ—  `AsyncClient` λ‘œ μ•±μ„ λ§Œλ“€κ³  λΉ„동기 μš”청을 `await` ν‚€μ›Œλ“œλ‘œ λ³΄λ‚Ό μˆ˜ μžˆμŠ΅λ‹ˆλ‹€:
+
+{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+
+μœ„μ˜ μ½”λ“œλŠ”:
+
+```Python
+response = client.get('/')
+```
+
+`TestClient` μ— μš”청을 λ³΄λ‚΄λ˜ κ²ƒκ³Ό λ™μΌν•©λ‹ˆλ‹€.
+
+/// tip | νŒ
+
+μƒˆλ‘œμš΄ `AsyncClient`λ₯Ό μ‚¬μš©ν•  λ•Œ async/awaitλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλ‹€λŠ” μ μ— μ£Όλͺ©ν•˜μ„Έμš”. μ΄ μš”청은 λΉ„λ™κΈ°μ μœΌλ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€.
+
+///
+
+/// warning | κ²½κ³ 
+
+λ§Œμ•½μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ Lifespan μ΄λ²€νŠΈμ— μ˜μ‘΄μ„±μ„ κ°–κ³  μžˆλ‹€λ©΄ `AsyncClient` κ°€ μ΄λŸ¬ν•œ μ΄λ²€νŠΈλ₯Ό μ‹€ν–‰μ‹œν‚€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
+`AsyncClient` κ°€ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰μ‹œμΌ°λ‹€λŠ” κ²ƒμ„ ν™•μΈν•˜κΈ° μœ„ν•΄
+`LifespanManager` from <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a>.ν™•μΈν•΄μ£Όμ„Έμš”.
+
+
+///
+
+## κ·Έ μ™Έμ˜ λΉ„동기 ν•¨μˆ˜ ν˜ΈμΆœ
+
+ν…ŒμŠ€νŠΈ ν•¨μˆ˜κ°€ μ΄μ œ λΉ„동기 ν•¨μˆ˜μ΄λ―€λ‘œ, FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μš”청을 λ³΄λ‚΄λŠ” κ²ƒ μ™Έμ—λ„ λ‹€λ₯Έ `async` ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  `await` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš© ν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.
+
+/// tip | νŒ
+
+ν…ŒμŠ€νŠΈμ— λΉ„동기 ν•¨μˆ˜ ν˜ΈμΆœμ„ ν†΅ν•©ν•  λ•Œ (예: <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB의 MotorClient</a>λ₯Ό μ‚¬μš©ν•  λ•Œ) `RuntimeError: Task attached to a different loop` μ˜€λ₯˜κ°€ λ°œμƒν•œλ‹€λ©΄, μ΄λ²€νŠΈ λ£¨ν”„κ°€ ν•„μš”ν•œ κ°μ²΄λŠ” λ°˜λ“œμ‹œ λΉ„동기 ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μΈμŠ€ν„΄μŠ€ν™”ν•΄μ•Ό ν•œλ‹€λŠ” μ μ„ μ£Όμ˜ν•˜μ„Έμš”!
+예λ₯Ό λ“€μ–΄ `@app.on_event("startup")` μ½œλ°± λ‚΄μ—μ„œ μΈμŠ€ν„΄μŠ€ν™”ν•˜λŠ” κ²ƒμ΄ μ’‹μŠ΅λ‹ˆλ‹€.
+
+///