pengantar
Baik di sini maupun di tempat lain di web ada banyak sekali artikel yang mempromosikan pengujian otomatis secara umum dan pengujian unit pada khususnya. Artikel menjelaskan manfaat pengujian, menggunakannya untuk menghilangkan kode rapuh, meningkatkan kualitas, bermigrasi dari sistem lama ke yang baru, refactoring. Dan, pada saat yang sama, hampir tidak ada yang menyebutkan kekurangan mereka di mana pun, dan tidak ada "peluru perak" dalam rekayasa!
Sebenarnya, ada "peluru perak", tetapi mereka ditemukan oleh para insinyur pertama, dan mereka dianggap oleh kami sebagai kata-kata hampa yang membosankan: "cuci tangan sebelum makan", "hapus kakimu", "strukturkan kodenya", " jangan menulis tanpa lekukan", "melokalkan status", dll. Namun demikian, tes bukanlah "peluru perak", tetapi salah satu alat yang paling efektif dan banyak digunakan, yang berarti memiliki kekurangan.
Dalam posting ini saya akan mencoba menyusun dan menuliskan dengan tepat kekurangan tes, terutama tes unit. Saya akan mencoba untuk tidak menulis tentang manfaatnya, karena sudah ada begitu banyak materi tentang ini, ulurkan tangan Anda. Tentu saja, di suatu tempat saya pasti akan melupakan sesuatu yang penting, dan di suatu tempat saya akan melebih-lebihkan. Oleh karena itu, tolong anggap artikel ini lebih seperti ajakan untuk berbicara daripada sesuatu yang selesai. Dari sudut pandang saya, topiknya cukup matang, dan oleh karena itu saya sangat ingin membahasnya secara rinci.
Mengapa pemrograman fungsional? Jadi kami menguji hampir secara eksklusif fungsi.
Selamat tinggal ilusi atau 33 basa-basi
Secara umum, bukan rahasia lagi bahwa cakupan pengujian 100% pun tidak menjamin perilaku program yang benar. Sebagai contoh, mari kita lihat kodenya:
def f( a, b):
x = 0
if a:
x += 2
else:
x += 0
if b:
x += 2
else:
x += 0
return x
#
assert f(True, False) == 2
assert f(False, True) == 2
Kami melewati semua cabang, semuanya baik-baik saja, tetapi apakah kami telah membuktikan bahwa fungsi f selalu mengembalikan dua?
, , 100% , , , , , . - - . - , "" .
property-base testing: QuickCheck Haskell, GAST Clean, Kotlintest, QCheck Ocaml, Hypothesis Python' . . , : , .
, -, , . Geant4 "" (), " " ( ) ( 5 , ).
, , - - . , 20 000 , , — 50 000 . , .
, property-based testing — , , . QuickCheck John Hughes — Building on developers' intuitions (...) | Lambda Days 19. , ...
, — : , , . , .
, , : ?
propertyDoubleEq :: Double -> bool
propertyDoubleEq x = (x == x)
, - - , , , .
2 + 2 = 5? ?
, , , . Jef239.
, - , , . - , , , copy-paste:
string monthName(unsigned int n) {
static vector<string> months = {"", "", ... };
return months[n % months.size()];
}
void testMonthNames() {
assert( monthName(0) == "");
...
}
, , "" . , , : , .
, - " ". , , , . , .
, , , . , , - !
, — , .
- —
, — , . , — , - , :
- . , - , "" , , .
- . , . , , , , .
- , , (. 1). , , . , !
, , , , . . , , , . , , .
- . , . , . -, , , .
— , .
, , - — , , .
- —
, , . , , .
- , , , . , , , , - . :
. , , — , .. . write-check-correct loop — , .
, Ocaml — , , - "" — () . -, , .
. - , - .
CI - - CI , - , . , , , PR .
, - -. , .
- —
, -, - , . , , , , . , , , , . - WindowMaker, Quake I, Heroes 2 , , . , TeX, , .
, -. , . , — " , ".
, - , , . , , - . This does not add business value, right?
, — , - - , , : . — , , Python 2 Python 3 Boost, . , !
: , , - . .
, "" — , , .
, . , . , , mutation testing, - .
, , - , , — , , , . , , . , , , - .
, - — , , . " – , , ".
" ", , , IDE , . , , - , . , , , , , . , , - , .
, , . , , . !