Generator pengujian berbasis LLM baru dari Meta
(read.engineerscodex.com)Generator pengujian berbasis LLM baru dari Meta memberi peluang untuk mengintip masa depan pengembangan
- Meta menerbitkan makalah berjudul "Automated Unit Test Improvement using Large Language Models at Meta".
- Makalah ini menunjukkan cara menggunakan AI untuk mempercepat pengembangan dan mengurangi bug perangkat lunak.
- Dengan mengintegrasikan LLM ke dalam alur kerja pengembang, pendekatan ini mengusulkan perbaikan perangkat lunak yang akurat dan lengkap untuk meningkatkan code coverage saat ini.
Poin utama
- TestGen-LLM menggunakan pendekatan 'Assured LLM-based Software Engineering' (Assured LLMSE).
- Pendekatan ensemble digunakan untuk menghasilkan usulan perbaikan kode dengan beberapa LLM, prompt, dan hyperparameter, lalu memilih perbaikan terbaik.
- TestGen-LLM dirancang khusus untuk meningkatkan test yang sudah ditulis manusia.
Statistik
- Dalam evaluasi produk Reels dan Stories di Instagram, 75% test case yang dihasilkan TestGen-LLM berhasil dibuild, 57% lulus secara andal, dan 25% meningkatkan coverage.
- TestGen-LLM mampu memperbaiki 10% dari semua class yang diterapkan, dan pengembang menerima 73% usulan perbaikan test lalu menerapkannya ke production.
- Dalam "test-a-thon" untuk membuat test guna meningkatkan test coverage Instagram, median jumlah baris kode yang ditambahkan oleh test TestGen-LLM adalah 2,5.
Insight yang bisa diterapkan
- Ini adalah contoh yang baik tentang bagaimana LLM dapat digunakan untuk secara efisien meningkatkan produktivitas pengembangan dan keandalan perangkat lunak.
- Nilai sejati LLM ada pada kemampuannya menemukan dan menangkap edge case yang tak terduga.
- Untuk menggunakan LLM di production, diperlukan orkestrasi, pipeline, dan pemrosesan.
Cara kerja TestGen-LLM
- TestGen-LLM menerapkan serangkaian filter semantik pada kandidat solusi yang dihasilkan oleh LLM internal Meta, sehingga hanya test yang paling bernilai yang dipertahankan.
- Filter 1: kemungkinan build, Filter 2: eksekusi (apakah test lulus), Filter 3: ketidakstabilan, Filter 4: peningkatan coverage.
- Filter pemrosesan ini menjamin peningkatan pada test suite.
Kesimpulan
- Makalah ini adalah cara yang baik untuk melacak kemajuan LLM di ranah keandalan perangkat lunak, sesuatu yang sudah banyak pengembang lakukan dengan memanfaatkan LLM.
- LLM akan semakin mampu menemukan bug dan melakukan pengujian pada sistem perangkat lunak yang makin kompleks.
Opini GN⁺
- Artikel ini memberikan wawasan menarik tentang bagaimana kecerdasan buatan dapat memengaruhi masa depan pengembangan perangkat lunak.
- Alat seperti TestGen-LLM dapat sangat membantu dalam mengotomatisasi pekerjaan pengembang dan meningkatkan efisiensi.
- Perkembangan teknologi seperti ini bergerak ke arah pengurangan kompleksitas pengembangan perangkat lunak, peningkatan kualitas, dan penghematan waktu pengembang.
1 komentar
Pendapat Hacker News
Menarik melihat arus yang ingin memakai LLM lebih dulu untuk menulis kode pengujian daripada implementasi
Mungkin karena sudah terlalu banyak melakukan TDD, saya melihat pengujian sebagai sesuatu yang menjelaskan bagaimana sistem seharusnya bekerja, dan bagian ini harus didefinisikan oleh manusia. Kode harus menyesuaikan diri di dalam guardrail yang dibuat oleh pengujian
Namun LLM bisa membantu menunjukkan area yang spesifikasinya kurang. Yang terjadi di sini mungkin adalah cara membuatnya mengusulkan unit test untuk bagian-bagian yang belum terspesifikasi dengan baik
Bahkan sebelum LLM, saya kadang berpikir apakah, jika semua pengujian sudah ditulis, seekor monyet dengan mesin tik pun bisa membuat aplikasi
Ini adalah pengujian yang mendefinisikan bagaimana codebase saat ini benar-benar bekerja, bukan bagaimana manusia percaya kode itu seharusnya bekerja
Dengan ini, penulisan ulang, refactoring, dan redesign bisa dilakukan sambil meminimalkan regresi. Masalah pada banyak kode legacy adalah tidak ada yang memahami perilaku yang dimaksudkan, dan kadang bahkan pengguna percaya sistem seharusnya bekerja dengan cara yang berbeda dari perilaku aktualnya
Karena itu, jika bukan perubahan yang secara eksplisit diinginkan, hal terpenting adalah tidak mengubah perilaku
Ide dasarnya adalah mengekspresikan proposisi perilaku kode yang lebih lemah daripada sistem pembuktian bentuk tertutup yang lengkap sebagai “properti”, lalu memverifikasinya dalam batasan yang pada dasarnya probabilistik
Contoh klasiknya adalah membalik string. Jika string dibalik dua kali, biasanya hasilnya harus kembali ke input. Dengan satu baris kode, Anda bisa memeriksa kasus tepi Unicode yang aneh sebanyak yang diizinkan waktu dan listrik
Contohnya terlihat sepele, tetapi saya pernah melihat para ahli CUDA yang mengerjakan autodiff dan kernel yang kemudian menjadi PyTorch memakai cara ini dengan sangat efektif, mendapatkan keandalan kode sekitar 5x dengan separuh upaya dan biaya
Tidak selalu cocok, tetapi ketika cocok hasilnya bagus, dan LLM tampaknya bisa mendekati contoh Hypothesis dengan cukup baik daripada mulai dari nol
Sebaliknya, saat menulis pengujian, kita harus menjelaskan apa yang harus dilakukan aplikasi dengan bahasa yang sangat bertele-tele dan penuh batasan, serta menulis puluhan atau ratusan baris kode setup hanya untuk memasukkan beberapa if/else yang dipercantik
Dalam bahasa seperti C++ atau Java, unit test tersusun dari kebosanan, jadi sama sekali tidak mengejutkan jika muncul insting untuk menyerahkan pekerjaan itu kepada LLM
Saya sering melihat engineer menulis kode selama beberapa hari, lalu belakangan menulis beberapa pengujian yang mau tak mau “membuktikan” bahwa sistem bekerja. Coverage-nya rendah dan biasanya rapuh
Bagi engineer yang berpikir dan bekerja seperti itu, sistem semacam ini akan terlihat seperti anugerah
Saya juga pernah punya manajer yang melarang menulis pengujian dulu karena katanya lambat. Untungnya saya sedang berstatus kontraktor sehingga bisa mengabaikannya dengan berkata “bicaralah dengan atasan saya”, tetapi mungkin ia berpikir sama seperti para engineer di atas
Dilihat dari sisi lain, kebanyakan developer membenci dokumentasi. Jika ada AI yang menulis dokumentasi bagus dari kode, mereka akan menyukainya. Dan bagi developer seperti itu, dokumentasi yang tidak perlu mereka tulis sendiri adalah dokumentasi yang bagus
Kode pengujian sering diperlakukan sebagai kode berprioritas rendah dan diserahkan kepada engineer yang lebih junior, yang tampak justru kebalikan dari arah yang diinginkan
Saya tidak ingin meninjau semuanya, tetapi satu bagian tampaknya sangat meleset
Dengan catatan bahwa saya membaca sekilas paper aslinya tak lama setelah diposting dan sekarang hanya sedang menelusurinya lagi, jadi ingatan saya samar
Blog itu menulis bahwa sebagian besar pengujian TestGen-LLM dari Meta hanya menambah coverage 2,5 baris, tetapi satu pengujian mencakup 1326 baris, dan nilai satu pengujian itu “secara eksponensial lebih besar”, serta nilai LLM yang secara aktif berpikir di luar kotak untuk menangkap kasus tepi tak terduga itu besar
Namun frasa “secara eksponensial lebih bernilai” saja seharusnya sudah menyalakan pendeteksi omong kosong. Jika melihat paper-nya, para penulis menjelaskan coverage 1326 baris ini sebagai satu pengujian yang mendapat jackpot, dan mengatakan bahwa tambahan coverage baris yang realistis untuk satu pengujian TestGen-LLM adalah median 2,5 baris
Para penulis tidak menyebut “kasus tepi tak terduga” atau “berpikir di luar kotak”. Sebaliknya, mereka menyajikannya sebagai kasus pengecualian yang mungkin saja menyentuh satu cabang dari switch statement yang mengerikan, atau sekadar kebetulan dari cara coverage kode dihitung
Di bagian “hasil kualitatif” pun terlihat mencolok bahwa mereka tidak menggali ini lebih jauh. Penjelasan yang tidak akurat tidak membantu siapa pun. Internet sudah terlalu banyak berisi orang yang berpura-pura memahami sesuatu yang hanya mereka pura-pura baca
Saya telah mengubah tulisan agar lebih jelas bahwa sebagian interpretasi itu adalah opini saya
Tulisan ini lebih merupakan komentar tentang makna hasil paper, bukan ringkasan paper. Bagaimanapun, Hacker News memang tempat untuk berdiskusi
Meski begitu, saya tetap berpikir bagian “secara eksponensial lebih bernilai” masih tepat. Fakta bahwa LLM bisa secara kebetulan mendapat “jackpot” dalam hal coverage pengujian adalah inti nilainya
Jika terus mencoba berbagai kombinasi lalu mendapatkan satu jackpot seperti dalam paper, itu sangat bernilai bagi tim. Bisa jadi itu pengujian yang tidak jelas bagi manusia untuk ditulis sendiri, atau terlalu membosankan
Dari posisi saya yang sudah terlalu banyak menghabiskan waktu di codebase Big Tech (F/G), ketika kita sudah tahu apa yang harus diuji tetapi harus mencari tahu “bagaimana mengujinya”, nilai itu terasa besar
Jelas tim ini juga didorong berfokus pada jumlah baris kode dan jumlah diff. Pada akhirnya ini hanya akan menjadi alat pembuat kode yang menambah satu lagi gunungan kode yang sulit di-debug
Pengujian yang baik itu sulit, dan coverage tidak selalu berarti baik.
Jika menulis terlalu banyak pengujian, program bisa dengan mudah menjadi kaku dan pada dasarnya berubah menjadi program pendeteksi perubahan. Jadinya seperti, “Anda mengubah sesuatu, ya? Semua pengujian rusak. Tidak apa-apa, sekarang tinggal minta LLM membuatnya lagi! Coverage 100%! Luar biasa! Ini kemajuan!”
Bagi saya, itu kesempatan untuk memastikan apakah perubahan tersebut memang disengaja. Tanpa itu, bagaimana kita tahu program melakukan apa yang seharusnya dilakukan?
Selain itu, kita harus membaca pengujian yang dianggap baik oleh lima orang lain. Kita semua tidak pandai menulis pengujian; masing-masing hanya punya caranya sendiri.
Setelah itu, pada setiap perubahan, pengembang secara alami menekan tombol regenerasi dan meng-commit semuanya. Diff-nya melimpah, tetapi sinyalnya meragukan.
Setelah pernah bekerja di industri semikonduktor, khususnya litografi komputasional, tempat desain berbasis pengujian menjadi standar, saya sulit menerima argumen itu.
Ini bukan berarti pengujian harus selalu ditulis sebelum kode produksi. Namun, pengujian adalah bagian dari kode sama seperti bagian lain dari codebase, dan harus ditulis bersama kode yang diuji.
Bagian terpenting dari pengujian adalah menunjukkan niat pengembang. Test suite menunjukkan bagaimana kode seharusnya digunakan, apa yang dilakukannya, apa yang tidak dilakukannya, dan untuk apa kode itu ditulis.
Dengan begitu, ketika pengembang lain menggunakan atau memodifikasi kode tersebut, mereka tidak perlu berkeliling di codebase seperti Sherlock Holmes mencari petunjuk.
Jika pengujian tidak bercerita, berarti Anda menulis pengujian dengan cara yang salah.
Sampai komputer bisa membaca pikiran dan memahami niat dengan lebih baik, generator berbasis AI/LLM tidak bisa menggantikan pekerjaan ini.
Tentu saja, jika satu-satunya tujuan test suite adalah mendapatkan tanda centang hijau pada pemeriksaan sebelum commit dan menampilkan angka coverage yang keren, AI bisa menggandakan produktivitas.
Generator kode otomatis akan membantu Anda menulis lebih banyak kode buruk dengan kecepatan cahaya. Jika ada yang mengeluh bahwa kode menjadi bengkak dan sulit dipahami karena terlalu banyak boilerplate, tinggal bilang agar AI yang menanganinya. Toh itu berhasil untuk Anda.
Masa depan pengembangan memang benar-benar terlihat seperti itu, tetapi itu bukan masa depan yang saya harapkan.
Yang Anda jelaskan tampaknya adalah pengujian “inti” dari kode. Pengujian yang sekaligus berfungsi sebagai dokumentasi, verifikasi, dan bagian dari stabilitas.
Pengujian lain seperti fuzzing memberikan nilai yang sama sekali berbeda. Saya melihat pengujian berbasis AI bisa menempati ruang di bagian ekor distribusi: banyak pengujian bernilai rendah yang terabaikan karena energi dan waktu manusia tidak mencukupi.
Begitu juga cara saya melihat kondisi alat AI saat ini: alat bantu kognitif.
Saya justru akan terkejut jika arah riset ini tidak menghasilkan sesuatu yang cukup berarti dalam beberapa tahun ke depan.
Saya mengutip ulang, dengan sedikit penyuntingan, apa yang saya tulis saat makalahnya sendiri diposting. Tulisan mereka keliru merepresentasikan statistik.
https://news.ycombinator.com/item?id=39406726
Abstraknya tidak sesuai dengan isi makalah yang sebenarnya. Ringkasannya terbaca seolah-olah memakai rasio berdasarkan test case: “75% berhasil dibangun dengan benar, 57% lulus secara stabil, 25% meningkatkan coverage.”
Laporan sebenarnya berbicara berdasarkan kelas pengujian, dan setiap kelas memiliki satu atau lebih test case.
Artinya: “75% kelas pengujian memiliki setidaknya satu test case baru yang berhasil dibangun dengan benar”, “57% kelas pengujian memiliki setidaknya satu test case yang berhasil dibangun dengan benar dan lulus secara stabil”, dan “25% kelas pengujian memiliki setidaknya satu test case yang dibangun, lulus, dan meningkatkan line coverage dibanding kelas pengujian lain pada target build yang sama.”
Keduanya adalah pernyataan yang sama sekali berbeda. Bahkan ada catatan kaki bahwa setiap upaya memperluas kelas pengujian bisa mencakup beberapa upaya pembuatan test case, sehingga tingkat keberhasilan per test case biasanya jauh lebih rendah daripada tingkat keberhasilan per kelas pengujian.
Namun di bagian kesimpulan, mereka kembali salah merepresentasikan hasil seperti di abstrak. Mereka menulis bahwa saat memakai TestGen-LLM dalam mode eksperimen, tingkat keberhasilan per test case adalah 25%, dan jika persyaratan line coverage dilonggarkan sehingga hanya menuntut build dan lulus, tingkat keberhasilannya naik menjadi 57%.
Saya bersimpati kepada orang-orang yang kelak harus memelihara kode legacy LLM yang buruk ini.
Itu akan terlihat mengerikan.
Malah mungkin terlihat cukup mirip, dengan komentar dan dokumentasi yang lebih lengkap, serta mungkin lebih kecil kemungkinannya untuk salah secara aktif.
LLM tidak akan pernah menjadi lebih baik dari sekarang dan sama sekali tidak berkembang selama 2 tahun terakhir. Itu cuma rantai Markov yang mewah.
LLM hanya bisa dipakai untuk menulis kode ketika orang yang tidak tahu coding secara membabi buta meng-commit kode ke produksi tanpa review apa pun.
Bagi orang yang tahu coding, mustahil ada gunanya dan tidak akan meningkatkan produktivitas.
Saya akan mengabaikan omong kosong LLM yang sama sekali tidak mengubah dunia ini, dan Anda juga wajib melakukan hal yang sama.
Jika tidak dipisahkan dengan baik, lingkungan ini mudah berubah menjadi lingkungan yang memusuhi developer, ketika manajer yang tidak paham menuntut cakupan tinggi dan para junior yang bersemangat diam-diam memasukkan banyak sekali pengujian AI
Pada akhirnya, setiap kali mengirimkan pekerjaan, developer harus mendapat stempel persetujuan dari kode pengujian buatan LLM yang sulit dipelihara
Penulisan sebagian pengujian mungkin bisa menjadi lebih cepat, tetapi tidak ada jaminan pemeliharaannya juga menjadi lebih cepat. Begitu pula dengan pemeliharaan kode yang diuji. Karena tidak ada jaminan bahwa pengujian yang dihasilkan adalah pengujian yang baik
Proses bersusah payah menulis pengujian biasanya juga membantu developer memeriksa desain sejak awal. Jika sulit diuji, biasanya desainnya tidak baik; misalnya dalam konteks harus menulis kode bersama orang lain, kontrak komponen sering kali belum diabstraksikan dengan cukup baik
Hal yang mudah terlewat adalah bahwa pengujian adalah kode yang bisa dikorbankan. Sebagian besar tidak akan menangkap apa pun sepanjang hidupnya, dan itu tidak masalah. Karena ia memberi rasa aman otomatis dan, saat gagal, mempersempit petunjuk tentang apa yang salah
Namun, investasi maksimal pada pengaman probabilistik tidak selalu menghasilkan imbalan. Semakin cakupan mendekati puncak, utilitas marginalnya makin menurun. Kecuali jalur eksekusi dengan trafik tinggi seperti standard library, membanggakan cakupan tinggi biasanya tidak membuahkan hasil
Selain itu, hampir selalu dibutuhkan ekosistem pengujian yang mencakup bukan hanya unit test, tetapi juga integration test, system test, dan sebagainya agar keseluruhan bisa berjalan. Apakah LLM akan duduk di rapat desain, memahami arsitektur, lalu menuliskan pengujian semacam itu juga? Atau kemampuannya akan dilebih-lebihkan sehingga menggeser hal-hal yang seharusnya dikerjakan?
Saat menginvestasikan upaya pada pengujian, dibutuhkan kepekaan untuk menilai “apa yang relevan”, bukan hanya saat menulisnya, tetapi juga saat desain dan pemeliharaan. Manusia cukup baik dalam hal ini, tetapi alat AI tidak
Bagian yang bisa dihemat LLM adalah pengetikan oleh developer berpengalaman yang sudah punya intuisi tentang apa yang baik untuk diuji dan apa yang tidak. Pada saat yang sama, LLM juga bisa mengganggu dengan menyelundupkan hal-hal yang tidak terlalu relevan ke dalam kode, dan itu memang sudah terjadi
Saya tidak menginginkan ekonomi yang memproduksi penekanan tombol. Saya menginginkan kumpulan penekanan tombol yang relevan dan sudah dipikirkan matang-matang. Dan saya berharap yang terakhir dapat dipisahkan dengan baik dari yang pertama, sehingga seiring waktu kegunaan objektifnya, atau ketiadaannya, menjadi terlihat
Saya sudah mencobanya dengan GPT-4
Saya menunjukkan sebuah modul TypeScript dan memintanya membuat unit test; hasilnya adalah pengujian yang berjalan, mencakup bukan hanya jalur normal tetapi juga beberapa kasus batas
ChatGPT melampaui ekspektasi dalam banyak hal. Pengujian tampaknya termasuk mudah menurut standar kemampuan GPT
Minggu lalu saya memintanya menulis kode Python yang menelusuri AST untuk membuat graf dan komponen React Flow. Saya tidak melakukan perbaikan sendiri, hanya mengulang umpan balik prompt beberapa kali, dan hasilnya berjalan sangat baik. Saya sudah melihat banyak kemampuan menarik serupa di GPT
Bagaimana AI tahu pengujian seperti apa yang harus ditulis?
Ini eksperimen yang menarik, tetapi agak meragukan. Menurut saya, cara AI paling bisa membantu dalam pengembangan perangkat lunak adalah ketika programmer mengajukan pertanyaan tentang kodenya sendiri atau kode orang lain, lalu AI menjawabnya. Kadang jawabannya akan mencakup saran kode, tetapi tidak harus selalu begitu
AI seharusnya bisa menjawab pertanyaan seperti “Apakah ada cara untuk menyederhanakan kode ini?” atau “Input apa yang bisa menyebabkan error?”
AI harus membantu kita memahami kode dan memahami cara memperbaikinya. Jika kita tidak memberi tahu apa yang harus dilakukan, AI tidak bisa tahu apa yang kita inginkan, jadi jangan biarkan AI menulis semuanya sendiri
Pengujian adalah contoh yang bagus. Apa yang ingin kita uji?
Akhirnya ada pembuatan kode AI yang masuk akal