Saya bertanya-tanya apakah mengukur cakupan kode bersyarat oleh alat saat ini untuk Java tidak usang sejak Java 8 muncul. Dengan Java 8 Optional
dan Stream
kita sering dapat menghindari kode cabang / loop, yang membuatnya mudah untuk mendapatkan cakupan bersyarat sangat tinggi tanpa menguji semua jalur eksekusi yang mungkin. Mari kita bandingkan kode Java lama dengan kode Java 8:
Sebelum Java 8:
public String getName(User user) {
if (user != null) {
if (user.getName() != null) {
return user.getName();
}
}
return "unknown";
}
Ada 3 jalur eksekusi yang mungkin dalam metode di atas. Untuk mendapatkan 100% cakupan bersyarat, kita perlu membuat 3 unit tes.
Java 8:
public String getName(User user) {
return Optional.ofNullable(user)
.map(User::getName)
.orElse("unknown");
}
Dalam hal ini, cabang disembunyikan dan kami hanya perlu 1 tes untuk mendapatkan cakupan 100% dan tidak masalah yang akan kami uji. Meskipun masih ada 3 cabang logis yang sama yang harus dibahas saya percaya. Saya pikir itu membuat statistik cakupan bersyarat sepenuhnya tidak dipercaya hari ini.
Apakah masuk akal untuk mengukur cakupan bersyarat untuk kode Java 8? Apakah ada alat lain yang melihat kode yang dimasukkan?
sumber
getName
? Tampaknya bahwa jikauser
nol, itu harus mengembalikan "tidak dikenal". Jikauser
bukan nol danuser.getName()
nol, itu harus mengembalikan "tidak dikenal". Jikauser
bukan nol danuser.getName()
bukan nol, itu harus mengembalikannya. Jadi, Anda akan menguji tiga kasus karena itulah kontraknyagetName
. Anda tampaknya melakukannya mundur. Anda tidak ingin melihat cabang dan menulis tes sesuai dengan itu, Anda ingin menulis tes Anda sesuai dengan kontrak Anda, dan memastikan kontrak terpenuhi. Saat itulah Anda memiliki cakupan yang baik.Jawaban:
Saya tidak tahu. Saya mencoba menjalankan kode yang Anda miliki melalui JaCoCo (alias EclEmma) hanya untuk memastikan, tetapi itu menunjukkan 0 cabang dalam
Optional
versi. Saya tidak tahu metode konfigurasi untuk mengatakan sebaliknya. Jika Anda mengonfigurasinya untuk juga menyertakan file JDK, secara teoritis akan menampilkan cabang diOptional
, tapi saya pikir akan konyol untuk mulai memverifikasi kode JDK. Anda hanya harus menganggap itu benar.Saya pikir masalah intinya adalah menyadari bahwa cabang tambahan yang Anda miliki sebelum Java 8 adalah, dalam arti tertentu, cabang yang dibuat secara artifisial. Bahwa mereka tidak lagi ada di Java 8 berarti Anda sekarang memiliki alat yang tepat untuk pekerjaan itu (dalam hal ini,
Optional
). Dalam kode pra-Jawa 8 Anda harus menulis tes unit tambahan sehingga Anda dapat memiliki keyakinan bahwa setiap cabang kode berperilaku dengan cara yang dapat diterima - dan ini menjadi sedikit lebih penting di bagian kode yang tidak sepele sepertiUser
/getName
contoh.Dalam kode Java 8, Anda malah menaruh kepercayaan pada JDK bahwa kode tersebut berfungsi dengan baik. Seperti, Anda harus memperlakukan
Optional
baris itu sama seperti alat cakupan kode memperlakukannya: 3 baris dengan 0 cabang. Bahwa ada baris dan cabang lain dalam kode di bawah ini adalah sesuatu yang belum Anda perhatikan sebelumnya, tetapi telah ada setiap kali Anda menggunakan sesuatu sepertiArrayList
atauHashMap
.sumber
if
dannull
masih bagian dari bahasa ;-) Ini masih mungkin untuk menulis kode dengan cara lama dan untuk lulusnull
pengguna atau pengguna dengannull
nama. Tes Anda harus membuktikan bahwa kontrak terpenuhi terlepas dari bagaimana metode diterapkan. Intinya adalah bahwa tidak ada alat untuk memberi tahu Anda jika Anda telah menguji kontrak sepenuhnya.Optional
(dan metode terkait), Anda tidak perlu lagi mengujinya. Tidak dengan cara yang sama Anda mengujiif-else
: setiapif
adalah ladang ranjau yang potensial.Optional
dan idiom fungsional serupa sudah dikodekan dan dijamin tidak akan membuat Anda tersandung, jadi pada dasarnya ada "cabang" yang hilang.Optional
. Seperti katanya, secara logis kita harus tetap menguji yanggetName()
menangani berbagai kemungkinan input dengan cara yang kita inginkan, terlepas dari implementasinya. Lebih sulit untuk menentukan ini tanpa bantuan cakupan kode yang membantu dalam cara pra-JDK8.if-else
karena masing-masing konstruk tersebut sepenuhnya ad-hoc. Sebaliknya,Optional
,orElse
,map
, dll, semua sudah diuji. Cabang-cabang, pada dasarnya, "menghilang" ketika Anda menggunakan idiom yang lebih kuat.