Anda dapat menemukan daftar blog, artikel, dan situs web tanpa akhir yang mempromosikan manfaat unit yang menguji kode sumber Anda. Hampir dijamin bahwa pengembang yang memprogram kompiler untuk Java, C ++, C # dan bahasa yang diketik lainnya menggunakan pengujian unit untuk memverifikasi pekerjaan mereka.
Jadi mengapa, terlepas dari popularitasnya, apakah pengujian absen dari sintaksis bahasa-bahasa ini?
Microsoft memperkenalkan LINQ ke C # , jadi mengapa mereka tidak menambahkan pengujian?
Saya tidak ingin memprediksi perubahan bahasa apa yang akan terjadi, tetapi untuk mengklarifikasi mengapa mereka tidak ada sejak awal.
Sebagai contoh: Kita tahu bahwa Anda dapat menulis sebuah for
loop tanpa sintaks dari for
pernyataan tersebut. Anda bisa menggunakan while
atau if
/ goto
pernyataan. Seseorang memutuskan sebuah for
pernyataan lebih efisien dan memperkenalkannya ke dalam bahasa.
Mengapa pengujian tidak mengikuti evolusi bahasa pemrograman yang sama?
sumber
Jawaban:
Seperti banyak hal, pengujian unit paling baik didukung di tingkat perpustakaan, bukan di tingkat bahasa. Secara khusus, C # memiliki banyak pustaka Pengujian Unit yang tersedia, serta hal-hal yang asli seperti .NET Framework
Microsoft.VisualStudio.TestTools.UnitTesting
.Setiap perpustakaan Unit Pengujian memiliki filosofi dan sintaksis pengujian yang agak berbeda. Semua hal dianggap sama, lebih banyak pilihan lebih baik daripada kurang. Jika pengujian unit dimasukkan ke dalam bahasa, Anda akan dikunci ke dalam pilihan perancang bahasa, atau Anda akan menggunakan ... perpustakaan, dan menghindari fitur pengujian bahasa sama sekali.
Contohnya
Nunit - Tujuan umum, kerangka pengujian unit yang dirancang secara idiomatis yang memanfaatkan fitur bahasa C # sepenuhnya.
Moq - Kerangka mengejek yang memanfaatkan sepenuhnya ekspresi lambda dan pohon ekspresi, tanpa metafora rekaman / pemutaran.
Ada banyak pilihan lain. Perpustakaan seperti Microsoft Fakes dapat membuat "shims ..." mock yang tidak mengharuskan Anda untuk menulis kelas menggunakan antarmuka atau metode virtual.
Linq bukan fitur bahasa (meskipun namanya)
Linq adalah fitur perpustakaan. Kami mendapat banyak fitur baru dalam bahasa C # itu sendiri secara gratis, seperti ekspresi lambda dan metode ekstensi, tetapi implementasi sebenarnya dari Linq ada dalam .NET Framework.
Ada beberapa gula sintaksis yang ditambahkan ke C # untuk membuat pernyataan linq lebih bersih, tetapi gula itu tidak diperlukan untuk menggunakan linq.
sumber
var
kata kunci :)Ada banyak alasan. Eric Lippert telah berkali-kali menyatakan bahwa alasannya
feature X
tidak ada dalam C # adalah karena itu tidak sesuai dengan anggaran mereka. Perancang bahasa tidak memiliki waktu atau uang yang tidak terbatas untuk mengimplementasikan berbagai hal, dan setiap fitur baru memiliki biaya perawatan yang terkait dengannya. Menjaga bahasa sekecil mungkin tidak hanya lebih mudah bagi perancang bahasa - itu juga lebih mudah bagi siapa pun yang menulis implementasi dan alat alternatif (misalnya IDE). Selain itu, ketika sesuatu diimplementasikan dalam hal bahasa daripada bagian dari itu, Anda mendapatkan portabilitas gratis. Jika pengujian unit diterapkan sebagai pustaka, Anda hanya perlu menulisnya sekali dan itu akan berhasil dalam implementasi bahasa yang sesuai.Perlu dicatat bahwa D memang memiliki dukungan tingkat sintaks untuk pengujian unit . Saya tidak tahu mengapa mereka memutuskan untuk melemparkan itu, tetapi perlu dicatat bahwa D dimaksudkan untuk menjadi "bahasa pemrograman sistem tingkat tinggi". Para perancang menginginkannya menjadi layak untuk jenis kode C ++ tingkat rendah yang tidak aman, secara tradisional telah digunakan, dan kesalahan dalam kode tidak aman sangat mahal - perilaku yang tidak terdefinisi. Jadi saya kira masuk akal bagi mereka untuk melakukan upaya ekstra pada apa pun yang membantu Anda memverifikasi bahwa beberapa kode tidak aman berfungsi. Misalnya, Anda dapat memastikan bahwa hanya modul tepercaya tertentu yang dapat melakukan operasi yang tidak aman seperti akses larik yang tidak dicentang atau aritmatika penunjuk.
Pengembangan cepat juga merupakan prioritas bagi mereka, sangat banyak sehingga mereka menjadikannya tujuan desain yang dikompilasi kode D cukup cepat untuk membuatnya dapat digunakan sebagai bahasa scripting. Memanggang unit menguji langsung ke dalam bahasa sehingga Anda dapat menjalankan tes Anda hanya dengan memberikan bendera tambahan ke kompiler membantu dengan itu.
Namun, saya pikir perpustakaan pengujian unit hebat tidak lebih dari sekedar menemukan beberapa metode dan menjalankannya. Ambil QuickCheck Haskell sebagai contoh, yang memungkinkan Anda menguji hal-hal seperti "untuk semua x dan y,
f (x, y) == f (y, x)
". QuickCheck lebih baik dideskripsikan sebagai unit test generator dan memungkinkan Anda untuk menguji hal-hal pada tingkat yang lebih tinggi daripada "untuk input ini, saya mengharapkan output ini". QuickCheck dan Linq tidak jauh berbeda - keduanya merupakan bahasa khusus domain. Jadi, alih-alih mengandalkan dukungan pengujian unit ke bahasa, mengapa tidak menambahkan fitur yang diperlukan untuk membuat DSL praktis? Anda akan berakhir dengan tidak hanya pengujian unit, tetapi bahasa yang lebih baik sebagai hasilnya.sumber
Karena pengujian, dan khususnya pengembangan yang digerakkan oleh pengujian, adalah fenomena yang sangat berlawanan dengan intuisi.
Hampir setiap programmer memulai karir mereka dengan percaya bahwa mereka jauh lebih baik dalam mengelola kompleksitas daripada yang sebenarnya. Fakta bahwa bahkan programmer terbesar tidak dapat menulis program besar dan kompleks tanpa kesalahan parah kecuali mereka menggunakan banyak tes regresi sangat mengecewakan dan bahkan memalukan bagi banyak praktisi. Oleh karena itu kecenderungan umum terhadap pengujian reguler bahkan di kalangan profesional yang seharusnya sudah tahu lebih baik.
Saya pikir fakta bahwa pengujian agama perlahan menjadi lebih utama dan diharapkan sebagian besar disebabkan oleh fakta bahwa dengan ledakan kapasitas penyimpanan dan daya komputasi, sistem yang lebih besar dari yang pernah dibangun - dan sistem yang sangat besar sangat rentan terhadap keruntuhan kompleksitas yang tidak dapat dikelola tanpa jaring pengaman dari uji regresi. Akibatnya, bahkan pengembang yang sangat keras kepala dan tertipu sekarang dengan enggan mengakui bahwa mereka perlu pengujian dan akan selalu perlu pengujian (jika ini terdengar seperti pengakuan pada pertemuan AA, ini cukup disengaja - membutuhkan jaring pengaman secara psikologis sulit untuk diterima bagi banyak orang. individu).
Sebagian besar bahasa populer saat ini berasal dari sebelum pergeseran sikap ini, sehingga mereka memiliki sedikit dukungan bawaan untuk tes: mereka memilikinya
assert
, tetapi tidak memiliki kontrak. Saya cukup yakin bahwa jika tren ini berlanjut, bahasa masa depan akan memiliki lebih banyak dukungan pada bahasa daripada tingkat perpustakaan.sumber
Banyak bahasa yang memiliki dukungan untuk pengujian. C menegaskan adalah tes bahwa program bisa gagal. Di situlah sebagian besar bahasa berhenti, tetapi Eiffel dan baru-baru ini Ada 2012 memiliki preinvarian (hal-hal yang harus dilewati oleh argumen untuk suatu fungsi) dan postinvarians (hal-hal yang harus dilewati oleh fungsi), dengan Ada menawarkan kemampuan untuk merujuk argumen awal di postinvariant. Ada 2012 juga menawarkan tipe invarian, jadi setiap kali sebuah metode dipanggil pada kelas Ada, tipe invarian diperiksa sebelum kembali.
Itu bukan jenis pengujian lengkap yang bisa diberikan kerangka pengujian yang baik kepada Anda, tetapi ini merupakan jenis pengujian penting yang dapat didukung oleh bahasa terbaik.
sumber
Beberapa pendukung bahasa fungsional yang diketik sangat berpendapat bahwa fitur bahasa ini mengurangi atau menghilangkan kebutuhan untuk tes unit.
Dua, imho, contoh bagus untuk ini adalah dari F # untuk Hiburan dan Keuntungan di sini dan di sini
Secara pribadi, saya masih percaya pada nilai unit test, tetapi ada beberapa poin yang valid. Misalnya, jika suatu keadaan ilegal tidak terwakili dalam kode, maka tidak hanya tidak perlu menulis unit test untuk kasus ini, itu tidak mungkin.
sumber
Saya berpendapat bahwa Anda telah melewatkan penambahan beberapa fitur yang diperlukan karena mereka tidak disorot untuk pengujian unit .
Misalnya, pengujian unit dalam C # terutama didorong dengan menggunakan atribut. Fitur Atribut Khusus menyediakan mekanisme ekstensi kaya yang memungkinkan kerangka kerja seperti NUnit untuk beralih dan bersaing, dengan hal-hal seperti pengujian berbasis Teori dan Parameter .
Ini membawa saya ke poin utama kedua saya - kita tidak cukup tahu tentang apa yang membuat testability yang baik untuk membuatnya menjadi bahasa. Laju inovasi dalam pengujian jauh lebih cepat daripada konstruksi bahasa lain sehingga kita perlu memiliki mekanisme yang fleksibel dalam bahasa kita untuk meninggalkan kebebasan untuk berinovasi.
Saya seorang pengguna tetapi tidak fanatik tentang TDD - ini sangat membantu dalam beberapa kasus terutama untuk meningkatkan pemikiran desain Anda. Ini tidak selalu berguna untuk sistem warisan yang lebih besar - pengujian tingkat lebih tinggi dengan data dan otomatisasi yang baik mungkin akan menghasilkan lebih banyak manfaat bersama dengan budaya inspeksi kode yang kuat .
Bacaan lain yang relevan:
sumber