Unit Testing Python
Unit Testing adalah metode pengujian perangkat lunak di mana unit-unit individu dari kode sumber (seperti fungsi, metode, atau class) diuji untuk menentukan apakah mereka berfungsi dengan benar.
"Tapi kode saya sudah jalan!" Mungkin jalan sekarang, tapi bagaimana jika 6 bulan lagi Anda mengubah satu baris kode dan merusak fitur lainnya? Unit test adalah jaring pengaman Anda.
Di Python, ada dua framework testing utama: unittest (bawaan) dan pytest (pihak ketiga, tapi sangat populer).
1. Menggunakan unittest (Bawaan)
unittest terinspirasi dari JUnit (Java). Ia menggunakan pendekatan berbasis Class.
Misalkan kita punya fungsi sederhana:
# hitung.py
def tambah(x, y):
return x + y
def bagi(x, y):
if y == 0:
raise ValueError("Tidak bisa bagi nol")
return x / y
Kita buat file test-nya:
# test_hitung.py
import unittest
from hitung import tambah, bagi
class TestHitung(unittest.TestCase):
def test_tambah(self):
self.assertEqual(tambah(3, 4), 7)
self.assertEqual(tambah(-1, 1), 0)
def test_bagi(self):
self.assertEqual(bagi(10, 2), 5)
# Test exception
with self.assertRaises(ValueError):
bagi(10, 0)
if __name__ == '__main__':
unittest.main()
Jalankan dengan: python test_hitung.py
2. Menggunakan pytest (Rekomendasi Modern)
pytest jauh lebih ringkas, powerful, dan "Pythonic". Ia menggunakan fungsi biasa (bukan class) dan keyword assert standar.
Instalasi:
pip install pytest
Menulis test dengan pytest:
# test_hitung_pytest.py
import pytest
from hitung import tambah, bagi
def test_tambah():
assert tambah(3, 4) == 7
assert tambah(-1, 1) == 0
def test_bagi():
assert bagi(10, 2) == 5
def test_bagi_nol():
with pytest.raises(ValueError):
bagi(10, 0)
Jalankan dengan cukup mengetik: pytest di terminal. Pytest akan otomatis mencari file yang diawali test_.
3. Konsep Mocking
Mocking adalah teknik mengganti bagian dari sistem yang sedang diuji dengan objek tiruan (mock objects). Ini berguna ketika kode Anda bergantung pada sistem luar seperti API, Database, atau File System.
Contoh: Kita ingin menguji fungsi yang melakukan request API, tapi kita tidak ingin benar-benar melakukan request (karena lama dan butuh internet).
Menggunakan unittest.mock:
from unittest.mock import Mock, patch
import requests
# Fungsi yang mau diuji
def ambil_data_user(url):
resp = requests.get(url)
if resp.status_code == 200:
return resp.json()
return None
# Test dengan Mock
@patch('requests.get')
def test_ambil_data_user(mock_get):
# Setup mock
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {"id": 1, "name": "Budi"}
# Masukkan mock response ke mock_get
mock_get.return_value = mock_response
# Jalankan fungsi
hasil = ambil_data_user("http://fakeurl.com")
# Assert
assert hasil["name"] == "Budi"
# Pastikan requests.get benar-benar dipanggil dengan URL yang benar
mock_get.assert_called_with("http://fakeurl.com")
4. Code Coverage
Seberapa banyak kode Anda yang sudah dites? Coverage tool bisa memberitahu Anda baris mana yang belum tersentuh oleh test.
Install:
pip install pytest-cov
Jalankan:
pytest --cov=my_project
Kesimpulan
- Unit Test wajib untuk aplikasi serius.
- pytest lebih disukai karena sintaksnya yang bersih.
- Mocking digunakan untuk mengisolasi unit dari dependensi eksternal.
- Biasakan menulis test sebelum kode (TDD - Test Driven Development) atau minimal bersamaan dengan kode.