☀️Siang
Python

Python Testing dengan pytest

Tutorial lengkap belajar pytest dari nol — fixtures, parametrize, markers, mocking, coverage, TDD, dan quiz interaktif dengan contoh kode praktis

Artikel: Python Testing Pytest Artikel: Python Testing Pytest


1. Pengenalan Testing

Testing adalah proses memverifikasi bahwa kode berfungsi sesuai harapan. Dalam pengembangan perangkat lunak, testing membantu menemukan bug lebih awal, memastikan kode tidak rusak setelah perubahan (regression), dan memberikan dokumentasi tentang perilaku kode.

Jenis-jenis Testing

Jenis Deskripsi Contoh
Unit TestMenguji fungsi/komponen secara individualTest fungsi hitung_total()
Integration TestMenguji interaksi antar komponenTest API + Database
Functional TestMenguji fitur dari perspektif penggunaTest login flow
End-to-End TestMenguji seluruh alur aplikasiTest checkout dari keranjang

Mengapa pytest?

Keunggulan Penjelasan
Sintaks SederhanaCukup gunakan assert, tidak perlu method khusus
Auto-discoveryOtomatis menemukan file test yang dimulai dengan test_
FixturesSistem setup/teardown yang powerful dan reusable
ParametrizeJalankan test yang sama dengan data berbeda
Rich Plugin EkosistemRibuan plugin: coverage, HTML report, parallel, dll
Backward CompatibleBisa menjalankan test dari unittest dan nose
Diagram: Testing Pyramid

Validasi UI

Validasi Modul

Jalankan kode

Feedback loop

🔺 E2E Tests (Sedikit, Lambat)

🔷 Integration Tests (Sedang)

✅ Unit Tests (Banyak, Cepat)

🏗️ Kode Aplikasi



2. Memulai dengan pytest

Instalasi

Diagram
1. RED (Gagal)
2. GREEN (Lulus)
3. REFA- CTOR

Contoh TDD: Membuat Class Keranjang Belanja

Python — Step 1: RED — Tulis test
# test_keranjang.py — Tulis test DULU (akan gagal karena class belum ada)
import pytest
from keranjang import Keranjang, Produk

class TestKeranjang:
    @pytest.fixture
    def keranjang(self):
        return Keranjang()

    @pytest.fixture
    def produk_laptop(self):
        return Produk(id=1, nama="Laptop", harga=10000000)

    @pytest.fixture
    def produk_mouse(self):
        return Produk(id=2, nama="Mouse", harga=150000)

    def test_keranjang_awalnya_kosong(self, keranjang):
        assert keranjang.jumlah_item() == 0
        assert keranjang.total() == 0

    def test_tambah_produk(self, keranjang, produk_laptop):
        keranjang.tambah(produk_laptop)
        assert keranjang.jumlah_item() == 1

    def test_tambah_produk_dengan_jumlah(self, keranjang, produk_mouse):
        keranjang.tambah(produk_mouse, jumlah=3)
        assert keranjang.jumlah_item() == 3

    def test_total_harga(self, keranjang, produk_laptop, produk_mouse):
        keranjang.tambah(produk_laptop)
        keranjang.tambah(produk_mouse, jumlah=2)
        assert keranjang.total() == 10000000 + (150000 * 2)

    def test_hapus_produk(self, keranjang, produk_laptop):
        keranjang.tambah(produk_laptop)
        keranjang.hapus(produk_laptop.id)
        assert keranjang.jumlah_item() == 0

    def test_hapus_produk_tidak_ada(self, keranjang):
        with pytest.raises(ValueError, match="Produk tidak ditemukan"):
            keranjang.hapus(999)

    def test_produk_string(self, produk_laptop):
        assert str(produk_laptop) == "Laptop (Rp 10,000,000)"
Python — Step 2: GREEN — Tulis kode
# keranjang.py — Implementasi agar test lulus
class Produk:
    def __init__(self, id, nama, harga):
        self.id = id
        self.nama = nama
        self.harga = harga

    def __str__(self):
        return f"{self.nama} (Rp {self.harga:,.0f})"

class Keranjang:
    def __init__(self):
        self._items = {}  # {produk_id: {'produk': ..., 'jumlah': ...}}

    def tambah(self, produk, jumlah=1):
        if produk.id in self._items:
            self._items[produk.id]['jumlah'] += jumlah
        else:
            self._items[produk.id] = {'produk': produk, 'jumlah': jumlah}

    def hapus(self, produk_id):
        if produk_id not in self._items:
            raise ValueError("Produk tidak ditemukan")
        del self._items[produk_id]

    def jumlah_item(self):
        return sum(item['jumlah'] for item in self._items.values())

    def total(self):
        return sum(
            item['produk'].harga * item['jumlah']
            for item in self._items.values()
        )

# Menjalankan:
# pytest test_keranjang.py -v
# Semua 7 test seharusnya PASSED ✅


9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang pytest:

Pertanyaan 1: Bagaimana cara pytest menemukan file test?

a) File yang diakhiri dengan .test.py
b) File yang dimulai dengan test_ atau diakhiri dengan _test.py
c) File yang ada di folder tests/ saja
d) File yang mengimpor pytest

Pertanyaan 2: Apa fungsi dari fixture dengan yield?

a) Mengembalikan beberapa nilai sekaligus
b) Memisahkan setup (sebelum yield) dan teardown (setelah yield)
c) Membuat fixture berjalan lebih cepat
d) Menghindari error saat test gagal

Pertanyaan 3: Apa yang dilakukan decorator @pytest.mark.parametrize?

a) Mengelompokkan test berdasarkan kategori
b) Menjalankan test yang sama dengan beberapa set data input
c) Menandai test yang diharapkan gagal
d) Menjalankan test secara paralel

Pertanyaan 4: Apa itu mocking dalam testing?

a) Menghapus test yang tidak diperlukan
b) Mengganti dependensi eksternal dengan objek palsu yang perilakunya dikontrol
c) Menulis test tanpa assert
d) Membuat test berjalan lebih lambat

Pertanyaan 5: Apa urutan siklus dalam TDD?

a) Write Code → Write Test → Refactor
b) Red → Green → Refactor
c) Design → Implement → Test
d) Plan → Code → Deploy
🔍 Zoom
100%
🎨 Tema