CI/CD dan Clean Code

Rehan Hawari
kelompok-propensi
Published in
5 min readMar 19, 2019

Pada individual review kali ini saya akan membahas mengenai CI/CD, clean code dan software testing.

CI/CD

Kelompok saya menggunakan docker untuk deployment. Kami memiliki tiga package, yakni backend_service (sebagai mock doku), backend (sebagai simulator) dan frontend (sebagai simulator). Masing-masing perlu di-deploy pada container yang berbeda karena ketiganya akan saling berkomunikasi. Setiap package melewati stage yang kurang-lebih sama, yakni:

  • Test
    Semua package wajib melewati stage ini karena pada stage ini juga akan dihitung code coverage dari package. Saya sempat kesulitan dalam mengambil code coverage untuk package backend_service dan backend yang menggunakan framework maven. Masalahnya adalah jacoco (java code coverage library) tidak mencetak output pada STDOUT, melainkan mencetaknya kedalam bentuk html di /target/site/jacoco/index.html. Oleh karena itu, saya perlu mencetak hasil code coverage tersebut dengan menggunakan command seperti berikut

Dengan begitu, hasil code coverage akan dicetak pada STDOUT sehingga gitlab dapat men-capture code coverage dari package.

  • Build
    Pada stage ini, dilakukan build dari package ke dalam bentuk executable. Package maven seperti backend dan backend_service akan dibentuk menjadi jar agar dapat dijalankan di dalam container. Saya sempat menemui masalah dalam melakukan build, yakni ternyata mvn install melakukan proses test lagi yang mana sebelumnya telah dijalankan pada stage test. Sehingga saya perlu memberikan flag bahwa pada stage ini test harusnya diskip seperti berikut

Dengan begitu, test tidak akan lagi dijalankan pada stage build, dan cukup menghemat waktu sekitar 3 menit.

  • Pages
    Stage ini seharusnya membuat file report dari jacoco (index.html) menjadi publik/dapat diakses melalui gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2019/PPLC1, tetapi sayangnya belum berjalan dengan baik. File tersebut belum dapat diakses, saya menduga masalah permission atau memang ada yang salah dalam gitlab ci saya. Berikut tampilan stage pages:
  • Deploy
    Untuk deployment, kami sudah menggunakan deployment berdasarkan environment development, staging dan production. Hal ini dilakukan dengan menentukan nama dari image yang dibuat berdasarkan environment code. Seperti berikut:

Sampai saat tulisan ini dibuat, yang sudah dicoba hanya environment development karena kami belum menggabungkan hasil ke staging maupun production. Meskipun begitu, environment development berjalan dengan baik tanpa ada masalah.

Clean Code

Selanjutnya saya akan membahas mengenai clean code yang sempat saya implementasikan. Sebelumnya kami sempat mengambil backlog mensimulasikan pembayaran menggunakan ATM Permata. Saya mengerjakan bagian pembuatan API untuk inquiry dari ATM Permata. Sayangnya, pada saat implementasi saya menggunakan penamaan yang kurang baik seperti menggunakan kata kerja untuk nama kelas (GetBillController). Akhirnya saya pun melakukan refactoring dengan mengganti penamaan menjadi PermataInquiryController.

Setelah mengimplementasikan ini, saya baru menyadari ternyata penamaan sangat penting dipikirkan baik-baik di awal. Karena apabila code telah jadi, mengubah penamaan dengan refactoring cukup melelahkan karena banyak code yang perlu diubah.

Selanjutnya, saya juga menerapkan prinsip DRY atau don’t repeat yourself. Lebih tepatnya, pada kali ini saya mencoba untuk tidak mengulangi code yang saya buat dan menghindari menuliskan code secara hardcode.

Di atas adalah contoh dari code yang hardcoded (penamaannya pada saat itu masih salah). Saya melakukan refactor dengan mengubah expectedResult diparse menjadi class dan membandingkan kedua instance dengan method equals.

Menurut saya cara ini lebih mudah dibaca dibandingkan dengan membandingkan string json yang panjang.

Selain contoh di atas, saya juga menerapkan class yang memiliki konsisten behavior. Saya memisahkan logic dengan controller, jadi sehingga diperlukan manipulasi request atau operasi logical, controller akan memanggil kelas service yang memiliki method-method untuk fungsi logical. Jadi, semua logic ada pada kelas service seperti berikut:

Saya juga menerapkan hal yang sama pada request body dan response body. Daripada menerima string, method pada controller akan menerima kelas Request sebagai request body dan mengembalikan HttpEntity yang didalamnya terdapat kelas Response yang saya buat. Contohnya seperti berikut:

Hal ini dapat dilakukan jika request body yang masuk ke method konsisten atau semua fieldnya mandatory. Jika Request body yang datang memiliki banyak field yang opsional, saya akan memilih menggunakan String sebagai input request body.

Software Testing

Saya akan membahas khusus tentang mock. Pada sprint sebelumnya, saya diharuskan membuat mock agar dapat mengontrol hasil output dari sebuah method. Namun, tidak seperti mock biasanya terdapat perbedaan yakni mock yang harus saya lakukan adalah mocking mvc. Mocking mvc berbeda karena pada saat mocking kita perlu membuat mvc berdasarkan kelas yang ingin dimock.

Saya mencoba melakukan melakukan test pada kelas PermataInquiryController yang memanggil InquiryService, sehingga saya perlu mock InquiryService dan membuat mvc yang isiniya PermataInquiryController.

InitMocks dan Building mock diperlukan jika melakukan mock mvc. Jika sudah init dan build, kita dapat menggunakan when thenReturn dari Mockito seperti biasanya.

Untuk mentrigger test, lakukan pemanggilan fungsi dengan mvc yang telah dibuat sebelumnya.

Cara ini merupakan pengetahuan baru untuk saya, sebelumnya saya hanya menggunakan mock decorator dan memanggil mockito when return, namun ternyata cara tersebut tidak dapat digunakan ketika melakukan test mvc karena mvc memanggil kelas asli dan when mockito tidak akan di-hit.

--

--