Manfaat dan Penerapan TDD

Nurul Faza S.
LEARNFAZZ
Published in
5 min readMar 20, 2019

Test driven development (TDD) adalah pendekatan untuk mengembangkan program secara bertahap dengan terlebih dahulu menulis tes dan kemudian menulis kode yang cukup untuk memenuhi tes tersebut [1]. Pada pendekatan ini, developer harus berpikir terlebih dahulu mengenai hal apa yang bisa dilakukan oleh kode yang akan diimplementasikan [3]. Kemudian, pemikiran tersebut akan dikembangan menjadi sebuah tes yang bisa memastikan bahwa kode tersebut dapat berjalan sesuai dengan keinginan.

sumber : https://www.perforce.com/sites/default/files/image/2018-08/image-blog-alm-what-test-driven-development.jpg

Manfaat TDD

Tentunya, TDD diterapkan karena memiliki manfaat yang dapat membantu kelancaran pengembangan software. Beberapa manfaat dari penerapan disiplin TDD adalah [2] :

  • Desain yang lebih baik — TDD dianggap dalam banyak kasus sebagai proses desain daripada proses testing. Hal ini dikarenakan kode test yang ditulis diawal cenderung lebih kohesif serta mengurangi coupling.
  • Efisiensi — Penggunaan TDD akan mengidentifikasikan kesalahan atau error dengan cepat ketika kode baru ditambahkan ke sistem. Selain itu, dengan menerapkan TDD, kita tidak perlu lagi membuat test setelah implementasi kode selesai. Hal ini memberikan keuntungan sendiri, karena membuat test setelah implementasi kode sudah selesai akan jauh lebih susah dibandingkan menulis test di awal [3].
  • Test assets Test case yang ditulis secara otomatis dalam TDD adalah aset yang berharga bagi proyek. Ketika ada sebuah peningkatan atau modifikasi pada kode, maka menjalankan unit test secara otomatis dapat mengidentifikasi terjadinya cacat/defect baru pada kode.
  • Mengurangi defect injection — Kesalahan lebih rentan terjadi pada saat pemeliharaan kode atau perubahan kode daripada implementasi kode baru. Seringkali, defect injection terjadi pada saat dilakukan pemeliharaan kode. Dengan penggunaan TDD, developer dapat mengetahui apakah perubahan tersebut mengakibatkan kesalahan pada kode yang sudah jadi atau kode yang baru.

Penerapan TDD pada Proyek LearnFazz

sumber : https://user-images.githubusercontent.com/9408641/27683709-e1c5e8c0-5cbe-11e7-99a4-215a5dae63f1.png

Pada proyek LearnFazz diberlakukan penerapan disiplin TDD. Implementasi TTD dapat dilihat pada commits di repository GitLab. Sebuah commit hanya mengandung file-file yang terkait pada suatu pekerjaan yang sama, dan pekerjaan ini biasanya dideskripsikan secara singkat pada commit message. Commit message disertai dengan tag yang menunjukkan tahap dari commit tersebut. Adapun, urutan tersebut adalah sebagai berikut.

Red — membuat kode tes untuk kelas atau fungsi/method kosong yang akan diimplementasikan. Adapun test yang dijalankan masih gagal karena implementasi dari test tersebut belum dilakukan. Diwajibkan terdapat minimal 1 buah commit yang membuat unit test dari setiap class atau fungsi kosong yang telah dibuat.

RED

Green — implementasi kode sudah sesuai dan lulus testing-nya. Commit dipastikan konsekuen dengan hasil test runner di GitLab, sehingga pipeline berhasil/lulus. Diwajibkan terdapat minimal 1 buah commit untuk tag ini.

GREEN

Refactor tag ini digunakan ketika melakukan perbaikan pada kode yang sudah dibuat sebelumnya, tetapi tidak mengubah implementasi yang sudah dilakukan. Commit ini dipastikan dapat membuat pipeline tetap sukses.

REFACTOR

Chores tag ini digunakan jika implementasi yang dilakukan tidak berhubungan dengan fungsionalitas, seperti mengganti atau menambahkan asset berupa image. Implementasi ini tidak memiliki aturan khusus terkait gagal atau sukses-nya pada pipeline.

CHORES

Berikut ini adalah contoh penerapan disiplin TDD pada implementasi User Interface kelas Tile Card.

  • Red — pada commit ini saya membuat kelas kosong untuk implementasi Tile Card.
import ‘package:flutter/material.dart’;class TileCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}

Kemudian saya membuat file test yang berisikan expect terhadap widget-widget yang akan ditampilkan pada Tile Card.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
Widget makeTestableWidget({Widget child}) {
return MaterialApp(
home: child,
);
}
testWidgets('Tile Card Widget Test', (WidgetTester tester) async {
final TileCard card = TileCard();
await tester.pumpWidget(makeTestableWidget(child: card));
// Test Widget
expect(find.byType(RichText), findsNWidgets(10));
expect(find.byType(SizedBox), findsNWidgets(5));
expect(find.byType(InkWell), findsNWidgets(3));
// Test Nonexistent Widget
expect(find.byType(FlatButton), findsNothing);
expect(find.byType(ListView), findsNothing);
});
}
  • Green — pada commit ini, saya telah mengimplementasikan User Interface dari Tile Card dengan widget-widget yang sesuai.
import 'package:flutter/material.dart';const String fullName = 'Daniel D. Ortiz';
const String dateTime = 'Yesterday at 4:59 PM';
class TileCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: CircleAvatar(
child: Text('D', style: TextStyle(fontSize: 25.0),),
radius: 25.0,
),
title: Text(fullName, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0),),
subtitle: Text(dateTime, style: TextStyle(fontSize: 12.0),),
),
],
),
);
}
}
  • Refactor — pada commit ini saya melakukan perbaikan kode dari commit GREEN. Adapun, kode yang saya ubah adalah menambahkan constructor dan instance variables.
import 'package:flutter/material.dart';

class TileCard extends StatelessWidget {
const TileCard({
this.fullName,
this.dateTime,
});

final String fullName;
final String dateTime;

@override
Widget build(BuildContext context) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: CircleAvatar(
child: Text('D', style: TextStyle(fontSize: 25.0),),
radius: 25.0,
),
title: Text(fullName, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0),),
subtitle: Text(dateTime, style: TextStyle(fontSize: 12.0),),
),
],
),
);
}
}
  • Chores — pada commit ini, saya menambahkan margin untuk bagian bawah card. Commit ini tidak berhubungan dengan fungsionalitas.
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.only(bottom: 15.0),
child: Column(
mainAxisSize: MainAxisSize.min,

Referensi :

  1. Gupta, A. & Jalote, P. (2007). An Experimental Evaluation of the Effectiveness and Efficiency of the Test Driven Development. First International Symposium on Empirical Software Engineering and Measurement (ESEM 2007).
  2. Nagappan, N., Maximilien, E.M., Bhat, T. et al. Empir Software Eng (2008) 13: 289. https://doi.org/10.1007/s10664-008-9062-z
  3. Testing & Test-driven Development. GitHub. Web. 20 Maret 2019. https://github.com/foundersandcoders/testing-tdd-intro

--

--