typed-pytest: ทวงคืน IDE autocomplete และความปลอดภัยของชนิดข้อมูลที่หายไปจาก MagicMock
(github.com/tmdgusya)ระหว่างเขียนโค้ดทดสอบด้วย Pytest แล้วใช้ MagicMock หลายคนน่าจะเคยเจอประสบการณ์ที่ IDE ไม่ช่วย autocomplete หรือพิมพ์ชื่อเมธอดผิดแล้วต้องเสียเวลางมหาสาเหตุกันมาบ้าง
mock แบบเดิมนั้นทรงพลังมาก แต่ type hint จะหายไป ทำให้ยากที่จะอาศัยตัวตรวจสอบชนิดข้อมูลอย่าง mypy หรือ pyright มาช่วยได้ เพื่อแก้ปัญหานี้จึงได้สร้าง typed-pytest ที่รองรับ การทำ mock แบบปลอดภัยต่อชนิดข้อมูล (Type-safe mocking) ขึ้นมา
คุณสมบัติหลัก:
- IDE autocomplete แบบครบถ้วน: รองรับการเติมชื่อเมธอดและพารามิเตอร์ของคลาสจริง รวมถึงเมธอดเฉพาะของ mock อย่าง
assert_called_once_withด้วย - ตรวจจับการพิมพ์ผิดตอน lint: หากเรียกเมธอดที่ไม่มีอยู่จริงหรือส่งอาร์กิวเมนต์ผิด ก็จะตรวจพบได้ทันทีตั้งแต่ก่อนรันเทสต์ (mypy/pyright)
- ตัวสร้างสตับ (Stub) โดยเฉพาะ: วิเคราะห์คลาสในโปรเจกต์แล้วสร้างไฟล์ type hint (
.pyi) ให้อัตโนมัติ (รองรับคลาสที่มี dependency ภายนอกอย่าง FastAPI, SQLAlchemy เป็นต้น) - แบ็กเอนด์ที่ยืดหยุ่น: ถ้าต้องการความเร็วสามารถใช้ inspect ได้ และถ้าต้องการ type hint ของค่าที่คืนมาอย่างละเอียดกว่าสามารถเลือกแบ็กเอนด์ stubgen ได้ (ปัจจุบัน stubgen ยังอยู่ในขั้นทดลอง)
ตัวอย่างการใช้งาน:
# MagicMock แบบเดิม: แม้พิมพ์ผิดก็ยังไม่รู้ก่อนรัน
mock = MagicMock(spec=UserService)
mock.get_usr(1) # พิมพ์ get_user ผิด แต่ linter ตรวจไม่พบ
# typed-pytest: linter แจ้ง error ทันที และรองรับ autocomplete
from typed_pytest_stubs import typed_mock, UserService
mock = typed_mock(UserService)
mock.get_usr # ❌ Error: "get_usr" is not a member of UserService
mock.get_user.assert_called_once_with(user_id=1) # ✅ ผ่านการตรวจสอบชนิดข้อมูลแล้ว
ไฟล์สตับที่สร้างขึ้นถูกออกแบบมาให้ใช้งานโดยสร้างเฉพาะในสภาพแวดล้อมพัฒนาแบบโลคัลและใน CI โดยไม่จำเป็นต้องอัปขึ้น Git และยังคำนึงถึงความเข้ากันได้กับเครื่องมือสมัยใหม่อย่าง uv ด้วย
GitHub: https://github.com/tmdgusya/typed-pytest
หวังว่าจะเป็นประโยชน์สำหรับคนที่อยากใช้ข้อดีของระบบชนิดข้อมูลได้อย่างเต็มที่แม้ในโค้ดทดสอบ และยินดีรับฟีดแบ็กเพื่อปรับปรุงการใช้งานเสมอ!!
ยังไม่มีความคิดเห็น