Flutter Code Testing Introduction

Dwi Kurnianto
evermos-tech
Published in
5 min readDec 6, 2022

Mulai dari mana ya ? Adalah pertanyaan yang muncul ketika inisialisasi automation testing di Flutter, seringkali programmer tidak tau mulai dari mana, lalu ketika sudah bisa menjawab mulai dari titik A. Muncul pertanyaan kedua coverage ? apa lagi ini 😂, nah kebetulan strategi yang perlu diterapkan Flutter untuk automation testing enggak berbeda jauh dengan strategi testing di bahasa pemrograman mobile lainnya. Dalam test pyramid umum testing akan digambarkan seperti berikut

Dimulai dari lapisan terbawah unit testing, integration testing & E2E testing. Piramida ini bisa juga berbeda tergantung environment & kebutuhan perusahaan, tapi secara umum ini semua sama dengan tujuan yang bisa kita breakdown seperti ini :

  1. Lapisan terbawah unit testing ditujukan untuk menguji kode / program sesuai dengan fungsi nya masing-masing (dengan skenario yang ditentukan sesuai kebutuhan), dengan menggunakan environment yang di simulasikan. Selain itu unit test memiliki kuantitas yang lebih banyak dari lapisan test lainya dikarenakan dalam unit test seringkali diperlukan pembuatan macket / mock & stub file untuk mensimulasikan interfacing dengan dependensi eksternal.
  2. Lapisan integration testing ditujukan untuk menguji seluruh komponen & environment menggunakan skenario yang sesuai acceptance criteria produk / fitur, dengan menggunakan environment yang sebenarnya. Integration test ini merupakan sweet spot dari automation testing karena bisa memastikan integrasi antara komponen dalam aplikasi valid / tidak, selain itu bisa menggambarkan sistem secara general, api, integrasi antara service dll. Selain itu proses eksekusinya ini biasanya cukup cepat, dengan jumlah pengetesan yang lumayan banyak dengan case yang berbeda-beda dan komprehensif.
  3. Lapisan paling atas E2E testing ini adalah testing yang di lakukan melalui interaksi langsung ke UI / user interface oleh penguji, selain itu test ini lebih sedikit dari segi kuantitasnya karena sifat checking Interaksi UI di lakukan secara real time & real environment yang mana waktu untuk menyelesaikan 1 test case terntentu akan bergantung ke environment (waktu load, latency, performance) Selain itu dari segi effort E2E testing ini lebih besar, oleh karena itu biasanya E2E testing di implementasikan pada Regression testing yang di tujukan untuk fitur-fitur yang belum stabil.

Nah selanjutnya dalam Flutter kurang lebih piramidanya dapat berbentuk seperti ini :

Pada piramida testing tersebut, akan lebih mengerucut pada implementasi code testing di Flutter. Pada dasarnya piramida testing ini terdapat lapisan-lapisan yang bisa kita jadikan acuan untuk “Mulai darimana” untuk merealisasikan sebuah automated testing dengan sistematis.

Unit Testing

A unit test tests a single function, method, or class. The goal of a unit test is to verify the correctness of a unit of logic under a variety of conditions. External dependencies of the unit under test are generally mocked out. Unit tests generally don’t read from or write to disk, render to screen, or receive user actions from outside the process running the test Source.

Nah dari referensi di atas kita bisa breakdown karakteristik unit test menjadi seperti ini :

  • Unit test di tujukan untuk menguji logical code
  • Unit test di lakukan menggunakan 1 atau lebih kondisi untuk memverifikasi logical code (Misalnya menguji untuk retrieve data : dengan kondisi sukses, error, dan error yang tidak diharapkan / unexpected error)
  • Dependensi eksternal di buat maket / mock file nya jadi tidak menggunakan dependensi eksternal asli (Contohnya datasource)

Widget Testing

A widget test (in other UI frameworks referred to as component test) tests a single widget. The goal of a widget test is to verify that the widget’s UI looks and interacts as expected. Testing a widget involves multiple classes and requires a test environment that provides the appropriate widget lifecycle context. For example, the Widget being tested should be able to receive and respond to user actions and events, perform layout, and instantiate child widgets. A widget test is therefore more comprehensive than a unit test. However, like a unit test, a widget test’s environment is replaced with an implementation much simpler than a full-blown UI system Source.

Dalam widget test dapat di breakdown menjadi seperti berikut :

  • Widget test di tujukan untuk menguji bagaimana UI ditampilkan sesuai dengan interaksi user dan state data
  • Sama halnya dengan unit test, environment pada widget test tidak menggunakan dependensi eksternal asli dan implementasinya di buat secara sederhana untuk menguji sebuah widget saja

Integration Testing

An integration test tests a complete app or a large part of an app. The goal of an integration test is to verify that all the widgets and services being tested work together as expected. Furthermore, you can use integration tests to verify your app’s performance. Generally, an integration test runs on a real device or an OS emulator, such as iOS Simulator or Android Emulator. The app under test is typically isolated from the test driver code to avoid skewing the results.

Sedangkan dalam integration test dapat di breakdown seperti ini :

  • Integration testing akan melingkupi test UI, service secara end-to-end
  • Integration testing dilakukan pada simulasi ter isolir dengan menggunakan environment sebenarnya
  • Selain itu Integration testing bisa menggunakan test driver code untuk mengetahui hasilnya secara akurat

Manual testing

Nah sedangkan dalam manual testingkarena hampir sebagian besar testing sudah tercover oleh tes yang dilakukan secara automated, manual testing hanya akan melingkupi exploratory test, smoke test dan regression test. Sedangkan untuk tes yang menggunakan kasus / skenario sudah dilakukan secara automated pada lapisan unit, component, dan integration test.

Coverage

Tabel di atas dapat digunakan untuk menentukan coverage dengan tingkat confidence, cost, dependencies, dan speed yang telah ditentukan pada masing-masing proses testing, unit test akan mengcover seluruh logical code layer yang digunakan untuk operasi data, widget test akan melingkupi seluruh operasi widget & page dalam skala yang simpel, dan integration test akan mengcover di mana testing dilakukan menggunakan environment sebenarnya, dengan case skenario yang kita tentukan dan dengan goal yang ditentukan.
Dengan demikian proses testing manual akan berkurang porsinya, sehingga QA akan dapat terfokus terhadap bagian-bagian critical yang tidak tercakup oleh automated testing dan juga melakukan eksploratory test untuk melakukan tidak hanya software testing, tapi juga final product testing untuk bisa menemukan sebuah keambiguan dalam product bila ditemukan. Nah selanjutnya kita akan bahas implementasinya dalam code, stay tune ya !

--

--