Setelah mempelajari tentang packaging dan distribusi pada seri belajar Python Part 9, kini saatnya kita akan memahami bagaimana kualitas dari kode Python yang kita buat melalui testing dan debugging.
Testing dan debugging adalah dua hal yang berbeda namun saling melengkapi. Dengan menguasai dua skill ini akan dapat mendukung Anda mengembangkan aplikasi Python secara profesional dan bebas dari bug.
Apa itu testing dalam Python?
Testing atau pengujian merupakan proses dengan menjalankan kode tertentu untuk memastikan bahwa output yang dihasilkan sesuai dengan yang diharapkan. Testing akan membantu kita dalam mendeteksi bug sebelum aplikasi masuk ke tahap production.
Manfaat Testing
Manfaat dari melakukan testing pada aplikasi Python sebagai berikut.
- Membantu menemukan error sebelum aplikasi digunakan oleh user.
- Memastikan fungsional script berjalan dengan baik.
- Membantu pembuatan dokumentasi aplikasi seperti pada test case.
- Menghemat waktu debugging setelah masa production.
Jenis-jenis Testing
Dalam pengembangan aplikasi Python, dapat menggunakan testing sebagai berikut:
- Unit Testing: Unit testing merupakan pengujian yang menguji dari unit terkecil dari kode, yaitu seperti function ataumethod secara terpisah.
- Integration Testing: Integration testing adalah pengujian interaksi antar modul atau komponen pada aplikasi agar memastikan semua dapat berjalan bersamaan dengan baik.
- Functional Testing: Function testing adalah pengujian dari semua fungsionalitas pada aplikasi dari perspektif user.
- End to End Testing: End to end testing merupakan tahap menguji alur kerja aplikasi lengkap dari awal sampai akhir.
Module Unit testing Python
Python menyediakan built-in module yang bernama unittest, dengan module ini disediakan framework untuk membuat dan menjalankan testing. Berikut contoh sederhana file dengan function dan unittest yang dapat digunakan.
calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("Tidak bisa membagi dengan nol")
return a / b
Test_calculator.py
import unittest
from calculator import add, subtract, multiply, divide
class TestCalculator(unittest.TestCase):
def test_add(self):
self.assertEqual(add(3, 5), 8)
self.assertEqual(add(-1, 1), 0)
self.assertEqual(add(0, 0), 0)
def test_subtract(self):
self.assertEqual(subtract(10, 5), 5)
self.assertEqual(subtract(5, 10), -5)
def test_multiply(self):
self.assertEqual(multiply(3, 4), 12)
self.assertEqual(multiply(-2, 5), -10)
def test_divide(self):
self.assertEqual(divide(10, 2), 5)
self.assertEqual(divide(9, 3), 3)
# Test untuk pembagian dengan nol (exception)
with self.assertRaises(ValueError):
divide(10, 0)
if __name__ == '__main__':
unittest.main()
Untuk menjalankan test, jalankan command berikut di terminal:
python test_calculator.pyAtau menggunakan test discovery:
python -m unittest discoverOutput yang akan muncul:
....----------------------------------------------------------------------Ran 4 tests in 0.001sOKAssert Methods Unittest
Pada testing dengan unittest terdapat asert methods untuk melakukan verifikasi. Sederhananya, asert methods akan menjadi “hakim” yang akan menentukan jika kondisi yang diperiksa benar, maka test akan lolos (Pass), sedangkan jika salah maka akan memicu kegagalan(Fail) dan akan diinformasikan letak kesalahannya.
Berikut adalah fungsi-fungsi verifikasi yang paling sering digunakan dalam pengujian kode:
- assertEqual(a, b) : Digunakan untuk memverifikasi bahwa nilai a sama dengan nilai b. Ini adalah metode yang paling sering digunakan untuk mengecek hasil perhitungan atau output fungsi.
- assertNotEqual(a, b) : Digunakan untuk memverifikasi bahwa nilai a tidak sama dengan nilai b. Berguna jika Anda ingin memastikan hasil tidak menghasilkan nilai yang dilarang.
- assertTrue(x) : Digunakan untuk memverifikasi bahwa ekspresi atau variabel x bernilai True. Cocok untuk mengecek kondisi logika atau status keberhasilan.
- assertFalse(x) : Digunakan untuk memverifikasi bahwa ekspresi atau variabel x bernilai False. Sering digunakan untuk memastikan suatu fitur tidak aktif atau proses gagal sebagaimana mestinya.
- assertIsNone(x) : Digunakan untuk memverifikasi bahwa variabel x secara spesifik adalah None. Penting untuk mengecek fungsi yang seharusnya tidak mengembalikan data dalam kondisi tertentu.
- assertIn(a, b) : Digunakan untuk memverifikasi bahwa elemen a terdapat di dalam koleksi b (seperti list, tuple, set, atau string).
- assertRaises(exc) : Digunakan untuk memverifikasi bahwa suatu potongan kode menghasilkan exception (error) tertentu. Metode ini memastikan bahwa penanganan error (error handling) pada aplikasi Anda berfungsi dengan benar.
Testing dengan pytest
Selain unittest, Anda dapat menggunakan pytest. Metode ini merupakan testing framework yang populer di komunitas Python. Berikut terkait cara penggunaan pytest.
Instalasi pytest
pip install pytesttest_calculator_pytest.py
import pytest
from calculator import add, subtract, multiply, divide
def test_add():
assert add(3, 5) == 8
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_subtract():
assert subtract(10, 5) == 5
assert subtract(5, 10) == -5
def test_multiply():
assert multiply(3, 4) == 12
assert multiply(-2, 5) == -10
def test_divide():
assert divide(10, 2) == 5
assert divide(9, 3) == 3
# Test untuk exception menggunakan pytest.raises
with pytest.raises(ValueError, match="Tidak bisa membagi dengan nol"):
divide(10, 0)Menjalankan pytest:
pytest test_calculator_pytest.pyApa Itu Debugging dalam Python?
Debugging merupakan proses menemukan dan memperbaiki error atau bug yang ada dalam kode atau script. Bentuk bug bisa bermacam-macam, seperti logic error, syntax error, atau runtime error. Pada python terdapat beberapa tools yang dapat membantu proses debugging yang dapat digunakan, diantaranya berikut.
Print Debugging
Teknik debugging menggunakan print debuggung merupakan teknik sederhana menggunakan print() untuk dapat melihat nilai variabel di program yang dibuat. Berikut contoh fungsi yang dapat dibuat.
def hitung_rata_rata(numbers):
# Debug print: Mengecek input yang masuk
print(f"DEBUG - Input: {numbers}")
if not numbers:
print("DEBUG - List kosong, mengembalikan 0")
return 0
total = sum(numbers)
print(f"DEBUG - Total: {total}") # Debug print
rata = total / len(numbers)
print(f"DEBUG - Rata-rata: {rata}") # Debug print
return rata
# Contoh pemanggilan
hasil = hitung_rata_rata([10, 20, 30, 40, 50])
Python Debugger (pdb)
Teknik selanjutnya pada Python dengan built-in yang disediakan yaitu pdb. Teknik ini memungkinkan untuk menjalankan kode step-by-step serta melakukan peneriksaan variabel secara interaktif.
import pdb
def bagi(a, b):
# Program akan berhenti di baris ini dan membuka terminal interaktif
pdb.set_trace()
hasil = a / b
return hasil
# Memanggil fungsi untuk mulai debugging
print(bagi(10, 0)) # Contoh dengan 0 untuk melihat error di debuggerBerikut beberapa command pdb yang dapat digunakan:
- n (next): Eksekusi baris berikutnya
- c (continue): Lanjutkan eksekusi hingga breakpoint berikutnya
- p variabel: Print nilai variabel
- l (list): Tampilkan kode di sekitar posisi saat ini
- q (quit): Keluar dari debugger
Breakpoint Built-in
Sejak peluncuran Python 3.7 adanya function built-in breakpoint yang dapat digunakan untuk debugging lebih praktis. Berikut contoh penggunaan breakpoint.
def proses_data(data):
hasil = []
for item in data:
# Program akan menjeda eksekusi di sini setiap kali iterasi dimulai
# Ketik 'c' di terminal untuk lanjut ke item berikutnya
breakpoint()
hasil.append(item * 2)
return hasil
# Contoh pemanggilan dengan data list
data_input = [10, 20, 30]
print(proses_data(data_input))Logging Module
Logging module merupakan langkah debugging untuk aplikasi yang lebih kompleks dan profesional. Berbeda dengan teknik print(). Logging akab memungkinkan untuk menyimpan data dalam file. Membedakan tingkatan kepentingan kode dan adanya timestamp waktu debugging secara otomatis. Berikut contoh code penggunaan logging module:
import logging
# Konfigurasi logging dasar
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Membuat logger spesifik untuk modul ini (Best Practice)
logger = logging.getLogger(__name__)
def process_user(user_id):
logger.debug(f"Memulai proses untuk user_id: {user_id}")
try:
# Simulasi proses data user
if not user_id:
raise ValueError("User ID tidak valid")
logger.info(f"User {user_id} berhasil diproses.")
except Exception as e:
# Menggunakan logger.exception akan menyertakan Traceback (detail error)
logger.error(f"Gagal memproses user {user_id}: {e}", exc_info=True)
# Contoh menjalankan fungsi
process_user(101)
process_user(None)IDE Debugger
Pada IDE seperti Visual Code, PyCharm dan Spyder memiliki visual debugger, yang akan mempermudah dalam proses debugging. Fitur debugging pada IDE diantaranta sebagai berikut.
- Set Breakpoint: Pada IDE akan adanya titik merah di samping nomor baris, pada tanda merah umumnya da keterangan atau pesan error yang ditampilkan.
- Watch Variables: Pada sisi dari IDE adanya variabel yang akan ditampilkan, hal ini digunakan untuk memantau perubahan nilai variabel secara otomatis tanpa mengetik print.
- Step Controls: Adanya tombol navigasi (Play, Step Over, Step Into), bagian ini akan mempermudah menjalankan kode baris demi baris untuk melihat alur logika.
- Evaluate Expressions: Pada IDE terdapat adanya debug console yang dapat digunakan untuk mencoba rumus atau mengubah nilai variabel saat program sedang dijeda.
Jenis Error yang Sering Ditemui
Berikut adalah beberapa jenis error yang sering ditemui ketika melakukan testing dan debugging pada Python.
1. Syntax error
Berikut contoh pesan error karena penulisan kode yang tidak sesuai dengan aturan pada Python.
# Missing colonif x > 5 print("Besar")# SyntaxError: invalid syntax2. Name error
Berikut contoh pesan error karena menggunakan variabel yang belum ada definisi sebelumnya.
print(nama) # NameError: name 'nama' is not defined3. Type error
Berikut adanya error karena operasi yang dibuat tidak kompatibel pada program.
x = "5"y = 10print(x + y) # TypeError: can only concatenate str to str4. Index error
Berikut adalah contoh pesan error ketika akses index tidak dapat dijangkau.
numbers = [1, 2, 3]print(numbers[5]) # IndexError: list index out of range5. Logic error
Pada logic error umumnya tidak ada pesan error namun hasilnya tidak sesuai yang diharapkan.
def rata_rata(numbers): return sum(numbers) / len(numbers)
# Jika numbers kosong, akan terjadi ZeroDivisionError# Perlu validasi terlebih dahuluKesimpulan
Testing dan debugging adalah dua skill fundamental yang harus dikuasai oleh setiap Python developer. Testing membantu memastikan kode bekerja sesuai ekspektasi, sementara debugging membantu menemukan dan memperbaiki error yang muncul.
Dengan menggunakan tools seperti unittest atau pytest untuk testing, serta pdb dan logging untuk debugging, Anda dapat mengembangkan aplikasi Python yang lebih stabil dan maintainable.
Demikian seri Belajar Python Part 10 tentang Testing dan Debugging. Nantikan Belajar Python Part 11 di mana kita akan membahas cara menghubungkan python ke database. Semoga bermanfaat!


