pytest adalah package pihak ketiga, dan ada situasi ketika kita tidak boleh menambahkan dependensi baru: environment server produksi yang terkunci, library yang dipakai lintas tim, atau skrip yang harus jalan dari Python standar saja. Python menjawab kebutuhan ini dengan module unittest yang terpasang di standard library sejak lama. Pada Chapter ini kita menulis test dengan gaya unittest, memakai setUp/tearDown untuk persiapan berulang, lalu membandingkan kapan unittest lebih tepat dipilih dibanding pytest.

Test Case Pertama dengan unittest #

unittest menguji kode lewat class yang mewarisi unittest.TestCase; setiap method berawalan test_ menjadi satu test. Simpan file test_kalkulator_unittest.py:

python
import unittest
from kalkulator import tambah, kurang, bagi
from keranjang import KeranjangBelanja


class TestFungsiKalkulator(unittest.TestCase):
    def test_tambah_dua_angka(self):
        self.assertEqual(tambah(2, 3), 5)

    def test_kurang_dua_angka(self):
        self.assertEqual(kurang(10, 4), 6)

    def test_bagi_menghasilkan_float(self):
        self.assertAlmostEqual(bagi(10, 4), 2.5)


class TestKeranjangBelanja(unittest.TestCase):
    def setUp(self):
        self.keranjang = KeranjangBelanja()
        self.keranjang.tambah_item("Kopi", 25000)

    def tearDown(self):
        self.keranjang.items.clear()

    def test_keranjang_berisi_satu_item(self):
        self.assertEqual(self.keranjang.jumlah_item(), 1)

    def test_total_harga_satu_item(self):
        self.assertEqual(self.keranjang.total(), 25000)


if __name__ == "__main__":
    unittest.main()

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 1 (import unittest): seluruh framework tersedia tanpa instalasi apa pun.
  2. Baris 6 (class TestFungsiKalkulator(unittest.TestCase)): class test wajib mewarisi unittest.TestCase agar runner mengenalinya.
  3. Baris 7–12 (self.assertEqual(...)): unittest tidak memakai assert polos; setiap pemeriksaan memanggil method seperti assertEqual(pengirim, harapan) dan assertAlmostEqual untuk angka pecahan.
  4. Baris 16–19 (setUp / tearDown): runner memanggil setUp() sebelum setiap method test dan tearDown() setelahnya — setiap test mendapat KeranjangBelanja yang segar berisi satu item.
  5. Baris 30 (unittest.main()): blok if __name__ == "__main__" membuat file ini juga bisa dijalankan langsung dengan python3 test_kalkulator_unittest.py.

Jalankan seluruh file lewat mode discovery:

bash
python3 -m unittest discover

Output yang Dihasilkan:

text
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK

Lima titik mewakili lima method test, dan OK menandakan semuanya lulus. Dengan flag -v, unittest menampilkan setiap nama test:

bash
python3 -m unittest discover -v

Output yang Dihasilkan:

text
test_bagi_menghasilkan_float (test_kalkulator_unittest.TestFungsiKalkulator.test_bagi_menghasilkan_float) ... ok
test_kurang_dua_angka (test_kalkulator_unittest.TestFungsiKalkulator.test_kurang_dua_angka) ... ok
test_tambah_dua_angka (test_kalkulator_unittest.TestFungsiKalkulator.test_tambah_dua_angka) ... ok
test_keranjang_berisi_satu_item (test_kalkulator_unittest.TestKeranjangBelanja.test_keranjang_berisi_satu_item) ... ok
test_total_harga_satu_item (test_kalkulator_unittest.TestKeranjangBelanja.test_total_harga_satu_item) ... ok

----------------------------------------------------------------------
Ran 5 tests in 0.001s

OK

Keluarga Method assert #

MethodMemeriksa
assertEqual(a, b)a == b
assertNotEqual(a, b)a != b
assertTrue(x) / assertFalse(x)kebenaran nilai x
assertIn(a, items)a ada di dalam items
assertIsNone(x)x is None
assertAlmostEqual(a, b)a dan b hampir sama (toleransi 7 desimal)
assertRaises(Error)blok membangkitkan exception tertentu

Daftar lengkap method ini bisa dilihat lewat python3 -c "help(unittest.TestCase)".

pytest versus unittest #

Aspekpytestunittest
Instalasipihak ketiga (pip install pytest)standard library, nol dependensi
Gaya penulisanfungsi bebas test_* dengan assert polosclass TestCase dengan method assert*
Laporan kegagalanbedah subekspresi otomatis (assert rewriting)pesan standar AssertionError
Fitur lanjutanfixtures, parametrize, plugin ekosistemterbatas pada yang disediakan stdlib
Kompatibilitasdapat menjalankan test gaya unittesttidak dapat menjalankan fixture pytest

Kapan Memilih unittest #

Gunakan unittest ketika proyek menuntut environment stdlib-only — misalnya library yang didistribusikan tanpa dependensi test tambahan, atau mesin target yang tidak boleh menjalankan pip install. Untuk seluruh situasi lain, pytest memberikan pengalaman menulis dan membaca kegagalan yang jauh lebih ringkas, dan itulah yang kita pakai untuk sisa Section ini.