Apakah kita perlu Logging saat melakukan TDD?


40

Saat melakukan siklus Merah, Hijau & Refactor kita harus selalu menulis kode minimum untuk lulus tes. Ini adalah cara saya telah diajarkan tentang TDD dan cara hampir semua buku menggambarkan prosesnya.

Tetapi bagaimana dengan logging?

Jujur saya jarang menggunakan logging dalam aplikasi kecuali ada sesuatu yang benar-benar rumit yang terjadi, namun, saya telah melihat banyak posting yang berbicara tentang pentingnya logging yang tepat.
Jadi selain membuat pengecualian, saya tidak bisa membenarkan pentingnya login dalam aplikasi teruji yang tepat (tes unit / integrasi / penerimaan).

Jadi pertanyaan saya adalah:

  1. Apakah kita perlu login jika kita melakukan TDD? tidakkah tes yang gagal mengungkapkan apa yang salah dengan aplikasi tersebut?
  2. Haruskah kita menambahkan tes untuk proses logging di setiap metode di setiap kelas?
  3. Jika beberapa level log dinonaktifkan di lingkungan produksi misalnya, bukankah itu akan menyebabkan ketergantungan antara tes dan lingkungan?
  4. Orang-orang berbicara tentang bagaimana log memudahkan debugging, tetapi salah satu keuntungan utama tentang TDD adalah bahwa saya selalu tahu apa yang salah karena tes yang gagal.

Apakah ada sesuatu yang saya lewatkan di sana?


5
Saya pikir logging adalah kasus khusus untuk banyak aturan. Kelas / fungsi harus melakukan satu hal dan satu hal saja ... kecuali untuk logging. Fungsi sebaiknya murni, kecuali untuk logging. Begitu seterusnya dan seterusnya. Penebangan melanggar aturan.
Phoshi

1
Bukankah kebanyakan logging ortogonal ke metodologi pengembangan SW yang digunakan? Jadi mungkin Anda harus mempersempitnya dan bertanya: Apakah kita perlu uji kasus untuk logging ketika melakukan TDD?
hyde

Jawaban:


50

1) Apakah kita perlu login jika kita melakukan TDD? tidakkah tes yang gagal mengungkapkan apa yang salah dengan aplikasi tersebut?

Itu mengasumsikan Anda memiliki setiap kemungkinan tes kebutuhan aplikasi Anda, yang jarang benar. Log membantu Anda melacak bug yang belum Anda tulis tesnya.

2) Haruskah kita menambahkan tes untuk proses logging di setiap metode di setiap kelas?

Jika logger itu sendiri diuji, itu tidak perlu diuji ulang di setiap kelas, mirip dengan dependensi lainnya.

3) Jika beberapa level log dinonaktifkan di lingkungan produksi misalnya, bukankah itu akan menyebabkan ketergantungan antara pengujian dan lingkungan?

Manusia (dan agregator log) bergantung pada log, pengujian tidak harus bergantung pada mereka. Biasanya ada beberapa level log, dan beberapa digunakan dalam produksi, dan beberapa level tambahan digunakan dalam pengembangan, mirip dengan:

"Level log rel adalah info dalam mode produksi dan debug dalam pengembangan dan pengujian" - http://guides.rubyonrails.org/debugging_rails_applications.html

Aplikasi lain menggunakan pendekatan serupa.

4) Orang berbicara tentang cara memudahkan debugging log, tetapi salah satu keuntungan utama tentang TDD adalah bahwa saya selalu tahu apa yang salah karena tes yang gagal.

Bug produksi akan telah lulus semua tes, jadi Anda mungkin perlu referensi lain untuk menyelidiki masalah tersebut.


26
Bahkan TDD yang dijalankan dengan sempurna dan sempurna tidak akan mencegah masalah produksi dengan kinerja, interaksi sistem, interaksi pihak ketiga. Masalah konkurensi juga sangat sulit untuk sepenuhnya ditutupi oleh tes. Cakupan uji 100% "hanya" berarti 100% kode Anda telah dieksekusi, bukan yang benar di semua negara bagian atau lingkungan.
Holstebroe

34

Logging berguna untuk menjelaskan perilaku aplikasi yang tidak biasa:

Log peristiwa mencatat peristiwa yang terjadi dalam pelaksanaan suatu sistem untuk menyediakan jejak audit yang dapat digunakan untuk memahami aktivitas sistem dan untuk mendiagnosis masalah. Mereka sangat penting untuk memahami kegiatan sistem yang kompleks, terutama dalam kasus aplikasi dengan sedikit interaksi pengguna (seperti aplikasi server ) ...

Tidak peduli bagaimana aplikasi diuji dan tidak peduli seberapa baik pengecualian dicatat, para penggunanya mungkin bertanya,

output dari program Anda adalah 0 sementara kami mengharapkannya menjadi 1, mengapa begitu?

Anda perlu mencatat untuk memverifikasi apa itu konfigurasi aplikasi, parameter, dan detail runtime lainnya untuk menjelaskan perilakunya (tidak biasa).

Dari perspektif di atas, penebangan lebih berorientasi pada dukungan daripada pada pembangunan. Setelah aplikasi ditayangkan, diinginkan untuk membiarkan orang lain menangani pertanyaan dari pengguna, untuk memungkinkan pemrogram fokus pada pengembangan lebih lanjut.

Mencatat aplikasi apa yang memungkinkan orang lain memahami perilaku program tanpa menggali ke dalam kode dan tanpa mengganggu pengembang dengan permintaan untuk menjelaskan apa yang terjadi.


5
+1 untuk "logging lebih berorientasi pada dukungan". Benar-benar memukul paku di kepala.
Tibos

1
+1 untuk "perilaku tidak biasa" dan juga untuk "logging lebih berorientasi pada dukungan". Tetapi bisakah Anda mengedit jawaban Anda untuk mencantumkan sumber paragraf yang Anda kutip?
logc

Sumber kutipan @logc disebut oleh tautan di kata pertama di sini, "Logging" - jika Anda mengkliknya, Anda akan dibawa ke artikel Wikipedia: en.wikipedia.org/wiki/Logfile
gnat

16

Sebagian besar jawaban di sini fokus pada aspek kebenaran. Tetapi logging juga memiliki tujuan yang berbeda: Penebangan dapat menjadi cara untuk mengumpulkan data yang relevan dengan kinerja. Jadi, bahkan ketika sistem bekerja tanpa kesalahan, log dapat memberi tahu mengapa itu lambat. Bahkan dengan cakupan uji penuh dari semua aspek, test suite tidak akan memberi tahu.

Tentu saja sistem kritis kinerja dapat / harus menyediakan metrik kinerja utama untuk beberapa dasbor operasional, tetapi pencatatan "klasik" dapat memberikan tingkat detail yang berbeda.


2
Juga jangan lupa tentang pendataan untuk tujuan jejak audit. Atau tagihan. Atau berbagai macam statistik. Atau pencatatan peristiwa untuk mencocokkan dengan jenis statistik lain dari sistem lain.
PlasmaHH

Bukankah membuat profil sesuatu yang akan Anda lakukan tanpa login? Atau apakah Anda hanya bermaksud bahwa Anda dapat terus mencatat hasil pembuatan profil?
Bergi

@Bergi: sepenuhnya tergantung pada cara kerja aplikasi Anda. Jika misalnya aplikasi web maka pencatatan waktu layanan dari setiap permintaan, dan kemudian mencoba mengelompokkan acara-acara tersebut untuk "orang yang berkinerja buruk" juga dapat bekerja.
PlasmaHH

Pemrofilan @Bergi terjadi dalam pengembangan, tetapi ada efek pada sistem langsung yang perlu diingat, menggunakan disk dapat menjadi lambat, CPU dapat lebih dimuat, layanan mungkin tidak merespons dalam waktu, utas paralel mungkin mengalami masalah penguncian ...
johannes

Audit @PlasmaHH adalah bagian dari persyaratan inti dan harus dicakup oleh tes. Dalam kebanyakan kasus, saya tidak menjalankannya pada rute logging "normal". Pencatatan normal mungkin gagal, audit tidak. "berbagai statistik" Saya berkumpul di bawah kinerja;)
johannes

8

Jawaban singkat untuk pertanyaan utama Anda adalah: sebagai aturan umum, bug dalam kode Anda TIDAK akan diekspos oleh TDD. Beberapa mungkin, idealnya banyak, tetapi tidak adanya tes gagal tidak menyiratkan tidak adanya bug. Ini adalah pepatah yang sangat penting dalam pengujian perangkat lunak.

Karena Anda tidak dapat mengetahui apakah Anda akan memiliki perilaku yang salah dalam sistem Anda, mungkin di bawah kondisi yang jarang terjadi, pencatatan adalah alat yang berguna yang dapat membantu memahami apa yang salah ketika segala sesuatu pasti salah.

Penebangan dan TDD mengatasi masalah yang berbeda.


7
  1. Kecuali jika Anda memiliki tes penutup 100%, yang biasanya tidak demikian, Anda tidak dapat mengetahui bahwa perangkat lunak Anda tidak akan pernah macet (EDIT: dan - seperti yang dikatakan dalam komentar - bahkan jika itu terjadi, sesuatu yang independen dari perangkat lunak Anda mungkin menyebabkan kecelakaan); itu sama dengan berpikir Anda dapat melakukan perangkat lunak yang sama sekali tidak memiliki bug (bahkan NASA tidak dapat melakukan ini). Jadi, paling tidak, Anda harus mencatat kemungkinan kegagalan jika program Anda macet sehingga Anda bisa tahu sebabnya.

  2. Pencatatan harus dilakukan oleh perpustakaan eksternal atau kerangka kerja magang tergantung pada teknologi yang Anda gunakan. Yang saya maksudkan adalah bahwa itu haruslah sesuatu yang telah diuji sebelumnya dan Anda tidak perlu menguji diri Anda sendiri. Sangatlah sulit untuk menguji bahwa setiap metode mencatat hal-hal yang seharusnya.

  3. Log tidak dimaksudkan untuk tes, seharusnya tidak ada ketergantungan sama sekali. Yang mengatakan, Anda tidak perlu menonaktifkan logging untuk tes jika terasa seperti kendala bagi Anda, meskipun log harus disimpan dalam file yang sesuai dengan lingkungan (Anda harus memiliki file yang berbeda untuk lingkungan pengujian, pengembangan dan produksi setidaknya).

  4. Kesalahan mungkin sangat tidak jelas dan tidak selalu jelas apa yang salah ketika satu tes TDD gagal. Log harus lebih tepat. Misalnya, jika Anda melakukan algoritme pengurutan dan seluruh kasus uji gagal, Anda harus memiliki log untuk setiap tes algoritma yang membantu Anda melihat di mana masalahnya sebenarnya.


3
Bahkan jika Anda memiliki cakupan 100%, apakah Anda memilikinya untuk setiap hal yang mungkin terjadi? Bagaimana jika koneksi jaringan ke basis data Anda turun? Apakah tes Anda akan memberi tahu Anda hal itu?
Zachary K

Anda tidak akan pernah tahu perangkat lunak Anda tidak akan pernah crash BAHKAN jika Anda memiliki cakupan 100%. Cakupan 100%, meskipun diinginkan, memberikan jauh lebih sedikit informasi tentang kebenaran daripada kelihatannya.
Andres F.

Ya, Anda benar tentang itu juga. Intinya, tidak memiliki kemungkinan crash tidak dapat dilakukan. Saya akan mengedit.
Pierre Arlaud

1
Hasil edit masih salah. Bahkan jika Anda memiliki cakupan uji 100%, mungkin ada bug dalam kode Anda (tidak perlu menyalahkan penyebab eksternal). Tes TIDAK menyiratkan pekerjaan kode Anda; satu-satunya hal yang mereka nyatakan dengan pasti adalah bahwa Anda gagal menulis tes yang menemukan bug :) Cakupan tes adalah metrik penting, tetapi tidak terkait langsung dengan tidak adanya bug.
Andres F.

3
Itu sepele untuk membuktikan bahwa "100% cakupan tes yang lolos! = Bebas bug". Contoh balasan: add(x, y) = 2(selalu mengembalikan 2). Tes berikut melewati dan menyediakan cakupan penuh: assert(2 == add(1,1)). Cakupan tes 100% untuk fungsi kereta :)
Andres F.

5

Ya, dalam kasus umum Anda perlu masuk.

Logging bukan tentang debugging. Baiklah, sebagian logging terkadang tentang debugging, dan Anda bisa melewati bagian itu jika Anda tidak membutuhkannya selama pengembangan.

Tetapi bagian yang lebih penting dari penebangan adalah tentang kelestarian. Pencatatan yang dirancang dengan baik mungkin menjawab pertanyaan-pertanyaan berikut:

  • Apakah aplikasi masih hidup dan menendang? (Dengan mencatat detak jantung setiap 1000 detik.)
  • Apakah kinerja aplikasi berubah selama 10 bulan terakhir? (Dengan mencatat statistik kinerja kasus penggunaan.)
  • Apakah beban aplikasi berubah selama 10 bulan terakhir? (Dengan mencatat jumlah permintaan per jenis permintaan.)
  • Apakah ada antarmuka kami yang mengubah karakteristik kinerjanya?
  • Apakah rilis baru menyebabkan karakteristik penggunaan yang berbeda terhadap beberapa subsistem?
  • Apakah kita sedang diserang DoS ?
  • Jenis kesalahan apa yang terjadi?

Semua ini dapat dicapai dengan login. Dan ya, itu harus direncanakan dan dirancang dan diuji, lebih disukai otomatis.

Logging adalah fitur yang pantas mendapatkan perawatan, sama seperti fitur lainnya.


4

TL; DR: Penebangan dan TDD bersifat orthogonal. Memiliki satu tidak ada hubungannya dengan kebutuhan yang lain

Apakah kita perlu login jika kita melakukan TDD? tidakkah tes yang gagal mengungkapkan apa yang salah dengan aplikasi tersebut?

Sebagian besar pencatatan yang telah saya implementasikan, dan yang saya lihat telah diterapkan adalah untuk mengatasi masalah operasional, bukan untuk debugging pengembangan (walaupun mungkin membantu). Audiens utama untuk pencatatan ini adalah admin dan ops yang menjalankan server Anda, mendukung orang-orang yang memiliki log yang dikirimkan kepada mereka untuk dianalisis, dan pelanggan yang ingin melihat log dan mencoba serta mencari tahu apa yang terjadi.

Log ini ada untuk membantu memecahkan masalah yang sebagian besar dilakukan ke titik integrasi. Ini dapat berupa layanan jaringan (basis data, sabun, dll.), Sumber daya lokal (disk, memori, dll), data buruk (input pelanggan, sumber data buruk / korup, dll), dll. Menangkap pengecualian, kesalahan pencatatan, dan bahkan melakukan pencatatan informatif (pengaturan, konfigurasi, dll.) dapat membantu mengatasi masalah.

Haruskah kita menambahkan tes untuk proses logging di setiap metode di setiap kelas?

Tambahkan pengujian di mana pun Anda perlu untuk menguji logging. Jika Anda memiliki panggilan ad hoc untuk keluar informasi maka mereka harus diuji. Meskipun jika Anda menerapkan logging dan pengujian log menggunakan Pemrograman Berorientasi Aspek atau pemrograman meta, itu dapat mengurangi beban pengujian.

Jika beberapa level log dinonaktifkan di lingkungan produksi misalnya, bukankah itu akan menyebabkan ketergantungan antara tes dan lingkungan?

Jika Anda menulis kode menggunakan IoC dan menggunakan tiruan, Anda harus dapat menguji semua penebangan Anda secara efektif tanpa bergantung pada pengaturan lingkungan tertentu.


3

TDD umumnya membantu mengurangi bug pengkodean. Ini membantu jauh lebih sedikit dengan bug dengan spesifikasi atau hanya kesalahpahaman tentang cara kerja.

"Oh? Kamu bisa mendapatkan pesan data sebelum mendapat konfirmasi bahwa logon berhasil? Aku tidak pernah tahu itu, yah itu tidak akan menangani itu!" ... Hal semacam itu. Logging sangat berguna untuk memberi tahu Anda apa yang coba dilakukan perangkat lunak sehingga Anda dapat menemukan kesalahan yang Anda lakukan.


2

Dalam pengalaman saya, tingkat logging yang hebat ditambahkan ke aplikasi ketika kita tidak melakukan TDD. Kemudian tingkat ketidakpastian menjadi tinggi maka kami menambahkan logging untuk melihat apa yang terjadi.

Sedangkan ketika melakukan TDD (atau mungkin menguji kapanpun) saya mendapati diri saya menambahkan lebih sedikit pernyataan log. Ini pada gilirannya berarti lebih sedikit LOC dan dapat (tidak selalu) mempengaruhi kinerja.

Tapi kami memang menambahkan log yang keluar-masuk untuk fungsi secara semi-otomatis di perusahaan saya dalam banyak kasus terlepas dari metode pengembangan. Seperti yang saya tahu ini dianggap wajib untuk analisis masalah produksi.

Contoh bisa menjadi metode kacang layanan EJB yang hadir di antarmuka publik. Lain mungkin kasus ketika fungsi melakukan perhitungan yang rumit. Ini dapat membantu banyak untuk memiliki angka memasuki metode (misalnya Anda dapat menulis tes unit untuk kembali ke topik umum yang ada).


dapatkah Anda memperluas alasan mengapa Anda menambahkan masuk-keluar log untuk fungsi? mengapa ini diperlukan di perusahaan Anda?
nyamuk

ya, tentu saja. Saya harap ini lebih baik sekarang.
dbalakirev
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.