From 0f0d6b7f96c6bbfafa12f7161f9fc8a614703be6 Mon Sep 17 00:00:00 2001 From: Ichlasul Affan <ichlasul.affan@ui.ac.id> Date: Wed, 1 Nov 2023 14:18:53 +0700 Subject: [PATCH] Revise the day 2 workshop about SQA --- docs/workshops/day_2_tdd.md | 467 ++++++++++-------- .../images/day_2_tdd_-_sonarqube_sibayar.png | Bin 0 -> 55009 bytes 2 files changed, 272 insertions(+), 195 deletions(-) create mode 100644 docs/workshops/images/day_2_tdd_-_sonarqube_sibayar.png diff --git a/docs/workshops/day_2_tdd.md b/docs/workshops/day_2_tdd.md index 65f0a0e..8598283 100644 --- a/docs/workshops/day_2_tdd.md +++ b/docs/workshops/day_2_tdd.md @@ -1,22 +1,23 @@ # Day 2: Test-Driven Development -* Session 1: 9:00 - 10:00: [Testing Category][1] -* Session 2: 10:15 - 11:30: Hands-on: A bigger Case study -* Session 3: 13:30 - 15:00: Hands-on: A bigger Case study +* Session 1: 9:00 - 10:30: [Testing Category][1] +* Session 2: 10:30 - 11:15: Hands-on: A bigger Case study +* Session 3: 13:00 - 15:30: Hands-on: A bigger Case study * Session 4: 15:30 - 16:30: Overview, Discussion, Lesson learned ## Dive Deeper into Unit Testing Pada hari pertama, telah disediakan contoh bagaimana membuat aplikasi web berbasis Spring Boot dengan *unit test* dan functional test suite yang lengkap. -Pada hari ini, kita akan mendalami terkait bagaimana membuat *unit test suite* yang memenuhi 5 aspek FIRST principle, sembari mengikuti *flow* Test-Driven Development: -- Fast: proses *testing* secara keseluruhan harus dilakukan dengan cepat. -- Isolated: setiap *unit test* **tidak boleh memengaruhi hasil** *unit test* lain. -- Repeatable: hasil tes konsisten meskipun dijalankan berkali-kali pada kondisi yang sama. -- Self-Validating: bisa digunakan untuk mengecek kesesuaian aplikasi jika terjadi perubahan kode. -- Thorough: sebisa mungkin mencakup keseluruhan kode dan *business logic* aplikasi. - -Untuk *hands-on* ini, kita akan fokus ke sisi back-end dari aplikasi. +Pada hari ini, kita akan mendalami terkait bagaimana membuat *unit test suite* yang memenuhi 5 aspek FIRST *principle*: + +- ***Fast***: proses *testing* secara keseluruhan harus dilakukan dengan cepat. +- ***Isolated***: setiap *unit test* **tidak boleh memengaruhi hasil** *unit test* lain. +- ***Repeatable***: hasil tes konsisten meskipun dijalankan berkali-kali pada kondisi yang sama. +- ***Self-Validating***: bisa digunakan untuk mengecek kesesuaian aplikasi jika terjadi perubahan kode. +- ***Thorough***: sebisa mungkin mencakup keseluruhan kode dan *business logic* aplikasi. + +Untuk *hands-on* ini, kita akan fokus ke sisi *back-end* dari aplikasi. Kita akan memanfaatkan teknik berupa *mock* dan *stub* untuk membuat kode cakupan setiap *test* kita menjadi lebih fokus terhadap objek yang benar-benar akan di-*test*. **Apa itu *mock*?** @@ -24,7 +25,7 @@ Kita akan memanfaatkan teknik berupa *mock* dan *stub* untuk membuat kode cakupa *Mock* adalah objek palsu yang kita bisa gunakan untuk menggunakan objek yang menjadi dependensi dari suatu fungsi/kelas. *Mock object* dapat kita gunakan untuk *tracking*, yaitu melihat bagaimana interaksi antara fungsi yang kita *test* dengan objek dependensi tersebut. -Contoh sederhananya adalah, kita mau melihat apakah fungsi kita melakukan proses *Save Object* ke sebuah database. +Contoh sederhananya adalah, kita ingin melihat apakah fungsi kita melakukan proses *Save Object* ke sebuah database. Berikut adalah contoh penggunaan *mock* di *test code*: ```java @InjectMocks @@ -46,10 +47,10 @@ Berikut adalah contoh penggunaan *mock* di *test code*: *Stub* adalah objek palsu yang kita bisa gunakan untuk menyimulasikan keluaran fungsi-fungsi pada objek tersebut. Hal ini sangat berguna jika kita menggunakan *library* eksternal atau API eksternal, sehingga *unit test* kita tidak akan membuang waktu dan *resource* untuk mengakses *library* atau API tersebut. -Kita bisa meminta *stub* untuk mengembalikan hasil yang kita mau untuk diproses oleh fungsi yang kita *test*. +Kita bisa meminta *stub* untuk mengembalikan hasil yang kita inginkan untuk diproses oleh fungsi yang kita *test*. Kita juga bisa meminta *stub* untuk memberikan *error* untuk menyimulasikan *negative case*. -Contoh sederhananya adalah, kita mau menyimulasikan bahwa terdapat objek *Payment* di database, +Contoh sederhananya adalah, kita ingin menyimulasikan bahwa terdapat objek *Payment* di database, tanpa kita harus memasukkan entri *Payment* ke dalam database terlebih dahulu. Berikut adalah contoh penggunaan *stub* di *test code*: ```java @@ -66,7 +67,7 @@ Berikut adalah contoh penggunaan *stub* di *test code*: Payment payment = new Payment("a-01", "Bambang", 20000); when(repository.getById("a-01")).thenReturn(payment); - // Cek apakakh eksekusi method "create" akan memunculkan exception PaymentAlreadyCreated + // Cek apakah eksekusi method "create" akan memunculkan exception PaymentAlreadyCreated assertThrows(PaymentAlreadyCreated.class, () -> { service.create("a-01", "Usep", 100000); }); @@ -78,10 +79,10 @@ Berikut adalah contoh penggunaan *stub* di *test code*: Untuk mengikuti rangkaian kegiatan workshop hari ini, harap persiapkan _tools_ berikut di komputer anda: -- Git -- IntelliJ Community Edition -- Java JDK 17 (`java` dan `javac`) -- Apache Maven (`mvn`) +- [Git](https://git-scm.com/) +- [Java JDK 17](https://adoptium.net/temurin/releases/?version=17) (`java` dan `javac`) +- [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) +- [Apache Maven](https://maven.apache.org/download.cgi) (`mvn`) Buat salinan _branch_ `main` dari repositori Git kode templat workshop hari ini: @@ -104,26 +105,28 @@ Kita akan lengkapi bersama saat tutorial ini. ## SIBAYAR: Pembayaran peer-to-peer dengan mekanisme Accept Payment dan Disbursement -SIBAYAR merupakan sistem pembayaran peer-to-peer sederhana yang menggunakan sebuah API *payment gateway* (dalam kasus ini, Flip) untuk menyalurkan uang. +SIBAYAR merupakan sistem pembayaran peer-to-peer sederhana yang menggunakan sebuah API *payment gateway* (dalam kasus ini, [Flip][2]) untuk menyalurkan uang. Berikut adalah flow keseluruhan dari sistem SIBAYAR: + 1. User bisa melakukan transfer uang ke User lain, atau ke nomor rekening yang tidak terdaftar di SIBAYAR. -2. SIBAYAR mengontak API Flip untuk mendapatkan link pembayaran, +2. SIBAYAR mengontak API [Flip][2] untuk mendapatkan link pembayaran, yang bisa digunakan User untuk membayar transfer tersebut. -3. User melakukan pembayaran menggunakan link pembayaran yang telah diberikan API Flip ke User melalui SIBAYAR. +3. User melakukan pembayaran menggunakan link pembayaran yang telah diberikan API [Flip][2] ke User melalui SIBAYAR. 4. Jika user sudah selesai melakukan pembayaran, - API Flip akan mengeksekusi *payment callback endpoint* milik SIBAYAR untuk melanjutkan proses transfer. -5. Ketika API Flip mengeksekusi *payment callback endpoint* SIBAYAR, + API [Flip][2] akan mengeksekusi *payment callback endpoint* milik SIBAYAR untuk melanjutkan proses transfer. +5. Ketika API [Flip][2] mengeksekusi *payment callback endpoint* SIBAYAR, sistem SIBAYAR akan kembali mengontak API Flip untuk transfer uang (*disbursement*) ke rekening tujuan. -6. Ketika Flip berhasil melakukan *disbursement*, +6. Ketika [Flip][2] berhasil melakukan *disbursement*, API Flip akan mengeksekusi *disbursement callback endpoint* milik SIBAYAR, sehingga pembayaran tersebut akan ditandai **sukses** oleh SIBAYAR. -Untuk tutorial hari ini, tidak perlu khawatirkan akses *callback* dari Flip, -karena Flip hanya bisa melakukan *callback* ketika aplikasi SIBAYAR sudah di-*deploy* secara publik. +Untuk tutorial hari ini, tidak perlu khawatirkan akses *callback* dari [Flip][2], +karena [Flip][2] hanya bisa melakukan *callback* ketika aplikasi SIBAYAR sudah di-*deploy* secara publik. Akan tetapi, kita tetap perlu mengimplementasikan keseluruhan sistem SIBAYAR, dengan menyusun tiga *controller*: + 1. `AuthenticationController`: untuk proses *login* dan *register* akun baru. 2. `PaymentController`: untuk melakukan *payment* baru dan melihat histori *payment*. -3. `CallbackController`: untuk *payment callback endpoint* dan *disbursement callback endpoint* yang akan dikontak oleh API Flip. +3. `CallbackController`: untuk *payment callback endpoint* dan *disbursement callback endpoint* yang akan dikontak oleh API [Flip][2]. ## Membuat *Test Suite Class* @@ -132,14 +135,18 @@ Untuk proses pembuatan *unit test*, kita akan memanfaatkan library `Mockito`. Untuk menyusun *test suite* yang support `Mockito`, kita perlu tambahkan anotasi `@ExtendWith(MockitoExtension.class)`. -Selain itu, kita perlu membuat fungsi yang akan dijalankan sebagai *set up* setiap *unit test* pada *test suite*. -Fungsi `setUp()` akan dijalankan **sebelum** setiap *unit test* dijalankan. -Dengan fungsi `setUp()`, kita bisa mengisolasi setiap *unit test* agar hasilnya bisa independen, +Selain itu, kita perlu membuat fungsi `setUp()` dengan anotasi `@BeforeEach`, yang berfungsi sebagai prosedur *set up* untuk setiap *unit test* pada *test suite*. +Fungsi `setUp()` yang dianotasi dengan `@BeforeEach` akan dijalankan **sebelum** setiap *unit test* dijalankan. +Dengan fungsi `setUp()`, kita bisa mengisolasi proses inisiasi setiap *unit test* agar hasilnya bisa independen, selain itu juga meningkatkan *reusability* dan konsistensi antar *test case* karena menggunakan cara inisiasi yang serupa. -Berikut adalah contoh inisiasi *test suite* untuk kelas `PaymentServiceImpl`. -Buat sejajar dengan kelas aslinya, yaitu di *package* `com.example.sibayar.service.payment`: +Berikut adalah contoh inisiasi *test suite* untuk *class* `PaymentServiceImpl`, yaitu *class* `PaymentServiceImplTest` yang dibuat di *folder* `src/test/com/example/sibayar/service/payment`: + ```java +package com.example.sibayar.service.payment; + +// ... import dependensi yang dibutuhkan untuk test + @ExtendWith(MockitoExtension.class) class PaymentServiceImplTest { @@ -161,73 +168,88 @@ class PaymentServiceImplTest { @BeforeEach void setUp() { paymentToOtherRequest = PaymentToOtherRequest.builder() - .destinationName("Pak Bambang") - .destinationBankCode("bca") - .destinationAccountNumber("123456789") - .amount(50000) - .build(); + .destinationName("Pak Bambang") + .destinationBankCode("bca") + .destinationAccountNumber("123456789") + .amount(50000) + .build(); paymentToUserRequest = PaymentToUserRequest.builder() - .destinationUserId(2) - .amount(50000) - .build(); + .destinationUserId(2) + .amount(50000) + .build(); paymentLinkResponse = PaymentLinkResponse.builder() - .expiredDate(LocalDateTime.of(2023, 11, 4, 23, 59)) - .linkId(1) - .linkUrl("https://flip.id/bambang") - .build(); + .expiredDate(LocalDateTime.of(2023, 11, 4, 23, 59)) + .linkId(1) + .linkUrl("https://flip.id/bambang") + .build(); payment = Payment.builder() - .id(1) - .sender(user) - .destinationName("Pak Bambang") - .destinationBankCode("bca") - .destinationAccountNumber("123456789") - .amount(50000) - .paymentLinkId(1) - .paymentLinkUrl("https://flip.id/bambang") - .expiredDate(LocalDateTime.of(2023, 11, 4, 23, 59)) - .status(String.valueOf(PaymentStatus.WAITING_PAYMENT)) - .build(); + .id(1) + .sender(user) + .destinationName("Pak Bambang") + .destinationBankCode("bca") + .destinationAccountNumber("123456789") + .amount(50000) + .paymentLinkId(1) + .paymentLinkUrl("https://flip.id/bambang") + .expiredDate(LocalDateTime.of(2023, 11, 4, 23, 59)) + .status(String.valueOf(PaymentStatus.WAITING_PAYMENT)) + .build(); } } ``` Dalam kasus ini, terdapat 3 objek yang akan dibuat objek *mock*/*stub*-nya, yang ditandai dengan anotasi `@Mock`: -1. `PaymentRepository`: repositori untuk Payment, diperlukan untuk operasi *database* terkait entri `Payment`. -2. `UserRepository`L repositori untuk Payment, diperlukan untuk operasi *database* terkait entri `User`. -3. `User`: objek data User (pengguna). + +1. `PaymentRepository`: sebuah *class* yang bertugas untuk melakukan operasi *database* terhadap tabel `Payment`. Di Spring Boot, *class* ini disebut sebagai *repository*. +2. `UserRepository`: sebuah *class* yang bertugas untuk melakukan operasi *database* terhadap tabel `User`. Di Spring Boot, *class* ini disebut sebagai *repository*. +3. `User`: sebuah *class* yang bertugas sebagai *database model* untuk tabel User (pengguna). Ketiga objek ini kemudian akan di-*inject* ke `PaymentServiceImpl` yang akan kita test, ditandai dengan anotasi `@InjectMocks`. -Terdapapt juga 2 objek yang akan menjadi parameter dari *fungsi* yang akan di-*test*, yaitu: -1. `PaymentToUserRequest`: *Data Transfer Object* (DTO) sebagai *parameter* fungsi `payToUser`, yang datang dari `PaymentController`. -2. `PaymentToOtherRequest`: *Data Transfer Object* (DTO) sebagai *parameter* fungsi `payToOtherDestination`, yang datang dari `PaymentController`. +Terdapat juga 2 objek yang akan menjadi parameter dari *fungsi* yang akan di-*test*, yaitu: + +1. `PaymentToUserRequest`: sebuah *Data Transfer Object* (DTO) sebagai argumen dari fungsi `payToUser`, yang datang dari `PaymentController`. +2. `PaymentToOtherRequest`: sebuah *Data Transfer Object* (DTO) sebagai argumen dari fungsi `payToOtherDestination`, yang datang dari `PaymentController`. Terdapat juga 2 objek yang akan menjadi hasil dari *stub*, yaitu: -1. `Payment`: objek data Payment. -2. `PaymentLinkResponse`: *Data Transfer Object* (DTO) untuk menampung hasil kembalian dari Flip API ketika membuat *payment link*. -### Tugas Anda -- [ ] Silakan *copy* snippet kode yang telah dijelaskan ke dalam project Anda. +1. `Payment`: sebuah objek *database model* untuk tabel Payment. +2. `PaymentLinkResponse`: sebuah objek *Data Transfer Object* (DTO) untuk menampung hasil kembalian dari Flip API ketika membuat *payment link*. -### Latihan Mandiri: Inisiasi *test suite* `CallbackServiceImpl` -- [ ] Buat *test suite* `CallbackServiceImpl`, sejajar dengan *test suite* `PaymentServiceImpl` yang telah dibuat. -- [ ] *Test suite* terdiri dari objek *mock/stub* berikut: - 1. `PaymentRepositoryImpl` -- [ ] *Test suite* terdiri dari objek untuk parameter fungsi yang di-*test* berikut: - 1. `PaymentCallbackRequest` - 2. `DisbursementCallbackRequest` -- [ ] *Test suite* terdiri dari objek *hasil stub* berikut: - 1. `DisbursementResponse` -- [ ] Buat fungsi `setUp()` untuk menyusun objek-objek *hasil stub*. +### Tugas Anda +- [ ] Buat *test suite* `PaymentServiceImplTest` sesuai dengan arahan yang diberikan. + - [ ] *Test suite* terdiri dari objek *mock/stub* berikut: + - `PaymentRepository` + - `UserRepository` + - `User` + - [ ] *Test suite* terdiri dari objek untuk parameter fungsi yang di-*test* berikut: + - `PaymentToUserRequest` + - `PaymentToOtherRequest` + - [ ] *Test suite* terdiri dari objek *hasil stub* berikut: + - `Payment` + - `PaymentLinkResponse` + - [ ] Buat fungsi `setUp()` untuk menyusun objek-objek *hasil stub*. + +### Latihan Mandiri: Inisiasi *test suite* `CallbackServiceImplTest` +- [ ] Buat *test suite* `CallbackServiceImplTest`, sejajar dengan *test suite* `PaymentServiceImplTest` yang telah dibuat. + - [ ] *Test suite* terdiri dari objek *mock/stub* berikut: + - `PaymentRepository` + - [ ] *Test suite* terdiri dari objek untuk parameter fungsi yang di-*test* berikut: + - `PaymentCallbackRequest` + - `DisbursementCallbackRequest` + - [ ] *Test suite* terdiri dari objek *hasil stub* berikut: + - `Payment` + - `DisbursementResponse` + - [ ] Buat fungsi `setUp()` untuk menyusun objek-objek *hasil stub*. ## Melakukan *Mock* dan *Stub* untuk Akses Database dan Helper Function Lain -SIBAYAR menggunakan Spring Data JPA untuk mengakases database In-Memory H2. +SIBAYAR menggunakan Spring Data JPA untuk mengakses database In-Memory H2. Dalam menggunakan Spring Data JPA, kita perlu membuat *repository interface* yang berisikan daftar *method* untuk mengakses *database*. JPA kemudian akan membuatkan implementasi setiap *method* secara *on the fly* sesuai dengan nama *method* yang kita gunakan. *Repository interface* tersebut akan menjadi sebuah komponen Spring yang bisa digunakan untuk *service* yang akan kita buat bersama. -Di tutorial hari ini, sudah tersedia *repository* untuk objek `Payment` dan objek `User`. +Di tutorial hari ini, sudah tersedia *repository* untuk tabel *database* `Payment` yaitu `PaymentRepository`, dan tabel *database* `User` yaitu `UserRepository`. *Database* adalah komponen dependensi pada objek *service* yang perlu kita isolasi. *Programmer* pada umumnya akan membuat entri ke *database* lalu akan menghapusnya kembali ketika test selesai. @@ -235,7 +257,7 @@ Akan tetapi, hal tersebut jadi memakan *resource* lebih dengan perlu adanya *tes Oleh karena itu, dalam menyusun *unit test* untuk *service*, kita perlu melakukan *mock* dan *stub* komponen *Repository*. Sebagai contoh, berikut adalah beberapa *test case* yang bisa Anda gunakan: -### `payToUser` sukses menyimpan dan mengembalikan objek `Payment` baru +### Contoh 1: Fungsi `payToUser` sukses menyimpan dan mengembalikan objek `Payment` baru ```java @Test void testPayToUserSuccess() { @@ -253,14 +275,18 @@ Sebagai contoh, berikut adalah beberapa *test case* yang bisa Anda gunakan: } ``` -Terlihat bahwa terdapat *stubbing* untuk fungsi `userRepository.findById(Integer)` untuk menyimulasikan bahwa di database terdapat objek *mock* `user`. -Selain itu, juga terdapat *stubbing* untuk fungsi `service.getPaymentLink(PaymentLinkRequest)` untuk mengembalikan objek `paymentLinkResponse`. +Berikut adalah penjelasan terkait *test case* ini: + +1. Di line 3, terdapat *stubbing* untuk fungsi `userRepository.findById(Integer)` untuk menyimulasikan bahwa di database terdapat objek *mock* `user`. +2. Di line 4, terdapat *stubbing* untuk fungsi `service.getPaymentLink(PaymentLinkRequest)` untuk mengembalikan objek `paymentLinkResponse`, untuk menyimulasikan kembalian dari pemanggilan API Flip untuk mendapatkan *payment link*. + *Test case* ini akan mengecek: -1. Apakah fungsi `payToUser` memanggil *helper function* `getPaymentLink` untuk akses API Flip? -2. Apakah fungsi `payToUser` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan objek `Payment` ke dalam database? + +1. Apakah fungsi `payToUser` memanggil **setidaknya satu kali** *helper function* `getPaymentLink` untuk akses API Flip? (sintaks verifikasi pemanggilan *mock* ada di line 8) +2. Apakah fungsi `payToUser` memanggil **setidaknya satu kali** fungsi `save` pada `PaymentRepository` untuk menyimpan objek `Payment` ke dalam database? (sintaks verifikasi pemanggilan *mock* ada di line 9) 3. Apakah fungsi `payToUser` mengembalikan objek `Payment`, dengan isi yang sama seperti yang dikembalikan oleh API Flip? -### `paymentCallback` sukses menyimpan status `WAITING_DISBURSEMENT` ketika status Payment Link `"SUCCESSFUL"` dan status Disbursement `"PENDING"` +### Contoh 2: Fungsi `paymentCallback` sukses menyimpan status `WAITING_DISBURSEMENT` ketika status Payment Link `"SUCCESSFUL"` dan status Disbursement `"PENDING"` ```java @Test void testPaymentCallbackWithSuccessfulStatusAndPendingDisbursement() { @@ -280,16 +306,20 @@ Selain itu, juga terdapat *stubbing* untuk fungsi `service.getPaymentLink(Paymen Fungsi `paymentCallback` bertujuan untuk meneruskan pembayaran lewat mekanisme *Disbursement* jika status Payment Link yang diberikan `"SUCCESSFUL"`. -Terlihat bahwa terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk menyimulasikan bahwa di database terdapat objek `payment`. -Selain itu, juga terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk mengembalikan objek `paymentLinkResponse`. -Selain itu, kita juga perlu *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`. -Selain itu, kita juga perlu *set status* pada objek `disbursementResponse` menjadi `"PENDING"` untuk menyimulasikan API Flip sedang melakukan proses *disbursement*. +Berikut adalah penjelasan terkait *test case* ini: + +1. Di line 3, terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk menyimulasikan bahwa di database terdapat objek `payment`. +2. Di line 4, dilakukan *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`, untuk menyimulasikan API Flip memanggil *payment callback* dengan status "sukses" sehingga proses *disbursement* bisa dilakukan. +3. Di line 5, terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk mengembalikan objek `paymentLinkResponse`. +4. Di line 6, dilakukan *set status* pada objek `disbursementResponse` menjadi `"PENDING"` untuk menyimulasikan API Flip sedang melakukan proses *disbursement*. + *Test case* ini akan mengecek: -1. Apakah fungsi `paymentCallback` memanggil *helper function* `disburseMoney` untuk akses API Flip? -2. Apakah fungsi `paymentCallback` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? + +1. Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** *helper function* `disburseMoney` untuk akses API Flip? (sintaks verifikasi pemanggilan *mock* ada di line 10) +2. Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? (sintaks verifikasi pemanggilan *mock* ada di line 11) 3. Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"WAITING_DISBURSEMENT"`? -### `paymentCallback` sukses menyimpan status `WAITING_DISBURSEMENT` ketika status Payment Link `"SUCCESSFUL"` dan status Disbursement `"DONE"` +### Contoh 3: Fungsi `paymentCallback` sukses menyimpan status `WAITING_DISBURSEMENT` ketika status Payment Link `"SUCCESSFUL"` dan status Disbursement `"DONE"` ```java @Test void testPaymentCallbackWithSuccessfulStatusAndSuccessfulDisbursement() { @@ -307,52 +337,63 @@ Selain itu, kita juga perlu *set status* pada objek `disbursementResponse` menja } ``` -Terlihat bahwa terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk menyimulasikan bahwa di database terdapat objek `payment`. -Selain itu, juga terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk mengembalikan objek `paymentLinkResponse`. -Selain itu, kita juga perlu *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`. -Selain itu, kita juga perlu *set status* pada objek `disbursementResponse` menjadi `"DONE"` untuk menyimulasikan API Flip langsung selesai melakukan *disbursement*. +Berikut adalah penjelasan terkait *test case* ini: + +1. Di line 3, terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk menyimulasikan bahwa di database terdapat objek `payment`. +2. Di line 4, dilakukan *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`, untuk menyimulasikan API Flip memanggil *payment callback* dengan status "sukses" sehingga proses *disbursement* bisa dilakukan. +3. Di line 5, terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk mengembalikan objek `paymentLinkResponse`. +4. Di line 6, dilakukan *set status* pada objek `disbursementResponse` menjadi `"DONE"`, untuk menyimulasikan API Flip langsung selesai melakukan *disbursement*. + *Test case* ini akan mengecek: -1. Apakah fungsi `paymentCallback` memanggil *helper function* `disburseMoney` untuk akses API Flip? -2. Apakah fungsi `paymentCallback` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? + +1. Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** *helper function* `disburseMoney` untuk akses API Flip? (sintaks verifikasi pemanggilan *mock* ada di line 10) +2. Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? (sintaks verifikasi pemanggilan *mock* ada di line 11) 3. Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"SUCCESS"`? ### Tugas Anda -- [ ] Silakan *copy* semua snippet kode yang telah dijelaskan ke dalam project Anda ke tempat yang sesuai. - - `testPayToUserSuccess` diletakkan di `PaymentServiceImplTest`. - - `testPaymentCallbackWithSuccessfulStatusAndPendingDisbursement` diletakkan di `CallbackServiceImplTest`. - - `testPaymentCallbackWithSuccessfulStatusAndSuccessfulDisbursement` diletakkan di `CallbackServiceImplTest`. - -### Latihan Mandiri: Buat *positive case* +- [ ] Buat *test case* `testPayToUserSuccess` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di dalam *test suite* `com.example.sibayar.service.payment.PaymentServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. +- [ ] Buat *test case* `testPaymentCallbackWithSuccessfulStatusAndPendingDisbursement` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di `com.example.sibayar.service.payment.CallbackServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. +- [ ] Buat *test case* `testPaymentCallbackWithSuccessfulStatusAndSuccessfulDisbursement` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di `com.example.sibayar.service.payment.CallbackServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. + +### Latihan Mandiri: Buat sebuah *positive case* - [ ] Buat *test case* `testPayToOtherSuccess` pada *test suite* `PaymentServiceImplTest` untuk mengecek: - 1. Apakah fungsi `payToOtherDestination` memanggil *helper function* `getPaymentLink` untuk akses API Flip? - 2. Apakah fungsi `payToOtherDestination` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan objek `Payment` ke dalam database? - 3. Apakah fungsi `payToOtherDestination` mengembalikan objek `Payment`, dengan isi yang sama seperti yang dikembalikan oleh API Flip? + - [ ] Apakah fungsi `payToOtherDestination` memanggil *helper function* `getPaymentLink` untuk akses API Flip? + - [ ] Apakah fungsi `payToOtherDestination` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan objek `Payment` ke dalam database? + - [ ] Apakah fungsi `payToOtherDestination` mengembalikan objek `Payment`, dengan isi yang sama seperti yang dikembalikan oleh API Flip? -### Latihan Mandiri: Buat *negative case* +### Latihan Mandiri: Buat beberapa *negative case* - [ ] Buat *test case* `testPaymentCallbackWithSuccessfulStatusButCancelledDisbursement` pada *test suite* `CallbackServiceImplTest` untuk mengecek: - 1. Apakah fungsi `paymentCallback` memanggil *helper function* `getPaymentLink` untuk akses API Flip? - 2. Apakah fungsi `paymentCallback` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? - 3. Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"DISBURSEMENT_FAILED"`? - - **CATATAN**: `status` pada `disbursementResponse` harus diganti dengan `"CANCELLED"`. + - [ ] Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** *helper function* `getPaymentLink` untuk akses API Flip? + - [ ] Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? + - [ ] Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"DISBURSEMENT_FAILED"`? + - **CATATAN**: `status` pada `disbursementResponse` harus diganti dengan `"CANCELLED"`. - [ ] Buat *test case* `testPaymentCallbackWithCancelledStatus` pada *test suite* `CallbackServiceImplTest` untuk mengecek: - 1. Apakah fungsi `paymentCallback` **TIDAK** memanggil *helper function* `getPaymentLink` untuk akses API Flip?<br /> + - [ ] Apakah fungsi `paymentCallback` **TIDAK** memanggil *helper function* `getPaymentLink` untuk akses API Flip?<br /> **HINT**: gunakan ```java verify(service, atMost(0)).disburseMoney(any(DisbursementRequest.class)) ``` untuk mengecek bahwa *helper function* tidak dipanggil. - 2. Apakah fungsi `paymentCallback` memanggil fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? - 3. Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"PAYMENT_FAILED"`? - - **CATATAN**: `status` pada `paymentCallbackRequest` harus diganti dengan `"CANCELLED"`. + - [ ] Apakah fungsi `paymentCallback` memanggil **setidaknya satu kali** fungsi `save` pada `PaymentRepository` untuk menyimpan perubahan objek `Payment` ke dalam database? + - [ ] Apakah fungsi `paymentCallback` mengembalikan objek `Payment` dengan `status` berupa `"PAYMENT_FAILED"`? + - **CATATAN**: `status` pada `paymentCallbackRequest` harus diganti dengan `"CANCELLED"`. ## Menguji Apakah Fungsi Mengeluarkan *Exception* dalam Suatu *Test Case* *Unit test* tidak hanya mencakup *positive case* (dalam kasus ini: mengembalikan objek `Payment`), akan tetapi juga perlu mencakup *negative case* (dalam kasus ini: mengeluarkan sebuah *exception*). + +Untuk mengecek apakah aplikasi mengeluarkan *exception*, kita bisa memanfaatkan fungsi `assertThrows`. Sebagai contoh, berikut adalah beberapa *negative case* yang bisa Anda gunakan: -### `payToUser` pada `PaymentServiceImpl` akan mengembalikan *error* ketika user ID dari *sender* dan *destination* sama. +### Contoh 1: `payToUser` pada `PaymentServiceImpl` akan mengembalikan *error* ketika user ID dari *sender* dan *destination* sama. ```java @Test void testPayToUserFailWhenSenderAndDestinationAreTheSame() { @@ -364,7 +405,7 @@ Sebagai contoh, berikut adalah beberapa *negative case* yang bisa Anda gunakan: *Test case* ini akan mengecek apakah *exception* `SelfPaymentException` dikeluarkan jika user ID dari *sender* dan *destination* sama. -### `payToUser` pada `PaymentServiceImpl` akan mengembalikan *error* jika Flip API sedang tidak bisa diakses. +### Contoh 2: `payToUser` pada `PaymentServiceImpl` akan mengembalikan *error* jika Flip API sedang tidak bisa diakses. ```java @Test void testPayToUserThrowsExceptionWhenAPIIsUnreachable() { @@ -378,13 +419,17 @@ Sebagai contoh, berikut adalah beberapa *negative case* yang bisa Anda gunakan: } ``` -Terlihat bahwa terdapat *stubbing* untuk fungsi `userRepository.findById(Integer)` untuk mengembalikan objek *mock* `user`. -Selain itu, juga terdapat *stubbing* untuk fungsi `service.getPaymentLink(PaymentLinkRequest)` untuk melempar *exception* `APIUnreachableException`. +Berikut adalah penjelasan mengenai *stubbing* pada *test case* ini: + +1. Di line 3, terdapat *stubbing* untuk fungsi `userRepository.findById(Integer)` untuk mengembalikan objek *mock* `user`. +2. Di line 4, terdapat *stubbing* untuk fungsi `service.getPaymentLink(PaymentLinkRequest)` untuk melempar *exception* `APIUnreachableException`. + *Test case* ini akan mengecek: -1. Apakah fungsi `payToUser` meneruskan *exception* `APIUnreachableException`? -2. Apakah fungsi `payToUser` memanggil *helper function* `getPaymentLink` untuk akses API Flip? -### `paymentCallback` pada `CallbackServiceImpl` akan mengembalikan *error* jika pembayaran lewat payment link sukses, namun Flip API untuk *disbursement* sedang tidak bisa diakses. +1. Apakah fungsi `payToUser` meneruskan *exception* `APIUnreachableException`? (pengecekan di line 6) +2. Apakah fungsi `payToUser` memanggil *helper function* `getPaymentLink` untuk akses API Flip? (sintaks verifikasi pemanggilan *mock* ada di line 9) + +### Contoh 3: `paymentCallback` pada `CallbackServiceImpl` akan mengembalikan *error* jika pembayaran lewat payment link sukses, namun Flip API untuk *disbursement* sedang tidak bisa diakses. ```java @Test void testPaymentCallbackWithSuccessfulStatusThrowsExceptionWhenAPIIsUnreachable() { @@ -399,25 +444,35 @@ Selain itu, juga terdapat *stubbing* untuk fungsi `service.getPaymentLink(Paymen } ``` -Terlihat bahwa terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk mengembalikan objek `payment`. -Selain itu, juga terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk melempar *exception* `APIUnreachableException`. -Selain itu, kita juga perlu *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`, -karena akses API Flip untuk *disbursement* hanya akan diakses jika status *payment link* sudah `SUCCESSFUL`. +Berikut adalah penjelasan mengenai *stubbing* pada *test case* ini: + +1. Di line 3, terdapat *stubbing* untuk fungsi `paymentRepository.findByPaymentLinkId(Integer)` untuk mengembalikan objek `payment`. +2. Di line 4, dilakukan *set status* pada objek `paymentCallbackRequest` menjadi `"SUCCESSFUL"`, + karena akses API Flip untuk *disbursement* hanya akan diakses jika status *payment link* sudah `SUCCESSFUL`. +3. Di line 5, Selain itu, juga terdapat *stubbing* untuk fungsi `service.disburseMoney(DisbursementRequest)` untuk melempar *exception* `APIUnreachableException`. + Ini untuk menyimulasikan ketika API Flip sedang tidak bisa diakses. + *Test case* ini akan mengecek: -1. Apakah fungsi `payToUser` meneruskan *exception* `APIUnreachableException`? -2. Apakah fungsi `payToUser` memanggil *helper function* `disburseMoney` untuk akses API Flip? + +1. Apakah fungsi `payToUser` meneruskan *exception* `APIUnreachableException`? (pengecekan di line 8) +2. Apakah fungsi `payToUser` memanggil *helper function* `disburseMoney` untuk akses API Flip? (sintaks verifikasi pemanggilan *mock* ada di line 11) ### Tugas Anda -- [ ] Silakan *copy* semua snippet kode yang telah dijelaskan ke dalam project Anda ke tempat yang sesuai. - - `testPayToUserFailWhenSenderAndDestinationAreTheSame` diletakkan di `PaymentServiceImplTest`. - - `testPayToUserThrowsExceptionWhenAPIIsUnreachable` diletakkan di `PaymentServiceImplTest`. - - `testPaymentCallbackWithSuccessfulStatusThrowsExceptionWhenAPIIsUnreachable` diletakkan di `CallbackServiceImplTest`. +- [ ] Buat *test case* `testPayToUserFailWhenSenderAndDestinationAreTheSame` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di dalam *test suite* `com.example.sibayar.service.payment.PaymentServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. +- [ ] Buat *test case* `testPayToUserThrowsExceptionWhenAPIIsUnreachable` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di `com.example.sibayar.service.payment.PaymentServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. +- [ ] Buat *test case* `testPaymentCallbackWithSuccessfulStatusThrowsExceptionWhenAPIIsUnreachable` sesuai dengan arahan yang sudah diberikan. + - [ ] *Test case* diletakkan di `com.example.sibayar.service.payment.CallbackServiceImplTest`. + - [ ] Pastikan *test case* mengecek tiga hal yang disebutkan di arahan. ### Latihan Mandiri: Buat *negative case* - [ ] Buat *test case* `testPayToOtherThrowsExceptionWhenAPIIsUnreachable` pada *test suite* `PaymentServiceImplTest` untuk mengecek: - 1. Apakah fungsi `payToOtherDestination` meneruskan *exception* `APIUnreachableException`? - 2. Apakah fungsi `payToOtherDestination` menjalankan *helper function* `getPaymentLink` untuk akses API Flip? + - [ ] Apakah fungsi `payToOtherDestination` meneruskan *exception* `APIUnreachableException`? + - [ ] Apakah fungsi `payToOtherDestination` memanggil **setidaknya satu kali** *helper function* `getPaymentLink` untuk akses API Flip? ## *Refactoring*: Bagaimana jika SIBAYAR bisa menggunakan lebih dari satu Payment Gateway? @@ -427,76 +482,98 @@ Bagaimana jika suatu hari kita tidak menggunakan Flip sebagai *payment gateway*? Salah satu cara yang dapat kita lakukan adalah memisahkan *helper function* `getPaymentLink` dan `disburseMoney` menjadi sebuah *class* tersendiri di bawah package `com.example.sibayar.external.paymentgateway`. Lalu, bagaimana cara kita menyesuaikan implementasi dan *unit test* kita ketika ada perubahan desain tersebut? +Pada bagian ini, kita akan melakukan proses *refactoring* beserta penyesuaian *unit test* yang perlu dilakukan. + ### Tugas Anda -- [ ] Buat interface baru `PaymentGatewayAPI`, dengan menggunakan *snippet* berikut: - ```java - public interface PaymentGatewayAPI { - PaymentLinkResponse getPaymentLink(PaymentLinkRequest request); - DisbursementResponse disburseMoney(DisbursementRequest request); - } - ``` -- [ ] Buat class baru `FlipAPI`, dengan menggunakan *snippet* berikut: - ```java - @Service("flipAPI") - @RequiredArgsConstructor - public class FlipAPI implements PaymentGatewayAPI { - @Value("${sibayar.flip.baseUrl}") - private String baseUrl; - @Value("${sibayar.flip.apiKey}") - private String apiKey; - private HttpClient client = HttpClient.newHttpClient(); - - public PaymentLinkResponse getPaymentLink(PaymentLinkRequest request) { - // TODO: Pindahkan isi fungsi getPaymentLink di PaymentServiceImpl ke sini. - } - - public DisbursementResponse disburseMoney(DisbursementRequest request) { - // TODO: Pindahkan isi fungsi disburseMoney di CallbackServiceImpl ke sini. - } - - private String getBasicAuthHeader(String username, String password) { - String valueToEncode = username + ":" + password; - return "Basic " + Base64.getEncoder() - .encodeToString(valueToEncode.getBytes()); - } - } - ``` -- [ ] Pada `PaymentServiceImpl` dan `CallbackServiceImpl`, buat koneksi baru ke `PaymentGatewayAPI` dengan menggunakan *snippet* berikut: - ```java - @Qualifier("flipAPI") - private final PaymentGatewayAPI api; - ``` -- [ ] Gunakan `api` untuk mengakses fungsi `getPaymentLink` dan `disburseMoney` yang telah dipindahkan. +- [ ] Buat *interface* baru `PaymentGatewayAPI` di package `com.example.sibayar.external.paymentgateway`, dengan menggunakan *snippet* berikut: + ```java + public interface PaymentGatewayAPI { + PaymentLinkResponse getPaymentLink(PaymentLinkRequest request); + DisbursementResponse disburseMoney(DisbursementRequest request); + } + ``` + Tujuan dari *interface* `PaymentGatewayAPI` adalah untuk memastikan bahwa semua *class* penghubung dengan API *payment gateway* dapat diakses dengan cara yang sama. +- [ ] Buat *class* baru `FlipAPI` di packakge `com.example.sibayar.external.paymentgateway`, dengan menggunakan *snippet* berikut: + ```java + @Service("flipAPI") + @RequiredArgsConstructor + public class FlipAPI implements PaymentGatewayAPI { + @Value("${sibayar.flip.baseUrl}") + private String baseUrl; + @Value("${sibayar.flip.apiKey}") + private String apiKey; + private HttpClient client = HttpClient.newHttpClient(); + + public PaymentLinkResponse getPaymentLink(PaymentLinkRequest request) { + // TODO: Pindahkan isi fungsi getPaymentLink di PaymentServiceImpl ke sini. + } + + public DisbursementResponse disburseMoney(DisbursementRequest request) { + // TODO: Pindahkan isi fungsi disburseMoney di CallbackServiceImpl ke sini. + } + + private String getBasicAuthHeader(String username, String password) { + String valueToEncode = username + ":" + password; + return "Basic " + Base64.getEncoder() + .encodeToString(valueToEncode.getBytes()); + } + } + ``` + Lakukan juga beberapa hal berikut: + + - [ ] Pindahkan juga isi *method* `getPaymentLink` yang sebelumnya ada di `com.example.sibayar.service.payment.PaymentServiceImpl`, ke dalam *method* `getPaymentLink` yang ada di `FlipAPI`. + - [ ] Pindahkan juga isi *method* `disburseMoney` yang sebelumnya ada di `com.example.sibayar.service.payment.CallbackServiceImpl`, ke dalam *method* `getPaymentLink` yang ada di `FlipAPI`. + +- [ ] Pada `PaymentServiceImpl` dan `CallbackServiceImpl`, buat koneksi baru ke implementasi dari `PaymentGatewayAPI` dengan cara membuat *instance variable* baru. Gunakan *snippet* berikut untuk diletakkan di definisi *class* dari `PaymentServiceImpl` dan `CallbackServiceImpl`. + ```java + @Qualifier("flipAPI") + private final PaymentGatewayAPI api; + ``` + `@Qualifier("flipAPI")` akan otomatis melakukan *dependency injection* sehingga variabel `api` akan berisi objek dari `FlipAPI`. +- [ ] Gunakan `api` untuk mengakses fungsi `getPaymentLink` dan `disburseMoney` yang telah dipindahkan ke `FlipAPI`. Misal dari sebelumnya: + ```java + PaymentLinkResponse apiResponse = getPaymentLink(apiRequest); + ``` + menjadi seprti berikut: + ```java + PaymentLinkResponse apiResponse = api.getPaymentLink(apiRequest); + ``` - [ ] Tambahkan objek *mock* untuk `PaymentGatewayAPI` pada *test suite* `PaymentServiceImplTest` dan `CallbackServiceImplTest` dengan menggunakan *snippet* berikut: - ```java - @Mock - private PaymentGatewayAPI flipAPI; - ``` -- [ ] Gunakan objek *mock* `flipAPI` untuk menggantikan pemanggilan fungsi `getPaymentLink` dan `disburseMoney` pada setiap `test case`. Misal: - ```java - when(service.disburseMoney(any(DisbursementRequest.class))).thenReturn(disbursementResponse); - // ... - verify(service, atLeastOnce()).disburseMoney(any(DisbursementRequest.class)); - ``` - menjadi seperti berikut: - ```java - when(flipAPI.disburseMoney(any(DisbursementRequest.class))).thenReturn(disbursementResponse); - // ... - verify(flipAPI, atLeastOnce()).disburseMoney(any(DisbursementRequest.class)); - ``` - -## Latihan Mandiri Tambahan: -- [ ] Lengkapi semua *test case* hingga Line Coverage menyentuh 100%. -- [ ] Buat kode *test case* yang *meaningful* dan *thorough*. + ```java + @Mock + private PaymentGatewayAPI flipAPI; + ``` +- [ ] Gunakan objek *mock* `flipAPI` untuk menggantikan pemanggilan fungsi `getPaymentLink` dan `disburseMoney` pada setiap *test case*. Misal dari sebelumnya: + ```java + when(service.disburseMoney(any(DisbursementRequest.class))).thenReturn(disbursementResponse); + // ... + verify(service, atLeastOnce()).disburseMoney(any(DisbursementRequest.class)); + ``` + menjadi seperti berikut: + ```java + when(flipAPI.disburseMoney(any(DisbursementRequest.class))).thenReturn(disbursementResponse); + // ... + verify(flipAPI, atLeastOnce()).disburseMoney(any(DisbursementRequest.class)); + ``` + +## Latihan Mandiri Tambahan +- [ ] Lengkapi semua *test case* hingga *Line Coverage* menyentuh 100%. +- [ ] Buat kode *test case* yang *meaningful* dan *thorough*. Cek apakah dependensi eksternal seperti *repository* atau *payment gateway* API dipanggil sesuai kebutuhan setiap *test case*. +- [ ] Integrasikan *project* Anda dengan SonarQube.<br /> + Contoh *project* SIBAYAR yang sudah memenuhi *Line Coverage* 100%: +  ## Penutup Kita sudah bersama-sama membuat *unit test* untuk Service, lengkap dengan cara menggunakan *mock* dan *stub*. Untuk bahan diskusi saat refleksi: -- [ ] Apakah Line Coverage 100% menjamin tidak ada bug? -- [ ] Bagaimana jika kita langsung melakukan modifikasi *database* atau mengakses langsung *library* atau API eksternal saat kita melakukan *unit test*? Apa dampaknya bagi konsistensi hasil dari *unit test*? + +- [ ] Apakah *Line Coverage* 100% menjamin tidak ada *bug*? Apakah *Line Coverage* 100% menjamin aspek **FIRST *principle*** terutama aspek ***Thorough***? +- [ ] Bagaimana jika kita langsung melakukan modifikasi *database* atau mengakses langsung *library* atau API eksternal saat kita melakukan *unit test*? Apa dampaknya bagi konsistensi hasil dari *unit test*? Apa dampaknya bagi **FIRST *principle*** pada *unit test* yang dibuat, terutama aspek ***Fast***, ***Isolated***, dan ***Repeatable***? - [ ] Apa kesulitan yang dialami Bapak/Ibu ketika menjalani tutorial ini? +Untuk hari ketiga, kita akan mendalami mengenai Functional Test dan Behaviour-Driven Development (BDD). [1]: https://docs.google.com/presentation/d/1f1vpyYOu3GSyIeyqGLU-D6REBn0ACN81?rtpof=true&usp=drive_fs +[2]: https://docs.flip.id/ diff --git a/docs/workshops/images/day_2_tdd_-_sonarqube_sibayar.png b/docs/workshops/images/day_2_tdd_-_sonarqube_sibayar.png new file mode 100644 index 0000000000000000000000000000000000000000..25a4475c93314ce884dfcdcc51c87492b9ffd3f9 GIT binary patch literal 55009 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 N*3;F`Wt~$(69DJBsBr)Q literal 0 HcmV?d00001 -- GitLab