Beranda / Kursus / Testing for Beginners / III — Best Practices
III — Best Practices
Artikel 9 dari 9

Best Practices & Next Steps

Checklist test suite yang sehat, kesalahan umum seperti flaky test dan over-mocking, serta roadmap lanjutan — property-based testing, mutation testing, contract testing, sampai menjalankan test otomatis di CI.

10 Juli 2026

Selamat, kamu sudah membangun test suite lengkap untuk task-tracker-api: unit test untuk logic murni, integration test dengan fixture dan dependency override, parametrization untuk menghindari duplikasi, mocking untuk dependency eksternal, coverage report yang dibaca kritis, dan satu fitur penuh yang dibangun lewat TDD. Di artikel penutup ini, kita rangkum jadi checklist, kesalahan umum, dan roadmap lanjutan.

Checklist Test Suite yang Sehat

  • [ ] Ada unit test untuk logic murni (validasi, kalkulasi, transformasi data) — cepat, tanpa I/O (artikel unit test pertama)
  • [ ] Ada integration test untuk endpoint API, memakai database test yang terisolasi per test (artikel fixtures & dependency override)
  • [ ] Test mengikuti pola Arrange-Act-Assert, satu test fokus menguji satu perilaku (artikel anatomi test yang baik)
  • [ ] Kasus negatif diuji sama seriusnya dengan kasus positif — input salah, tanpa izin, data dirusak (artikel unit test pertama, artikel fixtures & dependency override)
  • [ ] Skenario serupa dengan input berbeda dirapikan lewat parametrize, bukan duplikasi fungsi (artikel parametrization)
  • [ ] Dependency eksternal (API pihak ketiga, layanan pembayaran, email) di-mock, tidak pernah dipanggil sungguhan saat test (artikel mocking)
  • [ ] Coverage dicek rutin, tapi dibaca kritis — tahu BAGIAN mana yang tidak tercakup dan KENAPA (artikel test coverage)
  • [ ] Test bisa dijalankan cepat (unit test dalam hitungan detik) dan terisolasi (urutan jalan tidak memengaruhi hasil)
  • Kesalahan Umum

  • Menguji implementasi, bukan perilaku. Test yang terlalu detail memeriksa BAGAIMANA sesuatu dikerjakan (misalnya, memverifikasi urutan pemanggilan internal yang tidak relevan dengan hasil) akan rapuh — setiap refactor kecil yang tidak mengubah PERILAKU tetap memaksa test-nya diubah. Fokus pada APA yang dihasilkan/terjadi dari sudut pandang pemakai kode, bukan detail internal cara mencapainya.
  • Flaky test — kadang lolos, kadang gagal tanpa perubahan kode. Kita sendiri mengalami ini di artikel unit test pertama dengan test tampered token. Penyebab umum lain: test yang bergantung pada urutan eksekusi test lain, waktu (datetime.now() tanpa dikontrol), atau data acak tanpa seed. Begitu flaky test dibiarkan, tim mulai terbiasa "re-run saja sampai hijau" — dan begitu kebiasaan itu terbentuk, sinyal dari test suite sudah kehilangan makna.
  • Over-mocking — memock terlalu banyak, sampai test tidak lagi menguji apa pun yang berarti. Kalau SEMUA dependency di-mock, termasuk yang sebenarnya aman dipakai versi test (seperti database SQLite in-memory kita), test jadi cuma memverifikasi "apakah mock dipanggil", bukan "apakah sistem benar-benar bekerja". Mock secukupnya — cuma untuk yang benar-benar tidak boleh/tidak bisa dipanggil sungguhan saat test.
  • Ice-cream cone anti-pattern. Kebalikan dari testing pyramid yang dibahas di artikel pertama seri ini: terlalu banyak E2E test yang lambat dan rapuh, terlalu sedikit unit test. Gejalanya: test suite butuh puluhan menit dijalankan, developer jadi malas menjalankannya sering-sering, dan feedback loop yang seharusnya cepat jadi lambat.
  • Test suite yang lambat sehingga jarang dijalankan. Test yang tidak pernah dijalankan sama tidak bergunanya dengan tidak ada test sama sekali. Pisahkan unit dan integration (seperti yang kita lakukan lewat marker) supaya developer bisa dapat feedback cepat dari unit test saat aktif menulis kode, dan menjalankan suite lengkap sebelum commit.
  • Menulis test cuma untuk mengejar angka coverage. Sudah dibahas tuntas di artikel test coverage — angka tinggi tanpa assert yang berarti itu ilusi keamanan, bukan keamanan sungguhan.
  • Roadmap Lanjutan

    Seri ini fokus ke fondasi yang paling langsung berdampak. Kalau mau melangkah lebih jauh:

  • Property-based testing (Hypothesis untuk Python) — alih-alih menulis kasus test manual satu-satu, kita definisikan ATURAN yang harus selalu benar (misalnya "hasil hash_password tidak pernah sama dengan input aslinya"), lalu tool ini otomatis mencoba RIBUAN kombinasi input acak untuk mencari kasus yang melanggar aturan itu.
  • Mutation testing (mutmut) — melangkah lebih jauh dari coverage biasa, sudah disinggung di artikel test coverage.
  • Contract testing — untuk sistem dengan banyak service yang saling memanggil, memverifikasi bahwa "kontrak" antar service (bentuk request/response yang disepakati) tidak pernah dilanggar salah satu pihak, tanpa perlu menjalankan semua service sekaligus saat test.
  • Snapshot testing — menyimpan "snapshot" dari output yang dianggap benar (misalnya response JSON yang kompleks), lalu test berikutnya otomatis membandingkan apakah outputnya masih identik — berguna untuk struktur data besar yang merepotkan kalau ditulis assertion manual satu per satu.
  • End-to-end testing dengan Playwright/Selenium — mengetes aplikasi dari sudut pandang browser sungguhan, puncak dari testing pyramid yang dibahas di artikel pertama seri ini — dipakai secukupnya untuk alur paling kritis (login, checkout), bukan pengganti unit/integration test.
  • Load testing — kita sudah sempat menyinggung benchmark sederhana di artikel mengukur sebelum optimasi dari seri Scalability; test performa itu sendiri sebenarnya bentuk testing lain, dengan tujuan berbeda (memverifikasi KECEPATAN, bukan KEBENARAN).
  • Menjalankan test otomatis di CI — kalau belum, CI/CD for Beginners membahas cara menjadikan pytest sebagai gerbang wajib sebelum kode bisa merge — supaya test suite yang sudah kita bangun sepanjang seri ini benar-benar MENCEGAH kode rusak masuk ke main, bukan cuma dijalankan manual sesekali.
  • Kaitan dengan Seri Lain

    Seri ini melanjutkan task-tracker-api dari FastAPI for Beginners dan Security for Beginners. Test suite yang kita bangun di sini adalah gerbang yang akan dijalankan otomatis lewat pipeline CI/CD for Beginners, dan begitu API-mu perlu menangani trafik lebih besar, Scalability for Beginners membahas cara mengukur dan menskalakannya — dengan prinsip yang sama: ukur dulu, baru optimasi, buktikan dengan data.

    Penutup

    Kita sudah menempuh perjalanan dari "kenapa testing penting", memahami anatomi test yang baik, menulis unit test pertama, membangun integration test dengan fixture, merapikan lewat parametrization, mocking dependency eksternal, membaca coverage secara kritis, sampai membangun fitur penuh lewat TDD. Yang paling penting, setiap pelajaran di seri ini datang dari pengalaman nyata menulis test untuk task-tracker-api — termasuk saat kita sendiri menemukan test yang flaky, dan memperbaikinya bukan dengan menghapusnya, tapi dengan memahami akar masalahnya.

    Terima kasih sudah mengikuti seri Testing for Beginners ini. Selamat menulis test untuk proyek kamu sendiri!

    Topik

    TestingBest Practices
    III — Best Practices · Article 9 of 9