0% menganggap dokumen ini bermanfaat (0 suara)
12 tayangan53 halaman

Testing

Hak Cipta
© © All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai DOCX, PDF, TXT atau baca online di Scribd
0% menganggap dokumen ini bermanfaat (0 suara)
12 tayangan53 halaman

Testing

Hak Cipta
© © All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai DOCX, PDF, TXT atau baca online di Scribd
Anda di halaman 1/ 53

Pengenalan Testing

Testing atau pengujian merupakan bagian terpenting dari sebuah


pengembangan aplikasi, terutama untuk memastikan kode Anda terukur
dan mudah dipelihara (maintenance) di kemudian hari. Pengujian dalam
pengembangan aplikasi memiliki dua tujuan, antara lain:

 Mendapatkan informasi mengenai kualitas dari aplikasi tersebut.


 Memastikan apakah aplikasi sudah berjalan sesuai kebutuhan.

Dengan melakukan pengujian komprehensif terhadap fitur-fitur aplikasi,


diharapkan kita bisa mendapatkan pandangan mengenai aplikasi secara
objektif. Selain itu, dengan terpenuhinya kriteria aplikasi pada tahap
pengujian, aplikasi dapat dinyatakan aman dari bug dan dapat
didistribusikan, misal ke Google Play Store ataupun didistribusikan secara
tertutup di lingkungan perusahaan.

Tahapan testing bisa dilakukan oleh seorang tester secara manual


dengan menjalankan semua proses yang ada di aplikasi dan memastikan
seluruh fungsionalitasnya berjalan lancar. Selain itu, ada mekanisme lain
dalam melakukan testing, yakni testing secara otomatis tanpa
mengandalkan tester manual. Proses ini biasa dikenal dengan nama
Pengujian Otomatis (Automation Testing).

Tahap pengujian aplikasi ini mirip dengan seorang kontrol kualitas


(quality control) dalam sebuah pabrik memastikan produk minim cacat
produksi dan siap dikemas. Dalam industri manufaktur, mereka
menggunakan istilah zero defects, di mana semua hasil produksi harus
sesuai dengan spesifikasi yang telah ditentukan.
Zero defects lebih efektif untuk dicapai dengan adanya robot. Robot
tersebut memiliki tangan dan sensor canggih untuk membantu para
kontrol kualitas dalam memastikan spesifikasi produk.

Di dunia perangkat lunak, tahap pengujian dilakukan seperti halnya


manufaktur pabrik tersebut. Para software engineer akan membuat
dokumen User Acceptance Criteria yang berisi semua spesifikasi yang
diharapkan oleh pengguna (user). Biasanya kriteria tersebut disertai
dengan tingkat kebutuhan, seperti sangat penting, penting, dan lebih baik
jika ada (nice to have). Dari dokumen tersebut akan muncul User
Acceptance Testing, di mana berisi spesifikasi yang telah disetujui oleh
developer dan pembuat produk/aplikasi.

Sama halnya dengan manufaktur, dunia perangkat lunak pun memiliki


robot-robot dengan tangan dan sensor canggih. Robot tersebut adalah
sistem pengujian otomatis (Automation Testing). Pengujian otomatis inilah
yang akan membantu para kontrol kualitas dalam memastikan kualitas
aplikasi yang dikembangkan hingga bisa dipublikasikan.

Pengujian aplikasi bukanlah hal yang mudah karena memiliki disiplin


tersendiri dalam proses pengembangannya. Kegagalan dalam pengujian
aplikasi dapat menyebabkan produk yang dihasilkan tidak berjalan
dengan baik. Selain itu, kegagalan pengujian juga bisa berdampak buruk
pada sisi bisnis. Saat ini hampir setiap perusahaan aplikasi menempatkan
pengujian sebagai hal utama yang wajib dilakukan dalam proses
pengembangan aplikasi.

Dalam dunia Android terdapat test code yang berfungsi untuk menguji
aplikasi. Test code merupakan kumpulan kode untuk melakukan sejumlah
proses pengujian terhadap jalannya aplikasi dan memastikan ia berjalan
sesuai kebutuhan. Sebuah test code terbagi menjadi 2 bagian, yakni Unit
Test dan Instrumentation Test.
Berikut detail dari kedua test code di atas:

1. Unit Test
Unit test adalah tahapan testing yang menguji suatu komponen/unit
dari aplikasi secara individu. Individual komponen/unit di sini bisa
diartikan sebagai suatu class, satu method, atau bahkan satu
module. Lalu, bagaimana caranya jika Anda ingin menguji sebuah
method/fungsi supaya berjalan sesuai rencana? Caranya cukup
mudah, yakni dengan memberikan input dan melihat hasilnya
apakah sesuai dengan ekspektasi atau tidak.

Unit test berfungsi untuk mengisolasi bagian dari program dan


memberikan validasi bahwa ia sudah berjalan lancar. Dengan
mengisolasi bagian program, proses bug finding dapat berjalan
cepat seiring dengan perkembangan aplikasinya.

Biasanya kita bisa membuat unit testing pada direktori module-


name/src/test/java/. Unit testing berjalan pada local JVM dan tidak
mempunyai akses ke API Android Framework.

2. UI Test
UI Test merupakan sebuah mekanisme di mana aplikasi akan diuji
sesuai dengan kondisi user/pengguna ketika berinteraksi pada
sebuah aplikasi. Ia biasanya dihubungkan dengan beberapa
skenario perjalanan pengguna dalam aplikasi. Diharapkan segala
bentuk interaksi pengguna terhadap aplikasi dapat diprediksi pada
ranah UI Test.

Tahap pengujian ini bisa dilakukan dengan beberapa cara. Salah


satunya yaitu membuat skenario yang akan dilakukan pengguna
dalam pengujian tersebut, misalnya mengisi data, menekan tombol,
menggeser layar, dll. Setelah skenario dibuat, aplikasi akan
bergerak sendiri seolah-olah ada pengguna yang berinteraksi
dengan antarmuka. Kemudian, UI Test akan mengawasi bagaimana
tampilan aplikasi merespon setiap interaksi dan memvalidasi setiap
interaksi tersebut.
Kita bisa membuat UI Test pada direktori
module-name/src/androidTest/java/. UI Test merupakan sebuah
pengujian yang berjalan pada perangkat atau emulator dengan
memanfaatkan Android framework APIs dan API pendukung lainnya,
seperti Android Testing Support Library.

UI Test berbeda dengan Unit Test. Jika merasa sulit membedakannya,


simaklah rangkuman berikut, UI Test melakukan pengujian pada UI
yang ada pada aplikasi Android, sedangkan Unit Test melakukan
pengujian pada suatu fungsi-fungsi yang kecil.

Bagaimana? Apakah Anda sudah mulai penasaran cara untuk


mengimplementasikan pengujian ketika mengembangkan aplikasi? Yuk,
lanjut ke materi selanjutnya untuk mempelajarinya. Selamat belajar!
Teori Unit Test

Unit Test merupakan sebuah pengujian yang memvalidasi unit kode


secara individual. Tujuan dari unit test adalah memastikan setiap unit
perangkat lunak dapat berjalan sesuai fungsi yang sudah ditentukan.
Telah disebutkan sebelumnya bahwa di dalam unit test, kita tidak
memerlukan perangkat Android atau emulator untuk menjalankan
pengujian, melainkan IDE (Android Studio) saja. Kemudian hasil dari
pengujian akan ditampilkan pada konsol Android Studio.

Unit test berfungsi untuk menguji logika bisnis dalam sebuah aplikasi.
Dengan demikian kita harus menuliskannya hanya untuk menguji fungsi
kecil/unit kode demi memastikan apakah logika kerjanya sudah sesuai
dengan yang diharapkan. Misalnya, menguji apakah hasil dari (3 x 3)
sama dengan 9.

Kita akan menggunakan library JUnit untuk melakukan unit test. Library
ini secara otomatis sudah ditambahkan ketika kita membuat proyek baru
pada Android Studio. JUnit hanya digunakan untuk menjalankan tes,
sehingga ia tidak akan di-compile ketika aplikasi dijalankan pada
perangkat Android atau emulator. Tentunya ini bisa mengurangi ukuran
dari APK.

1. testImplementation 'junit:junit:4.12'

Okay, mari kita coba untuk melakukan pengujian sederhana


menggunakan JUnit pada sebuah logika kode. Anggap saja Anda telah
memiliki sebuah kelas Utils dengan kode berikut:

 Kotlin
 Java

1. object Utils {

2. @SuppressLint("SimpleDateFormat")

3. fun toSimpleString(date: Date): String {

4. return SimpleDateFormat("EEE, dd MM yyy").format(date)

5. }

6. }

Fungsi di atas bisa kita gunakan untuk mengubah date menjadi string
dengan format yang sudah ditentukan. Sekarang kita akan menambahkan
sebuah unit test pada fungsi tersebut untuk menguji apakah hasilnya
sesuai atau tidak dengan yang kita harapkan. Untuk menambahkan unit
test, tekan SHIFT + CTRL + T pada fungsi tersebut dan pilih Create
new test ..., maka akan muncul dialog seperti berikut:
Berikan tanda centang dan klik OK maka akan muncul sebuah dialog baru
untuk memilih tujuan penyimpanan dari kelas pengujian yang akan
dibuat.

Karena ini adalah sebuah unit test, maka Anda harus memilih folder
../test/.. untuk menyimpannya. Silakan pilih folder tersebut dan klik OK.
Android Studio secara otomatis akan membuatkan Anda sebuah kelas
testing dengan nama UtilsTest yang di dalamnya sudah terdapat test
function dari fungsi sebelumnya. Anda bisa mengubah nama dari fungsi
tersebut sesuai keinginan Anda.
 Kotlin
 Java

1. class UtilsTest {

2. @Test

3. fun toSimpleString() {

4. }

5. }

Anotasi @Test di atas akan memberitahu JUnit bahwa fungsi yang


dilampirkan dapat dijalankan sebagai sebuah test case. Sekarang Anda
bisa menambahkan kode untuk melakukan pengujian di dalam fungsi
toSimpleString() di atas.

 Kotlin
 Java

1. @Test

2. fun toSimpleString() {

3. val dateFormat: DateFormat = SimpleDateFormat("MM/dd/yyyy")

4. var date: Date? = null

5. try {

6. date = dateFormat.parse("02/28/2018")

7. } catch (e: ParseException) {

8. e.printStackTrace()

9. }

10. assertEquals("Wed, 28 Feb 2018", Utils.toSimpleString(date))

11. }

Perhatikan contoh kode di atas. Kita telah menambahkan fungsi


assertEquals() dari JUnit untuk memastikan kedua parameter di dalamnya
memiliki nilai yang sama. Parameter pertama dari fungsi tersebut adalah
nilai yang diharapkan, sedangkan parameter kedua adalah nilai yang
dihasilkan dari fungsi toSimpleString(). Sekarang coba jalankan pengujian
tersebut dengan menekan SHIFT + CTRL + F10 atau klik kanan pada file
UtilsTest dan pilih Run ‘UtilsTest’. Selanjutnya akan muncul hasil
pengujian pada konsol seperti berikut:
Dari hasil pengujian di atas, kita bisa melihat bahwa pengujian yang telah
kita lakukan gagal, ditunjukan dengan indikator warna merah pada
konsol. Kegagalan tersebut disebabkan nilai yang dikeluarkan oleh fungsi
toSimpleString() berbeda dengan nilai yang kita harapkan.

Coba perhatikan lagi hasil pengujian yang tertera pada konsol di atas. Di
sana terdapat log error yang menunjukan bahwa nilai yang kita harapkan
adalah Wed, 28 Feb 2018, sedangkan nilai yang dihasilkan oleh fungsi
toSimpleString() adalah Wed, 28 02 2018. Dengan demikian, kita bisa
memastikan di dalam fungsi toSimpleString() terdapat kode yang kurang
tepat.

Sekarang coba kita buka kembali kelas Utils dan temukan letak
kesalahan pada fungsi toSimpleString(). Di sana kita menentukan sebuah
pola (pattern) dari SimpleDateFormat dengan "EEE, dd MM yyy", di mana
MM tersebut akan menghasilkan output dari Month dengan format angka,
misal: 02. Format tersebut berbeda dengan format yang kita harapkan,
dan menyebabkan pengujian gagal. Silakan ubah pola dari
SimpleDateFormat menjadi "EEE, dd MMM yyy":

 Kotlin
 Java

1. @SuppressLint("SimpleDateFormat")

2. fun toSimpleString(date: Date?): String? {

3. return SimpleDateFormat("EEE, dd MMM yyy").format(date)

4. }

Jalankanlah kembali pengujiannya. Seharusnya pengujian akan berhasil,


sebagaimana ditandai oleh indikator warna hijau seperti berikut:
Dengan menerapkan Unit Test, Anda dapat melihat apakah kode yang
Anda buat sudah sesuai dengan tujuan atau belum. Tidak hanya itu saja,
Anda dapat memastikan kode tetap aman ketika terjadi perubahan
dengan menerapkan testing. Misalnya terdapat perubahan kode pada fitur
A yang berefek pada fitur B, apabila Anda melakukan tes secara manual,
mungkin Anda akan terlewat jika ada eror pada fitur B. Namun, jika Anda
menerapkan testing secara otomatis menggunakan Unit Test, cukup
jalankan tesnya saja, lalu status pada semua fitur dapat diketahui.
Sehingga, ketika terjadi kesalahan, Anda dapat langsung mendeteksi dan
memperbaikinya.
Latihan Unit Test Menggunakan JUnit dan Mockito
Tujuan

Pada Codelab kali ini Anda akan menggunakan Junit untuk melakukan
testing pada aplikasi Cuboid atau Balok. Poin penting yang tercakup
dalam materi ini adalah bagaimana cara menggunakan Junit untuk Unit
Test.

Alur Latihan

Berikut alur yang akan kita lakukan dalam latihan kali ini:

1. Menuliskan Skenario Pengujian.


2. Membuat Project bernama MyUnitTest.
3. Mengatur tampilan pada berkas layout XML.
4. Menambahkan kelas Cuboid untuk menampung data volume.
5. Menambahkan kelas ViewModel untuk menampung logika dan data
sementara.
6. Mengimplementasikan ViewModel ke dalam Activity.
7. Menjalankan aplikasi.
8. Menambahkan library untuk melakukan pengujian.
9. Membuat kelas pengujian bernama MainViewModelTest.
10.Mengempilimentasikan Skenario Pengujian ke dalam kode Unit Test.
11.Menjalankan pengujian.

Skenario Pengujian

Berikut ini adalah skenario pengujian Unit Test yang akan dilakukan di
Codelab Unit Test menggunakan Mockito:

 Memastikan hasil volume balok sesuai dengan yang diharapkan.


 Memastikan hasil luas permukaan balok sesuai dengan yang diharapkan.
 Memastikan hasil keliling balok sesuai dengan yang diharapkan.
 Memastikan metode hitung volume terpanggil.
 Memastikan metode luas permukaan terpanggil.
 Memastikan metode keliling terpanggil.

Codelab Unit Test Menggunakan Mockito

1. Buat Project baru di Android Studio dengan kriteria sebagai berikut:

Nama Project MyUnitTest


Target & Minimum Target
Phone and Tablet, Api level 21
SDK

Tipe Activity Empty Activity

Activity Name MainActivity

Use AndroidX artifacts True

Language Kotlin/Java

2. Sebelum menyusun layout, Anda perlu mengaktifkan fitur


ViewBinding terlebih dahulu untuk proyek kali ini. Hal tersebut dilakukan
supaya Anda tidak perlu lagi menginisiasi view secara manual
menggunakan fungsi findViewById. Menarik bukan? Okey, langsung saja
tambahkan kode berikut pada berkas build.gradle untuk
mengaktifkannya:

1. android {

2. ...

3.

4. buildTypes {

5. ...

6. }

7.

8. buildFeatures {

9. viewBinding true

10. }

11. }

Setelah selesai mengaktifkan ViewBinding, lanjutkan dengan menambahkan


kode pada berkas activity_main.xml seperti di bawah berikut:

1. <?xml version="1.0" encoding="utf-8"?>

2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

3. xmlns:tools="http://schemas.android.com/tools"

4. android:layout_width="match_parent"

5. android:layout_height="match_parent"
6. android:orientation="vertical"

7. android:padding="16dp"

8. tools:context=".MainActivity">

9.

10. <TextView

11. android:layout_width="match_parent"

12. android:layout_height="wrap_content"

13. android:text="@string/length" />

14.

15. <EditText

16. android:id="@+id/edt_length"

17. android:layout_width="match_parent"

18. android:layout_height="wrap_content"

19. android:layout_marginBottom="16dp"

20. android:inputType="numberDecimal"

21. android:lines="1" />

22.

23. <TextView

24. android:layout_width="match_parent"

25. android:layout_height="wrap_content"

26. android:text="@string/width" />

27.

28. <EditText

29. android:id="@+id/edt_width"

30. android:layout_width="match_parent"

31. android:layout_height="wrap_content"

32. android:layout_marginBottom="16dp"
33. android:inputType="numberDecimal"

34. android:lines="1" />

35.

36. <TextView

37. android:layout_width="match_parent"

38. android:layout_height="wrap_content"

39. android:text="@string/height" />

40.

41. <EditText

42. android:id="@+id/edt_height"

43. android:layout_width="match_parent"

44. android:layout_height="wrap_content"

45. android:layout_marginBottom="16dp"

46. android:inputType="numberDecimal"

47. android:lines="1" />

48.

49. <Button

50. android:id="@+id/btn_save"

51. android:layout_width="match_parent"

52. android:layout_height="wrap_content"

53. android:text="@string/save" />

54.

55. <LinearLayout

56. android:layout_width="match_parent"

57. android:layout_height="wrap_content"

58. android:layout_marginBottom="16dp"

59. android:orientation="horizontal">
60.

61. <Button

62. android:id="@+id/btn_calculate_volume"

63. android:layout_width="match_parent"

64. android:layout_height="wrap_content"

65. android:layout_weight="1"

66. android:text="@string/calculate_volume"

67. android:visibility="gone" />

68.

69. <Button

70. android:id="@+id/btn_calculate_circumference"

71. android:layout_width="match_parent"

72. android:layout_height="wrap_content"

73. android:layout_weight="1"

74. android:layout_marginStart="8dp"

75. android:layout_marginEnd="8dp"

76. android:text="@string/calculate_circumference"

77. android:visibility="gone" />

78.

79. <Button

80. android:id="@+id/btn_calculate_surface_area"

81. android:layout_width="match_parent"

82. android:layout_height="wrap_content"

83. android:layout_weight="1"

84. android:text="@string/calculate_surface_area"

85. android:visibility="gone" />

86. </LinearLayout>
87.

88.

89. <TextView

90. android:id="@+id/tv_result"

91. android:layout_width="match_parent"

92. android:layout_height="wrap_content"

93. android:layout_marginBottom="16dp"

94. android:gravity="center"

95. android:text="@string/result"

96. android:textSize="24sp"

97. android:textStyle="bold" />

98.

99. </LinearLayout>

Setelah menambahkan beberapa baris kode pada activity_main.xml di atas,


akan terdapat beberapa error. Tidak perlu khawatir, untuk mengatasinya cukup
tambahkan beberapa string item di dalam berkas strings.xml seperti berikut:

1. <resources>

2. <string name="app_name">MyUnitTest</string>

3. <string name="width">Lebar</string>

4. <string name="result">Hasil</string>

5. <string name="calculate_volume">Hitung Volume</string>

6. <string name="calculate_surface_area">Hitung Luas Area</string>

7. <string name="calculate_circumference">Hitung Keliling</string>

8. <string name="height">Tinggi</string>

9. <string name="length">Panjang</string>

10. <string name="save">Simpan</string>

11. </resources>
Setelah itu buatlah kelas baru dan beri nama CuboidModel dan ketikkan kode
berikut:

 Kotlin
 Java

1. class CuboidModel {

2. private var width = 0.0

3. private var length = 0.0

4. private var height = 0.0

5.

6. fun getVolume(): Double = width * length * height

7.

8. fun getSurfaceArea(): Double {

9. val wl = width * length

10. val wh = width * height

11. val lh = length * height

12.

13. return 2 * (wl + wh + lh)

14. }

15.

16. fun getCircumference(): Double = 4 * (width + length + height)

17.

18. fun save(width: Double, length: Double, height: Double) {

19. this.width = width

20. this.length = length

21. this.height = height

22. }

23. }
Lalu buatlah kelas baru dan beri nama MainViewModel dan ketikkan kode
berikut:

 Kotlin
 Java

1. class MainViewModel(private val cuboidModel: CuboidModel) {

2. fun getCircumference() = cuboidModel.getCircumference()

3.

4. fun getSurfaceArea() = cuboidModel.getSurfaceArea()

5.

6. fun getVolume() = cuboidModel.getVolume()

7.

8. fun save(w: Double, l: Double, h: Double) {

9. cuboidModel.save(w, l, h)

10. }

11. }

Setelah menambahkan 2 kelas baru, selanjutnya implementasikan kelas-


kelas tersebut pada MainActivity. Silakan ubah kelas tersebut menjadi
seperti berikut ini:

 Kotlin
 Java

1. class MainActivity : AppCompatActivity(), View.OnClickListener {

2.

3. private lateinit var activityMainBinding: ActivityMainBinding

4. private lateinit var mainViewModel: MainViewModel

5.

6. override fun onCreate(savedInstanceState: Bundle?) {

7. super.onCreate(savedInstanceState

8.

9. activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
10. setContentView(activityMainBinding.root)

11.

12. mainViewModel = MainViewModel(CuboidModel())

13.

14. activityMainBinding.btnSave.setOnClickListener(this)

15.
activityMainBinding.btnCalculateSurfaceArea.setOnClickListener(this)

16.
activityMainBinding.btnCalculateCircumference.setOnClickListener(this)

17. activityMainBinding.btnCalculateVolume.setOnClickListener(this)

18. }

19. }

Selanjutnya tambahkan aksi ketika btnSave dan beberapa button lainnya diklik
dan beri response-nya ketika berhasil. Sehingga MainActivity menjadi seperti
berikut:

 Kotlin
 Java

1. class MainActivity : AppCompatActivity(), View.OnClickListener {

2.

3. private lateinit var activityMainBinding: ActivityMainBinding

4. private lateinit var mainViewModel: MainViewModel

5.

6. override fun onCreate(savedInstanceState: Bundle?) {

7. super.onCreate(savedInstanceState)

8.

9. activityMainBinding = ActivityMainBinding.inflate(layoutInflater)

10. setContentView(activityMainBinding.root)

11.

12. mainViewModel = MainViewModel(CuboidModel())


13.

14. activityMainBinding.btnSave.setOnClickListener(this)

15. activityMainBinding.btnCalculateSurfaceArea.setOnClickListener(this)

16.
activityMainBinding.btnCalculateCircumference.setOnClickListener(this)

17. activityMainBinding.btnCalculateVolume.setOnClickListener(this)

18. }

19.

20. override fun onClick(v: View) {

21. val length =


activityMainBinding.edtLength.text.toString().trim()

22. val width =


activityMainBinding.edtWidth.text.toString().trim()

23. val height =


activityMainBinding.edtHeight.text.toString().trim()

24.

25. when {

26. TextUtils.isEmpty(length) -> {

27. activityMainBinding.edtLength.error = "Field ini tidak


boleh kosong"

28. }

29. TextUtils.isEmpty(width) -> {

30. activityMainBinding.edtWidth.error = "Field ini tidak


boleh kosong"

31. }

32. TextUtils.isEmpty(height) -> {

33. activityMainBinding.edtHeight.error = "Field ini tidak


boleh kosong"

34. }

35.

36. else -> {


37. val valueLength = length.toDouble()

38. val valueWidth = width.toDouble()

39. val valueHeight = height.toDouble()

40.

41. when (v.id) {

42. R.id.btn_save -> {

43. mainViewModel.save(valueLength, valueWidth,


valueHeight)

44. visible()

45. }

46. R.id.btn_calculate_circumference -> {

47. activityMainBinding.tvResult.text =
mainViewModel.getCircumference().toString()

48. gone()

49. }

50. R.id.btn_calculate_surface_area -> {

51. activityMainBinding.tvResult.text =
mainViewModel.getSurfaceArea().toString()

52. gone()

53. }

54. R.id.btn_calculate_volume -> {

55. activityMainBinding.tvResult.text =
mainViewModel.getVolume().toString()

56. gone()

57. }

58. }

59. }

60. }

61. }
62.

63. private fun visible() {

64. activityMainBinding.btnCalculateVolume.visibility =
View.VISIBLE

65. activityMainBinding.btnCalculateCircumference.visibility =
View.VISIBLE

66. activityMainBinding.btnCalculateSurfaceArea.visibility =
View.VISIBLE

67. activityMainBinding.btnSave.visibility = View.GONE

68. }

69.

70. private fun gone() {

71. activityMainBinding.btnCalculateVolume.visibility =
View.GONE

72. activityMainBinding.btnCalculateCircumference.visibility =
View.GONE

73. activityMainBinding.btnCalculateSurfaceArea.visibility =
View.GONE

74. activityMainBinding.btnSave.visibility = View.VISIBLE

75. }

76. }

6. Nah, sampai di sini Anda sudah membuat aplikasi Cuboid. Silakan


jalankan aplikasi Anda dan hasilnya terlihat seperti berikut:
Codelab Melakukan Pengujian Menggunakan JUnit dan Mockito

Selanjutnya lakukan pengujian pada project tersebut.

1. Atur konfigurasi dependencies dengan menggunakan


framework JUnit4 dan Mockito. Caranya edit build.gradle(module:
app) dan tambahkan dependencies berikut:

o Kotlin
o Java

1. ...

2. dependencies {

3. ...

4.

5. testImplementation 'org.mockito:mockito-core:3.6.0'

6. testImplementation 'org.mockito:mockito-inline:3.6.0'
7. }

Kemudian buka MainViewModel lalu tekan CTRL+SHIFT+T atau


ALT+ENTER pada teks MainViewModel dan pilih Create Test untuk
membuat kelas MainViewModelTest dalam
package test/java/applicationIDKamu/.

Kemudian akan muncul dialog Create Test. Pastikan Anda memilih


JUnit4 dan centang semua fungsi yang akan dibuat unit test-nya.

Setelah klik OK, akan muncul 2 pilihan yaitu androidTest untuk


melakukan Instrumentation Test dan test untuk melakukan Unit
Test. Pilihlah test karena Anda hanya ingin melakukan Unit Test saja.
Selanjutnya buka kelas MainViewModelTest. Pertama, siapkan kode-
kode yang diperlukan sebelum melakukan pengujian kelas ViewModel
pada method dengan anotasi @Before. Masukkan kode berikut ini:

 Kotlin
 Java

1. class MainViewModelTest {

2.

3. private lateinit var mainViewModel: MainViewModel

4. private lateinit var cuboidModel: CuboidModel

5.

6. @Before

7. fun before() {

8. cuboidModel = mock(CuboidModel::class.java)

9. mainViewModel = MainViewModel(cuboidModel)

10. }

11. }
Selanjutnya Anda akan menguji metode untuk menghitung volume dari
sebuah balok dengan membuat fungsi yang beranotasi @Test,
masukkanlah kode berikut:

 Kotlin
 Java

1. class MainViewModelTest {

2.

3. private lateinit var mainViewModel: MainViewModel

4. private lateinit var cuboidModel: CuboidModel

5.

6. private val dummyLength = 12.0

7. private val dummyWidth = 7.0

8. private val dummyHeight = 6.0

9.

10. private val dummyVolume = 500.0

11.

12. @Before

13. fun before() {

14. cuboidModel = mock(CuboidModel::class.java)

15. mainViewModel = MainViewModel(cuboidModel)

16. }

17.

18. @Test

19. fun testVolume() {

20. cuboidModel = CuboidModel()

21. mainViewModel = MainViewModel(cuboidModel)

22. mainViewModel.save(dummyWidth, dummyLength, dummyHeight)

23. val volume = mainViewModel.getVolume()


24. assertEquals(dummyVolume, volume, 0.0001)

25. }

26. }

Nah, untuk menjalankan pengujiannya, silakan


tekan CTRL+SHIFT+F10 atau klik kanan pada class dan pilih Run
'MainViewModelTest'.

Dan lihat hasilnya:

Gagal! Unit test gagal dan menunjukan indikator berwarna merah serta letak
erornya. Terlihat bahwa 'Expected = 500.0' dan 'Actual = 504.0'. Apa
artinya?

Pengujian Anda gagal, sebab ekspektasi mengenai hasil dari volume tersebut
adalah '500.0' sementara hasil sebenarnya adalah '504.0'.

Solusinya, ubahlah nilai dari variable dummyValue menjadi seperti


berikut:

 Kotlin
 Java
1. private val dummyVolume = 504.0

Nah, formula perhitungan volume sudah benar sekarang.

Catatan:
Angka 0.0001 pada parameter ketiga dalam assertEquals() adalah angka delta
yang merupakan selisih range di belakang koma bilangan double.

Sekarang coba jalankan pengujiannya sekali lagi dan lihat hasilnya.

Akan ada indikator berwarna hijau. Pesan tests passed menandakan bahwa Unit
Test berhasil.

Selanjutnya tambahkan pengujian metode untuk menghitung luas permukaan


dan keliling balok dengan 2 metode berikut:

 Kotlin
 Java

1. class MainViewModelTest {

2.

3. private lateinit var mainViewModel: MainViewModel

4. private lateinit var cuboidModel: CuboidModel

5.

6. private val dummyLength = 12.0

7. private val dummyWidth = 7.0

8. private val dummyHeight = 6.0

9.

10. private val dummyVolume = 504.0

11. private val dummyCircumference = 100.0


12. private val dummySurfaceArea = 396.0

13.

14. ...

15.

16. @Test

17. fun testCircumference() {

18. cuboidModel = CuboidModel()

19. mainViewModel = MainViewModel(cuboidModel)

20. mainViewModel.save(dummyWidth, dummyLength, dummyHeight)

21. val volume = mainViewModel.getCircumference()

22. assertEquals(dummyCircumference, volume, 0.0001)

23. }

24.

25. @Test

26. fun tesSurfaceArea() {

27. cuboidModel = CuboidModel()

28. mainViewModel = MainViewModel(cuboidModel)

29. mainViewModel.save(dummyWidth, dummyLength, dummyHeight)

30. val volume = mainViewModel.getSurfaceArea()

31. assertEquals(dummySurfaceArea, volume, 0.0001)

32. }

33. }

Jalankan pengujian dan lihat hasilnya:


Berhasil! Anda sudah melakukan testing pada proses perhitungan luas
permukaan dan keliling.

Selanjutnya lakukan pengujian menggunakan mock. dengan


menambahkan metode berikut:

 Kotlin
 Java

1. class MainViewModelTest {

2.

3. ...

4.

5. @Test

6. fun testMockVolume() {

7.
`when`(mainViewModel.getVolume()).thenReturn(dummyVolume)

8. val volume = mainViewModel.getVolume()

9. verify(cuboidModel).getVolume()

10. assertEquals(dummyVolume, volume, 0.0001)

11. }

12.

13. @Test

14. fun testMockCircumference() {

15.
`when`(mainViewModel.getCircumference()).thenReturn(dummyCi
rcumference)
16. val circumference = mainViewModel.getCircumference()

17. verify(cuboidModel).getCircumference()

18. assertEquals(dummyCircumference, circumference, 0.0001)

19. }

20.

21. @Test

22. fun testMockSurfaceArea() {

23.
`when`(mainViewModel.getSurfaceArea()).thenReturn(dummySurf
aceArea)

24. val surfaceArea = mainViewModel.getSurfaceArea()

25. verify(cuboidModel).getSurfaceArea()

26. assertEquals(dummySurfaceArea, surfaceArea, 0.0001)

27. }

28. }

8. Jalankan dan lihat hasilnya:

Hore! semua pengujian kelas perhitungan balok sudah rampung! Mulai


dari perhitungan volume, keliling, dan luas permukaan.

Selesai sudah testing yang dilakukakan, mari kita masuk ke bagian bedah
kode.
Bedah Kode

Anda sudah melewati beberapa latihan untuk melakukan unit test. Pada
Bedah Kode ini Anda akan mendapat penjelasan yang lebih dalam terkait
kode-kode yang digunakan pada latihan unit test.

OK mari kita pelajari satu per satu:

Unit Test Dependencies

 Kotlin
 Java

1. testImplementation 'junit:junit:4.13.2'

2. testImplementation "org.mockito:mockito-core:3.6.0"

3. testImplementation 'org.mockito:mockito-inline:3.6.0'

Dependencies yang digunakan pada latihan tadi adalah JUnit dan Mockito.
JUnit digunakan untuk melakukan unit test, sedangkan Mockito
digunakan sebagai mock object.

Fungsi dari mock object adalah mereplika objek yang digunakan oleh
objek yang sedang di-test. Tujuannya agar test yang dilakukan hanya
dilakukan pada unit yang berada dalam jangkauan objek yang sedang di-
test tanpa memengaruhi objek di luar jangkauan.

Manfaat Penggunaan Mocking

Beberapa manfaat dari mocking meliputi:

 Menghindari Terlalu Banyak Dependency. Mocking mengurangi


ketergantungan fungsi. Misalnya, jika Anda memiliki fungsi Kelas yang
bergantung pada fungsi B, tulislah beberapa unit test yang mencakup fitur
yang diberikan oleh fungsi B. Misalkan kode itu berkembang di masa
depan dan Anda memiliki lebih banyak fungsi, yaitu A tergantung pada B,
B bergantung pada C, dan C bergantung pada D. Jika kesalahan
dikenalkan pada Z, semua unit test Anda akan gagal.
 Mengurangi kelebihan beban (overload). Ini berlaku untuk fungsi
resource-intensive. Sebuah mock dari fungsi itu akan mengurangi
penggunaan sumber daya (resource) yang tidak perlu selama pengujian,
sehingga mengurangi waktu uji coba.
 Bypass kendala waktu dalam fungsi. Ini berlaku untuk aktivitas
terjadwal. Bayangkan sebuah proses yang telah dijadwalkan untuk
dijalankan setiap jamnya. Dalam situasi seperti ini, mocking benar-benar
menguji logika sehingga Anda tidak harus menjalankan test berjam-jam,
menunggu sampai selesai.
Annotation

Di dalam Unit Test tadi Anda telah menggunakan beberapa annotation, di


antaranya:

1. @Before
Fungsinya untuk menginisialisasi method sebelum melakukan test.
Method yang diberi anotasi @Before ini akan dijalankan sebelum
menjalankan semua method dengan anotasi @Test. Selain anotasi
@Before, dalam melakukan Unit Test juga ada anotasi @After yang
berfungsi sebaliknya dari anotasi @Before, yaitu untuk menginisialisai
method yang akan dijalankan setelah method dengan anotasi @Test.
2. @Test
Anotasi ini digunakan pada method yang akan dites.

Fungsi Test yang Digunakan

Dalam proses Unit Test tadi Anda menggunakan 3 fungsi yaitu


assertEquals, verify, dan any. Namun masih ada beberapa fungsi dari
JUnit dan Mockito yang bisa digunakan. Berikut adalah penjelasan dari
beberapa fungsi dari JUnit dan Mockito yang biasa digunakan dalam Unit
Test.

1. mock()
Fungsinya untuk membuat obyek mock yang akan menggantikan obyek
yang asli.
2. when()
Digunakan untuk menandakan event di mana Anda ingin memanipulasi
behavior dari mock object.
3. thenReturn()
Digunakan untuk memanipulasi output dari mock object.
4. verify()
Digunakan untuk memeriksa metode dipanggil dengan arguman yang
diberikan. Verify merupkan fungsi dari framework Mockito
5. assertEquals()
Fungsi ini merupakan fungsi dari JUnit yang digunakan untuk memvalidasi
output yang diharapkan dan output yang sebenarnya.

Untuk memperdalam tentang unit test silakan cek halaman ini.

 Local Unit Test

Hore, pengujian kelas perhitungan volume sudah rampung semua! Mulai


dari nilai inputan yang normal, inputan nilai double, inputan nilai zero
(nol), hingga verifikasi hasilnya.

Source code dapat Anda unduh pada tautan berikut :


 Source Code Latihan UnitTest
Teori UI Test dengan Espresso

Salah satu titik krusial dalam sebuah proses pengembangan aplikasi, baik
itu pada platform web, desktop, bahkan mobile adalah pada proses
pengujiannya. Pengujian yang baik akan menentukan hasil yang baik
pula.

Ini berpengaruh pada kualitas aplikasi yang dihasilkan. Kita tidak ingin
saat aplikasi sudah ada di tangan pengguna, aplikasi tersebut memberi
pengalaman yang tidak menyenangkan. Terlebih lagi, ketika aplikasinya
mengalami masalah, baik itu force closed maupun application not
responding. Ingat! Aplikasi mobile memiliki biaya akuisisi (acquisition
cost) yang sangat mahal. Meminta atau membuat pengguna mengunduh
dan menggunakan aplikasi bukanlah sesuatu yang murah.

Sekali pengguna menyatakan aplikasi kita tidak bagus, yang kemudian


berujung pada pencopotan aplikasi kita (uninstall), maka akan sulit untuk
membuat pengguna mengunduhnya kembali. Jadi kualitas aplikasi
berpengaruh terhadap konversi nilai dan interaksi yang dihasilkan. Tetapi,
kita tidak bisa menjamin aplikasi yang kita kembangkan terbebas 100%
dari masalah. Hal ini karena begitu beragamnya peranti, khususnya
Android. Namun, kita masih bisa membuatnya lebih stabil dan
mengupayakan jumlah masalah yang serendah mungkin. Dan itu poin
penting dari proses pengujian aplikasi.

Pengujian aplikasi, khususnya Android, dapat dilakukan secara manual


ataupun otomatis (automation test). Cara pertama yaitu melakukan
pengujian langsung terhadap APK yang di-deploy ke peranti atau
emulator. Pengujian ini membutuhkan ketelitian dari para penguji
biasanya tim quality assurance dan kesabaran bagi developer untuk
menerima kenyataan jika kode yang dibuat menyebabkan beragam
masalah.

Pengujian dilakukan dengan metode whitebox dan blackbox testing.


Pengujian jenis ini akan memakan waktu, membosankan, dan rawan
terjadi kesalahan atau human error.

Salah satu pendekatan modern dan efisien adalah dengan menggunakan


automation testing. Untuk Android sendiri sudah banyak tools seperti
JUnit, Roboelectric, Mockito, dan Espresso yang mampu melakukan ini.

Alat-alat di atas mendukung beragam metode pengujian. Tidak hanya


sekedar menguji secara fungsi atau algoritma yang kita gunakan, tetapi
sudah bisa masuk ke ranah pengujian otomatis untuk antarmuka.

Pada materi ini kita akan belajar bagaimana menguji antarmuka di


Android menggunakan espresso.
Tenang, topik ini akan lebih mengarah ke dasar penggunaan dan konsep
tentang UI test. Seperti definisinya, pengujian antarmuka akan
menekankan pada proses pengujian aplikasi melalui tampilan dan
komponen kontrolnya. Pengujian bisa berupa validasi input, pengecekan
output, atau pemberian sebuah event seperti click() pada sebuah elemen
antarmuka.

Secara karakteristik pengujian antarmuka mencakup beberapa hal


sebagai berikut :

1. User interface merupakan media visual untuk berinteraksi dengan


pengguna yang terdiri dari beragam komponen pembangun user interface
seperti label, button, radiobutton, dan lain sebagainya.
2. Selama proses pengujian, elemen properti yang menempel pada sebuah
komponen user interface akan memberi pengaruh terhadap kondisi atau
‘state’ dari komponen tersebut.
3. Pengujian user interface secara otomatis mampu melakukan pemberian
input dan event pada komponen seperti click(), pressKey() dan lain
sebagainya.
4. Pengujian ini lebih menekankan ke perbandingan antara proses yang
dilakukan dengan hasil yang diharapkan dalam sebuah skenario
penggunaan.
5. Pengujian user interface secara otomatis bergantung penuh pada
teknologi yang digunakan. Dalam hal ini framework atau tools yang
digunakan akan mempengaruhi hasil dari proses pengujian yang
dilakukan.

Espresso

Espresso merupakan sebuah framework pengujian yang tersedia pada


Android Testing Support Library. Framework ini menyediakan satu set API
yang memudahkan developer untuk menulis kode testing guna
menyimulasikan interaksi pengguna ke dalam sebuah aplikasi. Espresso
bisa berjalan pada peranti dengan OS Android Gingerbread (2.3.3) / API
Level 10 dan versi di atasnya.

Espresso sudah menjadi pilihan utama untuk melakukan UI test Android.


Sejak Google I/O 2017, ia juga sudah menjadi bagian dari keluarga besar
dari versi pertama Android Testing Support Library (ATSL). [13].

Ada beragam keuntungan ketika menggunakan Espresso. Framework ini


secara otomatis melakukan sinkronisasi antara sebuah skenario test
dengan target aplikasi yang akan diuji. Espresso akan memastikan
komponen aplikasi seperti activity dijalankan terlebih dahulu sebelum
test-nya berjalan. Ia juga mampu mendeteksi setiap proses asynchronous
yang berjalan di dalam aplikasi yang diuji.
Tiga Komponen Utama dari Espresso:

1. ViewMatchers (onView(ViewMatcher)) : Menemukan elemen atau


komponen antarmuka yang diuji.
2. ViewActions (perform(ViewAction)) : Memberikan event untuk melakukan
sebuah aksi pada komponen antarmuka yang diuji.
3. ViewAssertions : Melakukan pemeriksaan terhadap sebuah kondisi atau
state dari komponen yang diuji.

Sebagai contoh lihatlah alur pengujian berikut:

Dengan menggunakan Espresso, maka fungsi yang digunakan seperti ini:

Seperti yang telah disebutkan sebelumnya, pengujian ini sedikit berbeda


dengan unit tests. UI test digunakan untuk menguji behavior dari aplikasi
ketika pengguna berinteraksi dengan UI. Untuk melakukannya, kita akan
memanfaatkan fitur-fitur dari Espresso, sebuah library bawaan yang akan
membantu kita dalam melakukan UI test dengan mudah. Anda tidak perlu
menambahkan dependensi lagi karena secara otomatis sudah
ditambahkan ketika kita membuat proyek baru. Untuk memastikannya,
bukalah berkas build.gradle, maka Anda akan melihat dependensi yang
ditandai dengan androidTestImplementation berikut ini:

1. androidTestImplementation 'androidx.test:rules:1.4.0'

2. androidTestImplementation 'androidx.test:runner:1.4.0'

3. androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Selain dependensi di atas, konfigurasi lain yang telah ditambahkan adalah
testInstrumentationRunner pada defaultConfig.

1. testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Supaya materi ini lebih mudah dipahami, mari kita buat skenario
pengujian menggunakan sebuah kasus sederhana. Mari ngoding!
Latihan UI Test Menggunakan Espresso
Tujuan

Pada codelab kali ini Anda akan menguji antar muka dari aplikasi
menggunakan Espresso. Tujuannya agar UI dan UX aplikasi dapat berjalan
dengan benar. Hasil dari codelab kali ini akan menjadi seperti berikut:

Alur Latihan

Berikut alur yang akan kita lakukan dalam latihan kali ini:

1. Menuliskan Skenario Pengujian.


2. Melanjutkan kembali project bernama Latihan Unit Test Menggunakan
Mockito.
3. Menambahkan library untuk melakukan pengujian.
4. Membuat kelas pengujian bernama MainActivityTest .
5. Mengempilimentasikan Skenario Pengujian ke dalam kode UI Test.
6. Menjalankan pengujian.
Skenario Pengujian

Terdapat 4 skenario pengujian UI Test:

1. Pengujian keliling balok.


o Aplikasi terbuka dan menampilkan beberapa view.
o Memberi tindakan input pada edt_lenght, edt_width dan edt_height.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan Button btn_calculate_circuference telah ditampilkan.
o Memberi tindakan klik pada btn_calculate_circuference.
o Memastikan TextView tv_result telah ditampilkan.
o Memastikan hasil yang tampil sesuai ekspektasi.
2. Pengujian volume balok.
o Aplikasi terbuka dan menampilkan beberapa view.
o Memberi tindakan input pada edt_lenght, edt_width dan edt_height.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan Button btn_calculate_volume telah ditampilkan.
o Memberi tindakan klik pada btn_calculate_volume.
o Memastikan TextView tv_result telah ditampilkan.
o Memastikan hasil yang ditampilkan sesuai dengan ekspektasi.
3. Pengujian luas permukaan balok.
o Memberi tindakan input pada edt_lenght, edt_width dan edt_height.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan Button btn_calculate_surface_area telah ditampilkan.
o Memberi tindakan klik pada btn_calculate_surface_area.
o Memastikan TextView tv_result telah ditampilkan.
o Memastikan hasil yang tampil sesuai ekspektasi.
4. Pengujian input panjang, lebar dan tinggi balok.
o Aplikasi terbuka dan menampilkan beberapa view.
o Memberi tindakan empty input pada edt_lenght.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan eror yang tampil sesuai ekspektasi.
o Memberi tindakan input pada edt_lenght.
o Memberi tindakan empty input pada edt_width.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan eror yang tampil sesuai ekspektasi.
o Memberi tindakan input pada edt_width.
o Memberi tindakan empty input pada edt_height.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
o Memastikan eror yang tampil sesuai ekspektasi.
o Memberi tindakan input pada edt_height.
o Memastikan Button btn_save telah ditampilkan.
o Memberi tindakan klik pada btn_save.
Codelab UI Testing

1. Bukalah proyek sebelumnya tentang Latihan Unit Test Menggunakan


Mockito.

2. Tentu pertama kali Anda perlu menambahkan library dari Espresso di


build.gradle:

1. androidTestImplementation 'androidx.test:runner:1.4.0'

2. androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

3. androidTestImplementation 'androidx.test:rules:1.4.0'

4. androidTestImplementation 'androidx.test.ext:junit:1.1.3'

Untuk membuat proses pengujian berjalan lancar, silakan matikan semua


fungsi animasi yang terdapat pada halaman Developer Options pada
Setting → Developer Options seperti berikut:

Lakukan untuk semua konfigurasi animasi di atas. Alasannya adalah


memudahkan Espresso ketika menjalankan kode dengan beragam resource
yang digunakannya.

Sekarang saatnya Anda membuat kelas pengujian otomatis dengan cara


membuat kelas baru bernama MainActivityTest pada package utama
yang berlabel (androidTest). Caranya, masuklah ke MainActivity
kemudian tekan Alt+Enter maka akan muncul tampilan seperti ini:

Pilihlah Create Test, sehingga akan muncul tampilan seperti ini:

Biarkan default seperti tampilan di atas, kemudian pilih OK. Sehingga


akan ada dua pilihan androidTest atau test, untuk UI Test pilihlah
androidTest.
Selanjutnya akan terbentuk sebuah kelas seperti ini:

Hapus kelas ExampleInstrumentedTest dan ExampleUnitTest karena


kelas tersebut tidak dibutuhkan dalam proyek Anda.

Pertama Anda buka terlebih dahulu berkas MainActivityTest dan


tambahkanlah kode-kode berikut:

 Kotlin
 Java

1. @RunWith(AndroidJUnit4ClassRunner::class)

2. class MainActivityTest {
3. private val dummyVolume = "504.0"

4. private val dummyCircumference = "100.0"

5. private val dummySurfaceArea = "396.0"

6. private val dummyLength = "12.0"

7. private val dummyWidth = "7.0"

8. private val dummyHeight = "6.0"

9. private val emptyInput = ""

10. private val fieldEmpty = "Field ini tidak boleh kosong"

11.

12. @Before

13. fun setup(){

14. ActivityScenario.launch(MainActivity::class.java)

15. }

16. }

Setelah itu, lakukan pengujian keliling balok seperti yang ada di skenario di atas.

 Kotlin
 Java

1. ...

2. import androidx.test.espresso.Espresso.onView

3. import androidx.test.espresso.action.ViewActions.*

4. import androidx.test.espresso.assertion.ViewAssertions.matches

5. import androidx.test.espresso.matcher.ViewMatchers.*

6.

7. @RunWith(AndroidJUnit4ClassRunner::class)

8. class MainActivityTest {

9. ...

10.
11. @Test

12. fun assertGetCircumference() {

13. onView(withId(R.id.edt_length)).perform(typeText(dummyLength),
closeSoftKeyboard())

14. onView(withId(R.id.edt_width)).perform(typeText(dummyWidth),
closeSoftKeyboard())

15. onView(withId(R.id.edt_height)).perform(typeText(dummyHeight),
closeSoftKeyboard())

16.

17. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

18. onView(withId(R.id.btn_save)).perform(click())

19.

20.
onView(withId(R.id.btn_calculate_circumference)).check(matches(isDispl
ayed()))

21. onView(withId(R.id.btn_calculate_circumference)).perform(click())

22.

23. onView(withId(R.id.tv_result)).check(matches(isDisplayed()))

24.
onView(withId(R.id.tv_result)).check(matches(withText(dummyCircumfer
ence)))

25. }

26. }

Beberapa metode tidak akan ditawarkan oleh auto-complete Android


Studio. Untuk mengatasi ini, tekan Alt + Enter pada beberapa metode-
metode tadi dan lakukan static import seperti contoh di bawah ini:

 Kotlin
 Java
Kemudian pilih import sesuai dengan keterangan di atas.

 Setelah selesai, sekarang saatnya menjalankan kode pengujian. Jika


sebelumnya Anda menjalankan aplikasi terlebih dahulu, maka sekarang
pendekatannya dibalik. Anda harus menjalankan kode testnya terlebih
dahulu. Caranya, klik kanan pada MainActivityTest dan pilih run
‘MainActivity…’ seperti pada gambar di bawah ini:

Lalu pilih peranti yang terhubung dan akan menjadi tempat pengujian
aplikasi.
Perhatikan peranti Anda selama pengujian berlangsung.

Beragam nilai inputan akan dimasukkan secara otomatis. Keren, kan?

Setelah berjalan, perhatikan monitor panel yang aktif di bagian bawah Android
Studio . Panel tersebut berisi informasi progress pengujian. Jika semua pengujian
yang dilakukan berhasil, layar akan menampilkan hasil sukses seperti berikut:

Selanjutnya tambahkan kode untuk melakukan pengujian menghitung volume,


luas permukaan, dan input kosong di dalam aplikasi.
 Kotlin
 Java

1. @RunWith(AndroidJUnit4ClassRunner::class)

2. class MainActivityTest {

3. ...

4.

5. @Test

6. fun assertGetSurfaceArea() {

7. onView(withId(R.id.edt_length)).perform(typeText(dummyLength),
closeSoftKeyboard())

8. onView(withId(R.id.edt_width)).perform(typeText(dummyWidth),
closeSoftKeyboard())

9. onView(withId(R.id.edt_height)).perform(typeText(dummyHeight),
closeSoftKeyboard())

10.

11. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

12. onView(withId(R.id.btn_save)).perform(click())

13.

14.
onView(withId(R.id.btn_calculate_surface_area)).check(matches(isDispla
yed()))

15. onView(withId(R.id.btn_calculate_surface_area)).perform(click())

16.

17. onView(withId(R.id.tv_result)).check(matches(isDisplayed()))

18.
onView(withId(R.id.tv_result)).check(matches(withText(dummySurfaceAr
ea)))

19. }

20.

21. @Test

22. fun assertGetVolume() {


23. onView(withId(R.id.edt_length)).perform(typeText(dummyLength),
closeSoftKeyboard())

24. onView(withId(R.id.edt_width)).perform(typeText(dummyWidth),
closeSoftKeyboard())

25. onView(withId(R.id.edt_height)).perform(typeText(dummyHeight),
closeSoftKeyboard())

26.

27. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

28. onView(withId(R.id.btn_save)).perform(click())

29.

30.
onView(withId(R.id.btn_calculate_volume)).check(matches(isDisplayed())
)

31. onView(withId(R.id.btn_calculate_volume)).perform(click())

32.

33. onView(withId(R.id.tv_result)).check(matches(isDisplayed()))

34.
onView(withId(R.id.tv_result)).check(matches(withText(dummyVolume)))

35. }

36.

37. //Pengecekan untuk empty input

38. @Test

39. fun assertEmptyInput() {

40. // pengecekan input untuk length

41. onView(withId(R.id.edt_length)).perform(typeText(emptyInput),
closeSoftKeyboard())

42.

43. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

44. onView(withId(R.id.btn_save)).perform(click())

45.
46.
onView(withId(R.id.edt_length)).check(matches(hasErrorText(fieldEmpty
)))

47. onView(withId(R.id.edt_length)).perform(typeText(dummyLength),
closeSoftKeyboard())

48.

49. // pengecekan input untuk width

50. onView(withId(R.id.edt_width)).perform(typeText(emptyInput),
closeSoftKeyboard())

51.

52. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

53. onView(withId(R.id.btn_save)).perform(click())

54.

55.
onView(withId(R.id.edt_width)).check(matches(hasErrorText(fieldEmpty)
))

56. onView(withId(R.id.edt_width)).perform(typeText(dummyWidth),
closeSoftKeyboard())

57.

58. // pengecekan input untuk height

59. onView(withId(R.id.edt_height)).perform(typeText(emptyInput),
closeSoftKeyboard())

60.

61. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

62. onView(withId(R.id.btn_save)).perform(click())

63.

64.
onView(withId(R.id.edt_height)).check(matches(hasErrorText(fieldEmpty
)))

65. onView(withId(R.id.edt_height)).perform(typeText(dummyHeight),
closeSoftKeyboard())

66.

67. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))
68. onView(withId(R.id.btn_save)).perform(click())

69. }

70. }

Jalankan kembali instrumental testing Anda. Hasilnya akan terlihat seperti


ini:

4 dari 4 skenario pengujian berhasil dilakukan. Luar biasa!

Sekarang Anda sudah berhasil melakukan proses pengujian secara


otomatis. Mari kita ulik lebih lanjut. Hilangkan baris ini pada kode di
MainActivity.

 Kotlin
 Java

1. edtWidth = findViewById(R.id.edt_width)

Coba jalankan kode test seperti cara sebelumnya. Seharusnya proses pengujian
akan gagal. Anda dapat mengetahui pesan dan penyebab kegagalan pada
monitor panel seperti berikut:

1. android.support.test.espresso.PerformException: Error performing 'single


click - At Coordinates: 539, 947 and precision: 16, 16' on view 'Animations
or transitions are enabled on the target device.

2. For more info check: http://goo.gl/qVu1yV

3.
4. with id: com.dicoding.picodiploma.myunittest:id/btn_save'.

5. at
android.support.test.espresso.PerformException$Builder.build(PerformExc
eption.java:82)

6. ...

7. at
android.support.test.espresso.ViewInteraction.perform(ViewInteraction.jav
a:114)

8. at
com.dicoding.picodiploma.myunittest.MainActivityTest.assertSurfaceArea(
MainActivityTest.java:58)

9. at java.lang.reflect.Method.invoke(Native Method)

10. ...

11. at
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.j
ava:2145)

12. Caused by: java.lang.NullPointerException: Attempt to invoke virtual


method 'android.text.Editable android.widget.EditText.getText()' on a null
object reference

13. at
com.dicoding.picodiploma.myunittest.MainActivity.onClick(MainActivity.jav
a:46)

14. at android.view.View.performClick(View.java:6597)

Bedah Kode

Espresso

Sebelumnya, kita perlu ingat kembali tiga komponen utama dari Espresso:

1. ViewMatchers (onView(ViewMatcher)), untuk menemukan elemen


atau komponen antar muka yang diuji.
2. ViewActions (perform(ViewAction)), untuk memberikan event untuk
melakukan sebuah aksi pada komponen antar muka yang diuji.
3. ViewAssertions(check(ViewAssertion)), untuk mengecek sebuah
kondisi atau state dari komponen yang diuji.

Kita akan membedah kode yang baru saja kita buat berdasarkan skenario
yang kita buat.

 Kotlin
 Java
1. @Before

2. fun setup(){

3. ActivityScenario.launch(MainActivity::class.java)

4. }

Kode di atas digunakan untuk memerintahkan Activity mana yang akan


dijalankan.

Selanjutnya perhatikan kode berikut:

 Kotlin
 Java

1. onView(withId(R.id.edt_length)).perform(typeText(dummyLength),
closeSoftKeyboard())

Perhatikan kode di atas, jika kode di atas dibaca maka jadi seperti
ini: Sebuah view dengan id edt_length diberi tindakan input dengan
sebuah teks dummyLength dan menutup secara berlahan keyboard
Android. Jadi terdapat banyak aksi di dalam komponen Espresso.

Selanjutnya kode berikut:

 Kotlin
 Java

1. onView(withId(R.id.btn_save)).check(matches(isDisplayed()))

Jika kode di atas dibaca akan menjadi seperti ini: Memastikan sebuah
view dengan id btn_save dalam keadaan tampil.

Lalu perhatikan kode berikut:

 Kotlin
 Java

1. onView(withId(R.id.btn_save)).perform(click())

Jika kode di atas dibaca, akan menjadi seperti ini: Sebuah view dengan
id btn_save diberi aksi klik.

Dan yang paling penting adalah ini:

 Kotlin
 Java

1. onView(withId(R.id.tv_result)).check(matches(withText(dummyCircumference)))
Jika kode di atas dibaca, akan menjadi seperti berikut: Memastikan
sebuah view dengan id tv_result mempunyai teks yang sama
dengan dummyCircumference.

Perhatikan juga kode berikut yang berfungsi untuk mengecek eror pada
EditText:

 Kotlin
 Java

1. onView(withId(R.id.edt_length)).check(matches(hasErrorText(fieldEmpty)))

Jika kode di atas dibaca akan menjadi seperti berikut: Memastikan


sebuah view dengan id edt_length mempunyai pesan eror yang
sama dengan fieldEmpty.

Bagaimana? Mudah kan proses pengujian antarmuka dengan


menggunakan Espresso? Tak hanya mudah tapi juga efisien jika Anda
berhadapan dengan kasus yang lebih besar. Kebiasaan menuliskan kode
pengujian akan melatih Anda lebih kritis terhadap beragam kondisi yang
akan terjadi pada tiap fungsi di dalam aplikasi.

Apalagi bila Anda menulis kode test sebelum kode aplikasi. Proses
pengembangan aplikasi Anda dijamin jauh lebih baik dan mampu
menghasilkan produk yang lebih berkualitas! Proses pengujian otomatis di
atas masih sangatlah sederhana. Kami tantang Anda untuk
mengeksplorasi lebih jauh kemampuan Espresso lainnya!

Seperti biasa, agar Anda lebih paham tentang materi ini, kami sarankan
untuk membaca referensi dari beberapa tautan berikut:

 Espresso Testing
 Espresso Test Recorder
 Running Espresso Test
 UI Testing with Espresso

Untuk source code materi ini silakan Anda unduh di:

 Source Code Latihan UITest

Anda mungkin juga menyukai