Flutter Testing 101 — Memahami Unit Testing, Widget Testing, dan Integration Testing pada Flutter
Menganal jenis pengujian yang umum diterapkan pada Flutter seperti unit testing, widget testing, dan integration testing.
Testing atau pengujian adalah hal yang penting ketika mengembangkan sebuah produk berupa aplikasi. Dengan menerapkan testing, kita menjadi lebih percaya diri ketika akan merilis produk atau aplikasi tersebut ke publik karena kita sebagai developer dapat memastikan bahwa aplikasi yang kita kembangkan berjalan dengan baik sesuai yang diharapkan dan memiliki sedikit bugs.
Jenis-Jenis Testing
Metode testing yang umum diimplementasikan pada sebuah aplikasi ada 3 jenis, yaitu:
Unit Testing
Unit testing merupakan jenis testing pada sebuah aplikasi dimana pengujian difokuskan kepada apa yang disebut dengan unit. Unit merupakan bagian terkecil yang membangun sebuah aplikasi. Contoh paling sederhana dari unit ketika kita berbicara tentang OOP (Object-Oriented Programming) adalah Class dan Function. Unit testing akan memastikan komponen-komponen kecil dari sebuah aplikasi berjalan dengan baik dan sesuai dengan ekspektasi.
Untuk melakukan unit testing kita menggunakan fungsi berikut:
test('description', () {});
Contoh implementasi:
Pada kode di atas, kita coba melakukan testing untuk sebuah unit yaitu datasource movie_remote_data_source.dart
untuk mendapatkan data movies dari API. Ada dua skenario yaitu (1) ketika data dari API berhasil didapatkan dan (2) ketika data dari API gagal didapatkan.
Satu blok kode testing secara garis besar terdiri dari 3 bagian yaitu:
- Arrange: yaitu tahap dimana kita menyiapkan objek atau konfigurasi untuk testing (variabel dan nilai-nilai untuk testing). Pada contoh di atas, kita menyiapkan objek mock HTTP Client untuk dapat melakukan simulasi request data dari API saat testing.
Mocking adalah membuat objek tiruan agar dapat digunakan untuk testing tanpa harus memikirkan ketergantungan (dependency) objek tersebut dengan objek lain dalam project.
Library yang digunakan untuk mocking:
- Act: yaitu tahap dimana kita memanggil fungsi yang ingin diuji. Pada contoh di atas, kita memanggil fungsi
getNowPlayingMovies()
yang terdapat pada classMovieRemoteDataSourceImpl
. - Assert: yaitu tahap dimana kita memvalidasi aksi yang telah dijalankan apakah sudah sesuai dengan yang diekspektasikan atau tidak. Pada contoh di atas, ketika data berhasil didapatkan dari API kita memvalidasi hasil dari pemanggilan fungasi
getNowPlayingMovies()
apakah sama dengantMovieList
.
Widget Testing
Widget testing atau dalam istilah lain disebut dengan instrumentation testing merupakan jenis testing yang difokuskan kepada bagian-bagian yang membangun tampilan (User Interface) dari sebuah aplikasi seperti button, text field, dan sebagainya. Widget testing akan memastikan User Interface ditata sesuai dengan UI design aplikasi dan dapat berinteraksi baik dengan pengguna.
Untuk melakukan widget testing kita menggunakan fungsi berikut:
testWidgets('description', (WidgetTester tester) {});
Contoh implementasi:
Proses yang dilakukan pada widget testing masih sama dengan unit testing yaitu arrange, act, dan assert. Perbedaannya adalah di sini kita menguji bagian dari tampilan (User Interface) aplikasi. Pada contoh di atas, kita menguji apakah ketika pengguna menambahkan movie ke watchlist dengan menekan tombol save watchlist maka sebuah SnackBar
akan muncul.
Ketika tampilan atau UI aplikasi menerapkan state management seperti provider, BLoC, dan lainnya kita perlu mendeklarasikannya juga saat proses pump widget.
Integration Testing
Integration testing merupakan jenis testing yang difokuskan untuk menguji keseluruhan jalannya aplikasi (end-to-end testing). Jadi, integration testing seperti gabungan dari widget testing. Untuk menjalankan integration testing dibutuhkan sebuah emulator atau real device. Saat pengujian berlangsung aplikasi akan tampil pada emulator atau real device dan menjalankan aplikasi secara otomatis.
Integration testing sangat membantu untuk menguji bagaimana jalannya sebuah fitur atau seluruh aplikasi saat proses pengembangan. Akan lebih efisien dibandingkan kita harus menjalankan aplikasi dan menguji fitur atau seluruh aplikasi secara manual.
Untuk menerapkan integration testing, kita perlu menambahkan library pada pubspec.yaml
.
dev_dependencies:
...
integration_test:
sdk: flutter
Kemudian pada direktori project, kita perlu membuat sebuah folder baru bernama integration_test
. Contohnya seperti berikut:
integration_test
├── app_test.dart
└── robots
├── home_robot.dart
└── ...
Pada folder tersebut terdapat app_test.dart
yang berisi semua skenario end-to-end testing untuk aplikasi kita. Kemudian ada juga folder robots
yang berisi masing-masing skenario testing. Skenario testing aplikasi dapat dipisahkan (misalnya berdasarkan page).
Contoh implementasi:
Pada home_robot.dart
di atas, kita membuat skenario testing yang ingin diuji pada home page dari aplikasi. Contohnya adalah membuka drawer ketika menekan tombol menu pada AppBar
.
Untuk dapat mengakses widget yang kita tuju, kita dapat menggunakan Key()
. Jadi kita harus mendaftarkan sebuah key
pada widget yang ingin di-testing. Contohnya seperti berikut:
Kemudian kita dapat menggabungkan semua skenario testing ke dalam app_test.dart
.
Sebelum bisa menjalankan integration testing, kita harus memastikan dulu apakah halaman aplikasi sudah muncul dan siap menerima input dengan memanggil fungsi berikut:
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
Untuk menjalankan integration testing, siapkan emulator atau real device. Setelah itu, jalankan command berikut melalui terminal:
flutter test integration_test
Kesimpulan
Ketika mengembangkan aplikasi sebisa mungkin mempertimbangkan untuk melakukan testing. Agar hasil akhir aplikasi dapat terukur dengan baik dan memudahkan pemeliharaan ketika ada fitur yang ingin di-revamp atau fixing. Berikut adalah perbandingan ketiga jenis testing yang sudah dibahas:
Berikut adalah link untuk full-code project ini:
Jadi itu sedikit pembahasan tentang testing pada project aplikasi Flutter. Semoga bermanfaat dan terimakasih! 🙌