Jawaban saya kepada mereka yang percaya bahwa nilai TDD berlebihan

Suatu kali saya berbicara dengan pengembang dari perusahaan klien tentang perangkat lunak. Saya harus memahami bahwa percakapan tidak beres ketika lawan bicara mengatakan tentang bagaimana kami, para pengembang perangkat lunak, beruntung: "Kami menipu organisasi agar membayar kami untuk pekerjaan yang tampaknya sederhana." Tidak masalah seberapa banyak seseorang telah mahir dalam menulis kode, tetapi saya percaya bahwa tidak layak berbicara tentang seluruh industri pengembangan perangkat lunak sebagai sesuatu seperti sekelompok scammers.

Saya tidak fokus pada hal ini, percakapan menjadi Agile. Klien, secara umum, terbuka terhadap gagasan menguji metodologi baru dan meningkatkan proses kerja mereka. Tapi - hanya sampai saya menyebutkan pengembangan melalui pengujian (TDD, Test-Driven Development). Satu-satunya jawaban untuk ini adalah frasa berikut: "Nilai TDD dibesar-besarkan."



Tidak hanya itu menyakitkan bagi saya untuk mendengarnya, tetapi itu membuat saya menyadari bahwa TDD adalah salah satu dari metodologi Agile yang mungkin terlihat seperti sesuatu seperti "legenda urban". Inilah yang membuat saya menulis materi ini, di mana saya ingin menarik bagi mereka yang meragukan nilai TDD.

Apa itu TDD?


Biarkan saya mulai dengan mendefinisikan TDD. Ini adalah strategi pengembangan perangkat lunak, selama implementasi, ketika membuat program, mereka sepenuhnya dipandu oleh penulisan tes. Bahkan, ini bisa dimengerti dari nama metodologi ini. Gagasan ini diusulkan oleh Kent Beck dalam bukunya Development Through Testing, yang ditulis pada tahun 2003. Menggunakan TDD melibatkan tiga langkah berikut:

  1. Menulis tes yang gagal untuk sebagian kecil fungsi.
  2. Implementasi fungsional yang mengarah pada kelulusan tes.
  3. Refactoring kode lama dan baru untuk mempertahankannya dalam keadaan terstruktur dan mudah dibaca.

Proses ini juga dikenal sebagai siklus "Merah, Hijau, Refactoring".

Berikut adalah contoh sederhana menggunakan TDD. Di sini kita ingin menulis sebuah metode dalam Python yang dirancang untuk menghitung variabel Coleh teorema Pythagoras.

Berikut adalah kode uji (file test.py):

#!/usr/bin/env python

"""
test.py
"""

import unittest

from main import *

class TestDrivenDevelopment(unittest.TestCase):

        def test_pythagorean_theorem(self):
                a, b = 3, 4
                self.assertEqual(calculate_side_c(a, b), 5)

if __name__ == '__main__':
    unittest.main()

Berikut adalah kode metode ( main.py), di mana tidak ada yang terjadi sejauh ini:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return True

Sekarang coba jalankan tes.


Tes gagal (bagian "Merah" dari siklus TDD)

Menulis ulang kode, membawa kontenmain.pyke bentuk berikut:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    c_squared = (side_a * side_a) + (side_b * side_b)
    c = c_squared ** 0.5
    return c 

Jalankan tes lagi.


Tes berjalan dengan baik (bagian "Hijau" dari siklus TDD)

Sekarang kitamain.pyrefactorkode:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return ((side_a ** 2) + (side_b ** 2)) ** 0.5


Tes ini berhasil untuk kode yang dikenakan refactoring (Bagian "Refactoring" dari siklus TDD)

17 tahun telah berlalu sejak penerbitan buku pengembangan melalui pengujian. Tetapi bahkan hari ini, pada tahun 2020, masih belum ada jawaban pasti untuk pertanyaan yang sangat penting bagi banyak orang tentang apakah manfaat TDD sepadan dengan waktu dan upaya untuk mengimplementasikan metodologi ini. Akibatnya, banyak pengembang bahkan tidak mencoba mengembangkan melalui pengujian.

Untuk mendukung TDD, saya bertanya kepada pengembang mengapa mereka tidak menggunakan metodologi ini. Inilah 4 jawaban yang paling sering saya dengar:

  1. Kami memiliki departemen QA. Tes menulis adalah tugas mereka.
  2. Membuat tes di mana moki dan bertopik mungkin diperlukan dapat mengambil banyak waktu dan energi.
  3. TDD tidak memiliki keunggulan dibandingkan pengembangan konvensional.
  4. TDD lambat.

Mari kita menganalisis ide-ide ini.

Kami memiliki departemen QA. Tes menulis adalah tugas mereka


Ini jawaban atas pertanyaan saya tentang mengapa seseorang tidak menggunakan TDD akan selalu membuat saya tertawa sedikit. Saya adalah pendukung besar prinsip " Anda membangunnya, Anda menjalankannya ", ketika orang yang menulis kode bertanggung jawab untuk itu. Oleh karena itu, saya terganggu ketika saya melihat bahwa pengembang berperilaku seolah-olah hanya tugas mereka adalah menulis kode fungsional.

Saya sangat yakin bahwa pengembang bertanggung jawab untuk memastikan bahwa kode mereka memiliki kualitas berikut:

  • Kebenaran - memenuhi kebutuhan bisnis.
  • Jelasnya.
  • Testabilitas.
  • Kemungkinan diperpanjang.
  • Kesederhanaan.

Pemindahan tugas penulisan tes ke departemen QA, saya percaya, tidak termasuk dalam daftar tanggung jawab pekerjaan pengembang. Spesialis departemen QA memiliki masalah yang lebih penting. Mereka seharusnya tidak menghabiskan waktu kerja mereka, terutama, untuk menguji kode menggunakan metode "kotak hitam".

Membuat tes di mana moki dan bertopik mungkin diperlukan dapat mengambil banyak waktu dan energi


Saya mengerti perasaan mereka yang mengatakan demikian. Misalnya, Anda perlu menerapkan metode yang mengambil tiga nilai input berbeda. Masing-masing dari mereka adalah objek, dan masing-masing objek ini tidak memiliki atribut opsional. Semua ini perlu diuji dengan memeriksa opsi yang berbeda untuk metode ini. Untuk melakukan ini, Anda perlu mengkonfigurasi rintisan dan moka , serta menulis sejumlah besar kode tambahan. Dan semua ini hanya untuk menguji satu metode. Saya sudah berada dalam situasi yang sama. Namun, saya melihat semua ini dari perspektif lain.

Ketika saya berpikir tentang mengurangi upaya dan waktu yang dihabiskan untuk menulis tes, saya datang dengan prinsip-prinsip pemrograman SOLID dan piramida pengujian.

Mulai dengan SOLID dari sini.. Di sini, saya ingin mengingat fakta bahwa dalam singkatan SOLID diwakili oleh huruf S, yaitu, pada prinsip tanggung jawab tunggal (Prinsip Tanggung Jawab Tunggal). Ini adalah ide yang menurutnya metode dan kelas harus menyelesaikan hanya satu masalah. Mereka harus berfungsi sehingga kegiatan mereka tidak mempengaruhi sisa sistem.

Saya mengerti bahwa sebagian besar metode dalam perangkat lunak perusahaan melakukan tugas yang lebih sulit daripada menemukan jumlah beberapa angka yang diteruskan ke metode ini. Tetapi orang tidak dapat menyangkal fakta bahwa penggunaan metode yang ditujukan untuk menyelesaikan satu masalah dalam suatu proyek sangat memudahkan pengujian.

Mari kita bicara tentang piramida pengujian.


Pengujian piramida (gambar diambil dari sini )

Piramida pengujian sering digunakan untuk menemukan rasio yang benar dari berbagai jenis tes dalam suatu proyek.

Tes antarmuka pengguna (Tes UI) dan tes layanan (Uji Layanan) memerlukan cukup banyak waktu untuk penerapannya. Oleh karena itu, sebagian besar pengujian harus diwakili oleh tes unit (Tes Unit), karena dibutuhkan milidetik untuk menjalankan bahkan sejumlah besar tes tersebut. Ini, tentu saja, membantu meningkatkan loop umpan balik, yang merupakan salah satu tujuan utama DevOps.

Melakukan pengujian unit untuk menguji beberapa bagian kecil dari sistem juga memerlukan tingkat integrasi yang jauh lebih rendah dengan sistem lainnya. Ini membuat penulisan tes seperti itu lebih mudah. Metodologi TDD dirancang khusus untuk penggunaan tes unit.

Tentu saja, segala sesuatu lebih mudah diucapkan daripada dilakukan, dan untuk menulis sebagian besar tes, bahkan tes unit, Anda perlu berusaha. Namun, jika tampaknya menulis tes unit membutuhkan terlalu banyak upaya, Anda dapat menguji diri sendiri dengan mengajukan beberapa pertanyaan kepada diri sendiri:

  • Apakah ini tes modular, atau haruskah dianggap sebagai tes tingkat yang lebih tinggi, sebagai tes layanan?
  • Apakah kode dirancang dengan baik, apakah masing-masing kelas dan metode konsisten dengan prinsip tanggung jawab tunggal (apakah kodenya sangat erat)?

Jika ternyata tes menulis membutuhkan terlalu banyak waktu dan upaya, maka paling sering ini menunjukkan bahwa kode dapat dan mungkin perlu di refactored.

TDD tidak memiliki keunggulan dibandingkan pengembangan konvensional


Ironisnya, fakta bahwa TDD tidak memiliki keunggulan dibandingkan pengembangan konvensional dikatakan terutama oleh para programmer yang bahkan belum mencoba bekerja dengan gaya TDD. Tetapi sampai Anda mencoba sesuatu, Anda tidak dapat memahami apakah ini baik atau buruk. Bahkan band Coldplay tahu bahwa "jika kamu tidak pernah mencoba kamu tidak akan pernah tahu."

TDD memiliki dua kekuatan utama.

Keuntungan pertama TDD cukup jelas. Jika, sebelum menulis kode kerja, seseorang selalu menulis tes untuk kode ini, maka, menurut definisi, programmer selalu memiliki kode pengujian sendiri yang dapat digunakannya.. Inilah yang ditulis Martin Fowler tentang ini: "Anda memiliki kode pengujian sendiri jika Anda dapat menjalankan serangkaian tes otomatis pada basis kode dan, setelah berhasil menyelesaikan tes, Anda dapat yakin bahwa kode tersebut bebas dari cacat yang signifikan."

Dengan kata lain, menggunakan TDD berarti bahwa kode bekerja persis seperti yang dibutuhkan oleh programmer.

Ini adalah fakta yang luar biasa, karena memberikan kepercayaan serius pada stabilitas kode untuk setiap perubahan yang merugikan. Penggunaan TDD memungkinkan programmer untuk segera mengetahui apakah sesuatu dalam basis kode telah memburuk sebagai akibat dari refactoring atau perpanjangan kode. Lebih baik lagi, ini memberi tahu Anda jika ada kesalahan dalam sistem.

Kode swa-uji memungkinkan tim pengembangan untuk benar-benar memanfaatkan manfaat integrasi berkelanjutan dan sistem penerapan kode.

Keuntungan utama kedua TDD adalah bahwa metodologi pengembangan ini membuat pemrogram, bahkan sebelum menulis kode kerja, berpikir tentang apa yang akan mereka tulis dan bagaimana mereka akan menulisnya.

Memikirkan kode sebelum menulis itu mengarah pada fakta bahwa pengembang benar-benar tenggelam dalam esensi dari kebutuhan bisnis dan memperhitungkan kasus batas akun dan kemungkinan kesulitan di muka ketika menerapkan mekanisme yang sesuai. Akibatnya, saat menulis kode kerja, upaya dihabiskan untuk apa yang Anda butuhkan. Selain itu, penggunaan TDD mengarah pada fakta bahwa pengembang sedang merencanakan sistem perangkat masa depan dalam hal struktur dan arsitektur mereka. Jika hal-hal seperti itu direncanakan dan diperhitungkan sejak awal bekerja pada sistem, ini akan secara serius meningkatkan kemampuannya untuk meningkatkan dan memperluas.

TDD lambat


Pengembang yang mengatakan bahwa TDD lambat, biasanya mereka yang telah bekerja menggunakan metodologi ini untuk sementara waktu, dan kemudian kembali menulis tes yang dieksekusi setelah kode dibuat. Secara umum, ini adalah alasan yang paling sering disebut ketika berbicara tentang mengapa seseorang tidak menggunakan TDD.

Saya juga bisa mengerti mengapa programmer berpikir demikian. Memikirkan kode sebelum menulis itu membutuhkan waktu. Waktu dihabiskan untuk membuat tes untuk semua yang direncanakan untuk dilaksanakan, bahkan untuk metode yang, dalam kondisi normal, tes mungkin belum ditulis. Menemukan cara untuk secara efektif menggunakan bertopik dan massa juga terkadang bukan tugas tercepat dan paling menyenangkan.

Situasi ini juga diperparah oleh kenyataan bahwa produktivitas dan efisiensi programmer sering dievaluasi dalam hal kecepatan pekerjaan mereka dan waktu yang dihabiskan untuk membuat produk jadi. Semua ini mendorong tim programmer ke keinginan untuk bekerja secepat mungkin, ke keinginan untuk masuk ke dalam jadwal kerja yang ketat.

Dalam tulisan ini sistem empat indikator untuk menilai efektivitas DevOps:

  1. Frekuensi Penempatan.
  2. Ubah waktu eksekusi.
  3. Waktu pemulihan layanan.
  4. Frekuensi kegagalan dengan perubahan.

Saya sangat tertarik dengan indikator "Frekuensi Penempatan" dan "Frekuensi Kegagalan dengan Perubahan".

Saat menggunakan TDD, seperti yang saya katakan, berdasarkan asumsi bahwa sistem dibangun secara eksklusif menggunakan TDD, tim pengembangan, segera setelah melakukan perubahan pada sistem, akan tahu jika perubahan ini tidak mempengaruhi kinerja dari setiap dari bagian-bagian sistem. Selain itu, penggunaan TDD meningkatkan kecepatan menemukan kesalahan. Fakta bahwa tes dirancang untuk menguji fragmen kode yang sangat kecil memungkinkan Anda untuk dengan cepat mengetahui tempat proyek di mana kegagalan terjadi. Ini mengarah pada fakta bahwa kesalahan lebih kecil kemungkinannya terdeteksi dalam versi terbaru dari sistem yang sudah dikerahkan, yang mengurangi tingkat "Tingkat kegagalan selama perubahan".

Fakta bahwa tim pengembangan akan memiliki tingkat kepercayaan yang tinggi dalam keberlanjutan proyek dan dalam pekerjaan yang benar berarti bahwa tim dapat memutuskan apakah akan menyebarkan proyek ketika tes selesai dengan sukses. Adakah yang melakukan penyebaran proyek sesuai permintaan?

Proyek Phoenix mencakup empat jenis pekerjaan. Salah satunya adalah Pekerjaan Tidak Terduga. Pekerjaan seperti itu harus dilakukan ketika pengembang harus mengalihkan pikiran mereka dari apa yang mereka lakukan dan melakukan sesuatu yang lain. Biasanya koreksi dari beberapa jenis kesalahan. Jika proyek dibangun dari kode swa-uji, ini meminimalkan jumlah kesalahan. Ini, pada gilirannya, mengarah pada minimalisasi jumlah "pekerjaan tak terduga". Dan semakin sedikit "kejutan" dalam kehidupan pengembang - semakin dia merasa dan semakin produktif dan semakin baik dia bekerja.

Jika pengembang tidak terlalu khawatir tentang bug dalam produksi, ini berarti mereka dapat mencurahkan lebih banyak waktu untuk mengembangkan fungsionalitas baru yang bermanfaat dari produk. Dan jika pengembang memikirkan kode sebelumnya, menerapkan prinsip-prinsip yang berguna seperti SOLID dan terus terlibat dalam refactoring, ini meminimalkan jumlah "utang teknis". Ketika sebuah tim yakin dengan fungsionalitas dan kualitas kode, tim dapat benar-benar menggunakannya dalam dua hal. Semua ini meningkatkan kecepatan kerja.

Ringkasan


Seperti alat lainnya, seperti pendekatan pengembangan lainnya, metodologi TDD mungkin tampak canggung pada awalnya. Dan sebelum programmer benar menguasai metodologi ini, mungkin tampak agak lambat bagi mereka. Apa yang bisa kukatakan? Mengutip Jez Humble: "Jika sesuatu menyebabkan ketidaknyamanan, lakukan lebih sering dan Anda bisa mengatasinya."

Dan sekarang saya sarankan Anda berlatih metodologi TDD dan melakukannya sampai TDD berhenti menyebabkan Anda tidak nyaman :)

Pembaca yang budiman! Apakah Anda menggunakan metodologi TDD saat mengerjakan proyek Anda?

Source: https://habr.com/ru/post/undefined/


All Articles