Notes & software courses · Free to learn
Aph's Blog
On this page

Fixture & Parametrize

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

เตรียมข้อมูลซ้ำ ๆ ด้วย fixture และทดสอบหลายชุดข้อมูลด้วยโค้ดเดียวด้วย parametrize

เมื่อเทสต์หลายตัวต้องการข้อมูลเตรียมเหมือนกัน หรืออยากทดสอบฟังก์ชันเดียวด้วยหลายชุด input pytest มีเครื่องมือ fixture และ parametrize ที่ลดโค้ดซ้ำได้มาก

fixture — เตรียมของให้เทสต์

fixture คือฟังก์ชันที่เตรียมข้อมูล/สถานะให้เทสต์ใช้ร่วมกัน เทสต์ไหนต้องการก็รับชื่อ fixture เป็นพารามิเตอร์ pytest จะเรียกให้เอง

python
import pytest

@pytest.fixture
def sample_users():
    return [
        {"name": "Aph", "age": 25},
        {"name": "Bee", "age": 30},
    ]

def test_count(sample_users):       # รับชื่อ fixture
    assert len(sample_users) == 2

def test_first_name(sample_users):  # ใช้ข้อมูลชุดเดียวกัน
    assert sample_users[0]["name"] == "Aph"

parametrize — เทสต์หลายเคสด้วยโค้ดเดียว

แทนที่จะเขียนเทสต์ซ้ำหลายตัวสำหรับหลาย input ใช้ parametrize ใส่ชุด (input, expected) แล้ว pytest รันให้ครบทุกชุด

python
import pytest

def is_even(n):
    return n % 2 == 0

@pytest.mark.parametrize("number, expected", [
    (2, True),
    (3, False),
    (0, True),
    (-4, True),
    (7, False),
])
def test_is_even(number, expected):
    assert is_even(number) == expected
# รัน 5 เคส จากเทสต์เดียว

pytest.raises — ทดสอบว่า raise error

บางครั้งพฤติกรรมที่ถูกต้องคือ "ต้อง raise exception" ใช้ pytest.raises ตรวจว่าโค้ด raise ตามคาด

python
import pytest

def divide(a, b):
    return a / b

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(10, 0)        # ถ้าไม่ raise = เทสต์พัง
parametrize ลดโค้ดมหาศาล

แทนการ copy-paste เทสต์ 5 ตัวที่ต่างกันแค่ตัวเลข ใช้ parametrize เขียนครั้งเดียวรันหลายชุด — เพิ่มเคสใหม่แค่เติมบรรทัดใน list อ่านง่ายและครอบคลุมกว่า

สรุปหัวข้อนี้

  • fixture เตรียมข้อมูล/สถานะให้เทสต์ใช้ร่วม — รับเป็นพารามิเตอร์
  • parametrize รันเทสต์เดียวด้วยหลายชุด (input, expected)
  • pytest.raises ตรวจว่าโค้ด raise exception ตามคาด
  • ทั้งหมดช่วยลดโค้ดซ้ำและครอบคลุมเคสมากขึ้น
แบบฝึกหัด

1) เขียน fixture เตรียม list ข้อมูลแล้วใช้ใน 2 เทสต์ 2) ใช้ parametrize ทดสอบฟังก์ชันด้วย 5 ชุด input/output 3) เขียนเทสต์ที่ตรวจว่าฟังก์ชัน raise ValueError ด้วย pytest.raises 4) เพิ่มเคสใหม่ใน parametrize แล้วรันดู