/eshop-adpro

Lab/Tutorial Repository for Advanced Programming Course

Primary LanguageJava

Reflections

Coverage Branches

Deployment dapat dilihat di sini.

Modul 1

Refleksi 1

You already implemented two new features using Spring Boot. Check again your source code and evaluate the coding standards that you have learned in this module. Write clean code principles and secure coding practices that have been applied to your code. If you find any mistake in your source code, please explain how to improve your code. Please write your reflection inside the repository's README.md file.

Pada source code saya, saya telah menerapkan beberapa prinsip clean code, seperti membuat setiap method hanya melakukan suatu hal saja, tidak melakukan hal-hal lain, memberikan nama method dan variable sesuai dengan apa yang dilakukan atau disimpan dari method atau variable tersebut, dan membuat classes yang mempunyai tujuannya sendiri juga, tidak mencampurnya semua dalam sebuah class. Selain itu, saya juga telah menerapkan secure coding practice pada fitur edit dan delete product dengan mengecek apakah id dari product yang ingin di edit/delete ada atau tidak, jika id tersebut tidak ada, program akan melempar Exception bahwa product dengan id yang diinginkan tidak ada. Generasi id tersebut juga sudah aman karena menggunakan library UUID milik Java dan tidak dapat di set oleh pengguna. Penggunaan framework Spring Boot dengan Thymeleaf juga sudah memberikan lapisan keamanan sederhana, seperti validasi input integer sehingga tidak overflow. Namun, menurut saya masih ada beberapa hal yang dapat ditingkatkan dalam source code saya, seperti penambahan bagian yang mengurus error agar website tidak mengeluarkan stack trace error.

Refleksi 2

After writing the unit test, how do you feel? How many unit tests should be made in a class? How to make sure that our unit tests are enough to verify our program? It would be good if you learned about code coverage. Code coverage is a metric that can help you understand how much of your source is tested. If you have 100% code coverage, does that mean your code has no bugs or errors?

Setelah menulis beberapa unit test, saya merasa lebih yakin bahwa method-method yang telah saya buat bekerja sesuai dengan ekspektasi. Menurut saya, banyak unit test yang terdapat dalam sebuah class jangan terlalu sedikit, tetapi jangan terlalu banyak juga, harus dapat menemukan titik tengah yang baik agar semua method/function dalam sebuah class dapat di test dengan baik. Untuk mengecek unit test yang kita buat sudah mencukupi untuk memverifikasi program yang kita buat, idealnya test yang kita buat dapat mencapai 100% code coverage, karena code coverage merupakan metric yang secara simpel melihat apakah semua baris code yang ada dalam source code dieksekusi. 100% coverage berarti semua baris berhasil dieksekusi, namun 100% coverage masih belum menjamin bahwa code kita tidak ada bug atau error, karena coverage hanya menjamin x% baris code telah tereksekusi. Masih ada kemungkinan beberapa edge case yang tidak terpikirkan oleh kita untuk kita tulis dalam unit test yang kita buat.

Suppose that after writing the CreateProductFunctionalTest.java along with the corresponding test case, you were asked to create another functional test suite that verifies the number of items in the product list. You decided to create a new Java class similar to the prior functional test suites with the same setup procedures and instance variables. What do you think about the cleanliness of the code of the new functional test suite? Will the new code reduce the code quality? Identify the potential clean code issues, explain the reasons, and suggest possible improvements to make the code cleaner! Please write your reflection inside the repository's README.md file.

Berdasarkan code CreateProductFunctionalTest.java yang saya buat, terdapat beberapa hal yang akan menjadi pengulangan jika saya melakukan setup yang sama, seperti inisiasi variable baseUrl dan endpoint yang akan digunakan, inisiasi variable port, library-library yang akan di import, serta ada beberapa bagian code yang sama. Jika saya ingin memverifikasi jumlah item yang terdapat dalam list product, tentu saya harus membuat produk-produknya dahulu, karena pada awalnya tidak ada produk yang tersedia. Bagian ini sama saja seperti pada saat saya melakukan testing untuk membuat product pada CreateProductFunctionalTest.java. Walaupun sebenarnya bisa saja saya membuat product secara programmatic lalu baru melakukan verifikasi banyak barang secara functional, menurut saya ini bisa saja digabungkan dengan file functional test yang sudah ada. Kemudian, untuk memverifikasi jumlah product yang ada dalam list product, saya menghitung banyaknya elemen <td> yang ada dalam HTML, dengan 1 product menghasilkan 4 elemen <td>. Cara tersebut juga saya gunakan untuk memverifikasi keberadaan product yang saya telah buat pada functional test create product, sehingga sekali lagi, bisa saja saya gabungkan dengan test tersebut. Namun, salah satu masalahnya dengan penggabungan ini adalah panjangnya method yang akan terbentuk, karena akan membuat beberapa produk baru lalu di verifikasi. Menurut saya, salah satu cara mengatasi ini adalah dengan melakukan setup beberapa product secara programmatic dahulu, kemudian untuk test create product, dibuat lagi suatu product baru dengan cara memverifikasi keberhasilan create product tersebut dengan cara lain selain menghitung jumlah elemen <td> yang terdapat pada halaman, dan kemudian baru mengecek banyaknya product dalam list product dengan menghitung jumlah elemen <td>.

Modul 2

List the code quality issue(s) that you fixed during the exercise and explain your strategy on fixing them.

Code quality issues yang saya perbaiki cukup minor, yaitu hanya memperbaiki statement if yang seharusnya menggunakan kurung kurawal meskipun hanya ada 1 statement setelahnya dan menghapus modifier public dari method yang di deklarasi pada interface PublicService. List code quality issues tersebut dapat dilihat pada link berikut. Strategi saya dalam memperbaiki code quality issues tersebut adalah melihat permasalahannya di tab Security di GitHub dan melakukan apa yang diminta permasalahan tersebut. Berhubung issue yang saya perbaiki cukup minor, hal tersebut sangat mudah dilakukan. Dari sekian banyak issues yang muncul di tab Security, saya hanya memperbaiki kedua jenis code quality issues tersebut karena issue-issue yang lain tidak terlalu berkaitan dengan kualitas code yang saya tulis. Issue lain lebih ke arah apa saja yang seharusnya terdapat dalam suatu project, seperti license, security policy, atau penambahan Dependabot.

Look at your CI/CD workflows (GitHub)/pipelines (GitLab). Do you think the current implementation has met the definition of Continuous Integration and Continuous Deployment? Explain the reasons (minimum 3 sentences)!

Menurut saya, workflow CI/CD yang telah saya implementasikan sejauh ini sudah dapat dikatakan memenuhi definisi Continuous Integration dan Continuous Deployment secara basic. Dari workflow CI/CD yang saya implementasikan, 3 diantaranya merupakan workflow CI dan satu merupakan workflow CD. Workflow CI yang saya miliki meliputi workflow untuk mengetes apakah ketika saya mengubah atau menambahkan code, hasil perubahan/penambahan tersebut dapat merusak fitur-fitur lain. Selain itu, ada juga workflow untuk memastikan ketika saya mengubah atau menambahakan code ke code base saya, code yang saya tulis itu tidak menimbulkan code quality issues atau mengintroduce vulnerability. Untuk workflow CD, saya melakukan deployment di Koyeb, sehingga workflow deploymentnya sudah di konfigurasi oleh Koyeb sendiri dan saya hanya mengkonfigurasi agar workflow tersebut hanya berjalan ketika ada push ke main. Dari sini, menurut saya definisi Continous Integration dan Continuous Deployment sudah terpenuhi meskipun mungkin tidak terlalu fully featured seperti project besar dan mungkin sebenarnya masih ada hal-hal lain yang diperlukan.

Modul 3

Explain what principles you apply to your project!

Principle yang saya telah apply ke project saya adalah principle Single Responsibility Principle (SRP), Open-Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface Segregation Principle (ISP), dan Dependency Inversion Principle (DIP). Dengan SRP, saya mengubah code saya sehingga setiap class hanya melakukan suatu hal saja, tidak mencampur-campur kewajiban tiap class, seperti class ProductController hanya untuk mengurus mapping untuk Product dan class CarController hanya untuk mengurus mapping untuk Car. Dengan OCP, saya memastikan bahwa classes dan function yang saya buat dapat di extend atau ditambahkan implementasinya, tanpa harus mengubah code base yang sudah ada, seperti penggunaan interface ProductService sebagai basis dalam pembuatan ProductServiceImpl yang mengharuskan di buatnya beberapa method yang nantinya akan digunakan tetapi masih dapat ditambahkan method-method lain sebagai method pendukung. Dengan LSP, saya membuat agar code yang saya tulis, menggunakan super class dibanding menggunakan concrete implementation tidak akan merusak code base, seperti pada penggunaan CarService, saya mengubah tipe CarServiceImpl menjadi CarService dan tidak ada code yang rusak. Dengan ISP, interface yang saya buat hanya memiliki hal-hal yang penting untuk dimiliki saja untuk Product dan Car, seperti pembuatan dan penyimpanan objek, edit objek, penghapusan objek, dan pencarian objek. Dengan DIP, saya membuat bagian-bagian code yang membutuhkan objek lain seperti Service yang membutuhkan Repository agar objek yang dibutuhkan tidak di instansiasi secara langsung pada class yang terkait, melainkan di inject melalui Autowired milik Spring.

Explain the advantages of applying SOLID principles to your project with examples.

Dengan mengaplikasikan principle SOLID pada project saya, ketika saya ingin mengubah detail implementasi dari suatu bagian code, saya tidak harus mengubah semua code basenya untuk menyocokkannya dengan code baru. Misalnya, jika saya ingin mengubah implementasi method create untuk Car, saya tidak perlu mengubah method create pada tingkat service ataupun controller. Saya bisa hanya mengubah implementasinya pada CarRepository dan menyesuaikan apa yang harus di return dari method tersebut. Selama saya tidak mengubah-ubah return type method create pada CarRepository, codebase saya tidak akan rusak oleh perubahan ini. Dengan mengaplikasikan principle SOLID, saya juga dapat tahu dengan cepat file apa yang harus saya modifikasi ketika saya ingin mengubah atau menambahkan suatu hal. Misal saya ingin menambahkan mapping untuk Product, maka saya pasti akan mengedit file ProductController.java karena class ProductController merupakan class yang memiliki tanggung jawab terhadap mapping untuk Product.

Explain the disadvantages of not applying SOLID principles to your project with examples.

Jika saya tidak mengaplikasikan principle SOLID pada project saya, maka saya membutuhkan waktu yang lebih untuk memastikan penambahan atau modifikasi pada code base tidak akan membuat hal-hal lain rusak dan tidak bekerja. Misalnya saya ingin mengubah implementasi pada method delete untuk Product. Saya akan mengubah implementasi method tersebut pada class ProductRepository, namun setelah mengubahnya, saya tidak punya keyakinan bahwa perubahan yang saya buat tidak akan merusak bagian-bagian lain dari code base saya. Bisa saja perubahan yang saya lakukan merusak sesuatu di tengah jalan sehingga ketika user ingin melakukan Delete Product, product tidak ke delete dan hal lain yang terjadi. Hal ini berarti saya harus menghabiskan waktu lebih untuk menyesuaikan code base terhadap code yang baru saja saya modifikasi. Tanpa menerapkan SOLID pada project saya, struktur project saya dapat terlihat berantakan atau terlalu kotor karena ada class dimana class tersebut melakukan berbagai macam hal sekaligus, misalnya menjadi controller dan service sekaligus.

Modul 4

Reflect based on Percival (2017) proposed self-reflective questions (in “Principles and Best Practice of Testing” submodule, chapter “Evaluating Your Testing Objectives”), whether this TDD flow is useful enough for you or not. If not, explain things that you need to do next time you make more tests.

Menurut saya, flow TDD ini cukup membantu saya tapi di lain sisi juga membuat saya bekerja terlalu lama memikirkan test yang benar. Flow TDD ini sempat membantu saya menemukan bug yang saya mungkin terlewat jika saya tidak melakukan TDD. Bug tersebut ada pada PaymentRepository method save, yang seharusnya mengubah status order berdasarkan status payment tetapi saya terlewat belum mengimplement hal tersebut. TDD membuat saya mampu mendapatkan bug tersebut di awal sehingga saya tidak harus debug program saya nanti. Namun saya juga merasa terbatasi oleh TDD karena menghabiskan terlalu banyak waktu memikirkan test yang benar dan dimana harus meletakkan method yang sesuai.

You have created unit tests in Tutorial. Now reflect whether your tests have successfully followed F.I.R.S.T. principle or not. If not, explain things that you need to do the next time you create more tests.

Menurut saya, semua test yang telah saya bikin pada tutorial ini kurang lebih sudah memenuhi principle F.I.R.S.T. Menurut saya, test yang saya buat sudah mengcover semua kemungkinan happy dan unhappy, namun saya masih kurang yakin apakah memang sudah semua kasus telah dibuat, sehingga saya kurang yakin terhadap terpenuhinya principle T. Tetapi, terkait principle lainnya dari F.I.R.S.T., saya yakin bahwa test yang saya buat sudah memenuhi principle-principle tersebut. Hal ini dikarenakan saya juga sudah mengikuti tutorial yang terlihat sudah memenuhi principle F.I.R.S.T. Test yang saya buat tidak berjalan terlalu lama karena test tidak terlalu kompleks, saya hanya mengetest hal-hal yang dianggap penting dari setiap method. Selain itu, test tersebut juga repeatable, isolated, dan self-validating karena saya memisahkan setiap kasus test menjadi testnya sendiri dan sudah memiliki assertions yang sesuai.