Ruthless Testing 3

Posted on July 20th, 2006 | by Endy Muhardin |

Alkisah, di suatu project, ada kode program yang berkelakuan aneh. Kode program tersebut berfungsi untuk melakukan pendaftaran user baru ke dalam sistem. Jadi, user membuka form, mengisi data diri, dan menekan tombol Submit. Tidak ada yang aneh dengan fiturnya.

Keanehannya adalah, entah kenapa, aplikasi tersebut cuma bisa digunakan 7 kali. Jadi pada waktu user ke-8 menekan tombol Submit, datanya tidak tersimpan di database. Anehnya juga, aplikasi tidak menimbulkan pesan error. Hmm … sungguh gaib.

Berbagai upaya dilakukan untuk mengatasi masalah ini. Tim pengusir hantu didatangkan, lengkap dengan kostum putih-putih dan botol penangkap hantu, karena dicurigai ada ’sesuatu’ dengan angka 7. Tetapi tidak juga mencapai solusi yang memuaskan.

Akhirnya, seorang anggota milis JUG didatangkan. Beliau memeriksa source code fitur registrasi tersebut, sebagai berikut:


public void save (User u) {
  try {
    Connection conn = DriverManager.getConnection(url, username, password);

    PreparedStatement pstm = conn.prepareStatement("INSERT INTO user VALUES (?,?,?)");
    pstm.setInt(1, u.getId());
    pstm.setString(2, u.getUsername());
    pstm.setString(3, u.getPassword());

    pstm.executeUpdate();
  } catch(Exception err) {

  }
}

Pembaca yang teliti (ya, maksudnya Anda) akan segera menemukan asal muasal semua ‘kejadian gaib’ di atas, yaitu:

  1. Connection dibuka, tapi tidak pernah ditutup. Besar kemungkinan max connection di database adalah 7 concurrent connection. Sehingga setelah 7 kali connect dan 0 kali disconnect, database akan menolak koneksi baru.
  2. Catch block dibiarkan kosong, sehingga error dari database tidak akan tampil di mana-mana.

Hmm .. kesalahan yang ‘newbie banget’. Melalui pemeriksaan menyeluruh, ditemukan kesalahan serupa di berbagai bagian kode yang lain.

Pada titik ini, para project manager, development team leader akan segera mengeluh dan bersiap-siap mengisi komentar di bawah, “Masa saya harus baca kode baris-per-baris? Kayak kurang kerjaan aja !!”
Sebelum Anda lakukan itu, sabar dulu .. baca sampai habis. Kita akan segera lihat solusinya.

Pemeriksaan baris kode seperti ini sangat melelahkan. Semakin besar projectnya, semakin banyak baris kodenya, semakin tinggi beban pemeriksaannya. Di lain pihak, kalau kita tidak melakukan pemeriksaan, kita menimbulkan resiko terjadinya masalah di kemudian hari.

Jadi, bagaimana solusinya?

Untungnya –seperti biasa– kita bukan yang pertama menemukan masalah seperti ini. Masalah sudah pernah dialami orang lain, dan dibuatkan solusinya, sehingga kita –seperti biasa– tinggal download dan pakai :D

Jawaban dari masalah ini adalah automated code review. Tools ini akan melakukan review terhadap source code, sesuai dengan aturan yang kita tetapkan, dengan teliti, otomatis, dan repeatable. Dengan tool ini, berapapun baris kode yang ada, semua akan diperiksa secara menyeluruh.

Ada beberapa solusi yang dapat digunakan:

Pada contoh kali ini, kita akan coba menggunakan PMD. Caranya mudah:

  1. Download dari websitenya.
  2. Extract
  3. Buat target di Ant untuk memanggil PMD.
  4. Lihat reportnya

Untuk langkah #1 dan #2 tidak perlu dijelaskan lebih lanjut. Target Ant untuk langkah #3 adalah sebagai berikut:


<target name="code-review" depends="prepare">
  <pmd targetjdk="1.5" shortFilenames="true">

    <ruleset>basic</ruleset>
    <ruleset>codesize</ruleset>
    <ruleset>clone</ruleset>
    <ruleset>controversial</ruleset>
    <ruleset>coupling</ruleset>
    <ruleset>design</ruleset>
    <ruleset>finalizers</ruleset>
    <ruleset>imports</ruleset>
    <ruleset>javabeans</ruleset>
    <ruleset>logging-java</ruleset>
    <ruleset>logging-jakarta-commons</ruleset>
    <ruleset>naming</ruleset>
    <ruleset>optimizations</ruleset>
    <ruleset>strictexception</ruleset>
    <ruleset>strings</ruleset>
    <ruleset>sunsecure</ruleset>
    <ruleset>unusedcode</ruleset>

    <formatter
        type="net.sourceforge.pmd.renderers.HTMLRenderer"
        toFile="${pmd.result}/pmd.html"
    />
    <fileset dir="src">
      <include name="**/*.java"/>
    </fileset>
  </pmd>
</target>

Berikut penjelasannya:

  1. Target JDK : memeriksa kesesuaian dengan JDK 1.5
  2. Ruleset : Aturan yang akan diberlakulkan. Detailnya bisa dilihat di website PMD. Sebagai contoh, dengan memberlakukan ruleset basic, kita memeriksa blok catch yang kosong, sehingga mencegah masalah pesan error di atas. Sedangkan ruleset design memeriksa apakah Connection yang dibuat sudah ditutup.
  3. Formatter : Jenis formatter yang digunakan. Report yang dihasilkan PMD dapat berupa text, xml, csv.
  4. Fileset: source code yang akan direview. Kita dapat mengganti parameter ini dan mereview semua source code yang ada di harddisk kita. SIlahkan mencoba mendownload source code project open source java (misalnya Tomcat, atau JBoss), dan lihat apakah kode programnya ditulis dengan baik.

Laporan yang dihasilkan bentuknya seperti ini:
PMD Review Result

Selamat mencoba. Semoga bermanfaat.

  1. 5 Responses to “Ruthless Testing 3”

  2. By Muhammad Sudirman on Jul 25, 2006 | Reply

    Maaf… saya menggunakan Java == hanya sebagai hobi.
    Saya lebih sering pakai C++ atau C# (Microsoft .NET).

    Hhhmmmm…. aneh, kenapa kode seperti ini menjadi aneh ?
    Coba kita lihat, ruang lingkup object conn == dalam fungsi save()

    So ? jika sudah keluar dari fungsi save(), bukankah tugas dari VM untuk memusnahkan object conn.
    Bila object conn sudah dimusnahkan ? Apa tidak sepantasnya, semua resouce yang digunakan oleh object conn menjadi ???

    Kecuali object conn bersifat static

    Dari uraian Anda ini, saya malah mendapat kesimpulan :: “Waaahhh.. JVM klo’ men-destroy suatu object, maka resouce object itu tidak dibersihkan euy…”

    “Hanya sekedar bertukar fikiran” — itulah gunanya Blog khan ?

  3. By Endy Muhardin on Jul 26, 2006 | Reply

    Pengamatan yang teliti .. :D

    Berikut tanggapan saya.
    Pertama, contoh kode di atas belum tentu benar 100%, bahkan belum tentu bisa compile. Contoh kode di atas cuma dimaksudkan untuk menegaskan maksud saya bahwa code review itu penting. Sama seperti Donald Knuth dalam bukunya Art of Programming, mengatakan, bahwa tidak semua contoh kode dalam bukunya bisa dikompile, apalagi dijalankan, karena memang hanya sekedar ilustrasi.

    Kedua, tentang method Connection.close. Berdasarkan Java API Documentation, dinyatakan bahwa method close :
    Releases this Connection object’s database and JDBC resources immediately instead of waiting for them to be automatically released.
    Note: A Connection object is automatically closed when it is garbage collected.

    Berarti benar pengamatan mas Sudirman bahwa pada saat object conn menjadi korban GC, connection akan segera di-close.
    Tapi berarti kita mengandalkan GC untuk menutup koneksi, di mana exact timing of collection is unpredictable. Bisa 2 detik kemudian, bisa juga 2 hari kemudian.

    So, kalau object conn tersebut belum ter-GC sedangkan method save sudah dieksekusi berkali-kali, tetap akan terjadi connection leak.

    Begitu hasil googling saya. Silakan dikoreksi kalo salah. :D

  4. By ed on Mar 5, 2007 | Reply

    Dasar bodoh kamu sudirman , sok komentar..biarkanlah org berkreasi memberikan nasehat !!

  5. By blablabla on Aug 16, 2007 | Reply

    4 Responses to “Ruthless Testing 3”

    Tapi komentarnya hanya ada 3???

    Tanya kennn apa……

    LOL

Post a Comment