Jika Anda hanya memiliki satu pernyataan per tes; bagaimana cara menguji beberapa input?

15

Saya mencoba membangun beberapa test case, dan telah membaca bahwa Anda harus mencoba dan membatasi jumlah pernyataan per test case.

Jadi pertanyaan saya adalah, apa cara terbaik untuk menguji suatu fungsi dengan beberapa input. Sebagai contoh, saya memiliki fungsi yang mem-parsing string dari pengguna dan mengembalikan jumlah menit. String bisa dalam bentuk "5w6h2d1m", di mana w, h, d, msesuai dengan jumlah minggu, jam, hari, dan menit.

Jika saya ingin mengikuti '1 pernyataan per aturan pengujian' saya harus membuat beberapa tes untuk setiap variasi input? Kelihatannya konyol jadi saya hanya punya sesuatu seperti:

self.assertEqual(parse_date('5m'), 5)
self.assertEqual(parse_date('5h'), 300)
self.assertEqual(parse_date('5d') ,7200)
self.assertEqual(parse_date('1d4h20m'), 1700)

Dalam satu test case. Apakah ada cara yang lebih baik?

pasak
sumber
Cara terbaik untuk melakukannya adalah menggunakan parameter (beberapa kerangka kerja mendukung fitur ini, semua kerangka kerja harus). Dengan cara ini Anda menguji satu perilaku tetapi dengan mempertimbangkan banyak kasus uji dan masih dapat melihat nilai parameter apa yang menyebabkan kesalahan jika kesalahan terjadi
Kemoda

Jawaban:

23

Cara yang lebih pragmatis untuk melihat satu penegasan per aturan "tes", adalah memiliki pernyataan Anda dalam satu tes mencakup konsep tunggal.

Dengan cara ini Anda masih menguji konsep tunggal dalam uji tunggal. Dalam kasus Anda, apakah string input Anda diurai dengan benar dalam satu tanggal.

Anda harus melakukan penilaian berdasarkan kasus per kasus untuk memeriksa apakah Anda lebih baik menguji konsep tunggal dengan banyak penegasan atau memiliki satu penegasan dalam banyak pengujian.

Pilih opsi yang membuat tes lebih jelas, lebih sedikit pengulangan sementara masih memiliki tes Anda dapat menyoroti berbagai titik kegagalan dalam metode Anda. Anda ingin menjadi jelas ketika tes gagal persis apa yang terjadi daripada harus men-debug tes Anda untuk mencari tahu apa yang salah.

Gilles
sumber
17

Ini sangat tergantung pada perpustakaan pengujian Anda. Di perpustakaan C # NUnit Anda dapat melakukan sesuatu seperti:

[TestCase('5m', 5)]
[TestCase('5h', 300)]
[TestCase('5d', 7200)]
[TestCase('1d4h20m', 1700)]
public void ParseDateTest(inputString, expectedMinutes)
{
    Assert.That(parse_date(inputString), Is.EqualTo(expectedMinutes));
}
Gober1
sumber
Di java dengan testng Anda memiliki metode
@DataProvider
itu solusi IMHO terbaik. di hampir setiap bahasa Anda dapat membuat parameter pengujian Anda. untuk java: @Parameterized , JunitParams , Zohhak
piotrek
3

Ya, buat beberapa tes untuk setiap variasi input.

Tujuan utama dari satu pernyataan per pedoman pengujian adalah untuk memilikinya (idealnya) bahwa satu kesalahan mengarah pada satu kegagalan tes dan sebaliknya sehingga Anda tahu persis apa yang gagal. Kemudian Anda dapat bekerja dengan satu tes yang sangat tepat untuk men-debug akar penyebab dan memverifikasi. Anda dapat memecahkan ini dengan satu menegaskan, dan Anda bisa baik-baik saja dengan beberapa menegaskan. Dalam skenario khusus ini, saya akan memiliki tes untuk setiap sufiks dan beberapa kombinasi pemesanan.

Mudah-mudahan jelas mengapa mengisolasi tes adalah manfaat: Anda membuang sedikit waktu debugging ketika ada yang tidak beres. Sekarang, jika Anda benar - benar yakin bahwa tes tersebut tidak mungkin gagal, dan biaya overhead berburu melalui tes kecil, maka mungkin masuk akal untuk hanya menguji semuanya sekaligus untuk menghemat waktu implementasi.

Tetapi sejarah telah menunjukkan bahwa menghemat sedikit waktu menulis kode dengan mengorbankan membaca / menggunakan kode tidak pernah sepadan. Oleh karena itu pedoman.

Telastyn
sumber
1

Puritan akan mengatakan bahwa pernyataan untuk nilai input yang berbeda harus dimasukkan dalam metode tes yang terpisah di dalam kelas tes. Salah satu alasan untuk ini adalah, tergantung pada UI pengujian Anda, seringkali lebih mudah untuk membedakan antara kegagalan pengujian individu daripada antara pernyataan individual, yang mungkin membuat Anda mengidentifikasi sumber kegagalan lebih cepat.

Saat menguji dengan JUnit kita bisa menyiasatinya dengan menggunakan versi metode assert * dengan argumen String awal untuk membedakan satu pernyataan dari yang lain dalam metode pengujian yang sama.

self.assertEqual("just minutes", parse_date('5m'), 5)
self.assertEqual("just hours", parse_date('5h'), 300)
self.assertEqual("just days", ('5d') ,7200)
self.assertEqual("days, hours, minutes", parse_date('1d4h20m'), 1700)
Mike Partridge
sumber