it-swarm-id.com

Bagaimana Anda tahu apa yang harus diuji ketika menulis unit test?

Dengan menggunakan C #, saya memerlukan kelas bernama User yang memiliki nama pengguna, kata sandi, bendera aktif, nama depan, nama belakang, nama lengkap, dll.

Harus ada metode untuk otentikasi dan simpan pengguna. Apakah saya hanya menulis tes untuk metodenya? Dan apakah saya perlu khawatir tentang pengujian properti karena mereka. Net pengambil dan setter?

127
Mike Roosa

Banyak tanggapan bagus untuk ini juga pada pertanyaan saya: " Memulai TDD - Tantangan? Solusi? Rekomendasi? "

Bolehkah saya juga merekomendasikan untuk melihat posting blog saya (yang sebagian terinspirasi oleh pertanyaan saya), saya sudah mendapat tanggapan yang bagus tentang itu. Yaitu:

Saya Tidak Tahu Mulai Dari Mana?

  • Mulai dari awal. Pikirkan tentang tes menulis hanya ketika Anda menulis kode baru. Ini dapat berfungsi kembali dengan kode lama, atau fitur yang sama sekali baru.
  • Mulai dari yang sederhana. Jangan melarikan diri dan mencoba membuat kerangka kerja Anda berkeliling serta menjadi TDD-esque. Debug. Assert berfungsi dengan baik. Gunakan itu sebagai titik awal. Itu tidak mengacaukan proyek Anda atau membuat dependensi.
  • Mulai positif. Anda mencoba untuk meningkatkan keahlian Anda, merasa senang tentang hal itu. Saya telah melihat banyak pengembang di luar sana yang senang stagnan dan tidak mencoba hal-hal baru untuk memperbaiki diri. Anda melakukan hal yang benar, ingat ini dan itu akan membantu menghentikan Anda dari menyerah.
  • Mulai siap menghadapi tantangan. Sangat sulit untuk memulai pengujian. Harapkan tantangan, tapi ingat - tantangan bisa diatasi.

Hanya Uji Untuk Yang Anda Harapkan

Saya memiliki masalah nyata ketika pertama kali memulai karena saya terus duduk di sana mencoba mencari tahu setiap masalah yang mungkin terjadi dan kemudian mencoba untuk mengujinya dan memperbaikinya. Ini adalah cara cepat untuk sakit kepala. Pengujian harus menjadi proses YAGNI yang nyata. Jika Anda tahu ada masalah, maka tulis tes untuk itu. Kalau tidak, jangan repot-repot.

Hanya Uji Satu Hal

Setiap test case seharusnya hanya menguji satu hal. Jika Anda mendapati diri Anda memasukkan "dan" dalam nama kasus uji, Anda melakukan sesuatu yang salah.

Saya harap ini berarti kita dapat beralih dari "getter and setters" :)

130
Rob Cooper

Uji kode Anda, bukan bahasa.

Tes unit seperti:

Integer i = new Integer(7);
assert (i.instanceOf(integer));

hanya berguna jika Anda menulis kompiler dan ada kemungkinan bukan nol bahwa metode instanceof Anda tidak berfungsi.

Jangan menguji hal-hal yang bisa Anda andalkan pada bahasa yang digunakan. Dalam kasus Anda, saya akan fokus pada otentikasi Anda dan menyimpan metode - dan saya akan menulis tes yang memastikan mereka dapat menangani nilai nol di salah satu atau semua bidang itu dengan anggun.

63
Tim Howland

Ini membuat saya memasuki unit testing dan itu membuat saya sangat senang

Kami baru mulai melakukan pengujian unit. Untuk waktu yang lama saya tahu akan baik untuk mulai melakukannya tetapi saya tidak tahu bagaimana memulainya dan yang lebih penting apa yang harus diuji.

Kemudian kami harus menulis ulang sepotong kode penting dalam program akuntansi kami. Bagian ini sangat kompleks karena melibatkan banyak skenario yang berbeda. Bagian yang saya bicarakan adalah metode untuk membayar penjualan dan/atau faktur pembelian yang sudah dimasukkan ke dalam sistem akuntansi.

Saya hanya tidak tahu bagaimana memulai mengkodekannya, karena ada begitu banyak opsi pembayaran yang berbeda. Faktur bisa menjadi $ 100 tetapi pelanggan hanya mentransfer $ 99. Mungkin Anda telah mengirim faktur penjualan ke pelanggan tetapi Anda juga telah membeli dari pelanggan itu. Jadi Anda menjualnya seharga $ 300 tetapi Anda membeli seharga $ 100. Anda dapat mengharapkan pelanggan membayar Anda $ 200 untuk menyelesaikan saldo. Dan bagaimana jika Anda menjual seharga $ 500 tetapi pelanggan hanya membayar Anda $ 250?

Jadi saya punya masalah yang sangat kompleks untuk dipecahkan dengan banyak kemungkinan bahwa satu skenario akan bekerja dengan sempurna tetapi akan salah pada jenis kombinasi invocie/pembayaran lainnya.

Di sinilah unit testing datang untuk menyelamatkan.

Saya mulai menulis (di dalam kode uji) metode untuk membuat daftar faktur, baik untuk penjualan maupun pembelian. Lalu saya menulis metode kedua untuk membuat pembayaran aktual. Biasanya pengguna akan memasukkan informasi itu melalui antarmuka pengguna.

Lalu saya membuat TestMethod pertama, menguji pembayaran yang sangat sederhana dari satu faktur tanpa diskon pembayaran. Semua tindakan dalam sistem akan terjadi ketika pembayaran bank akan disimpan ke database. Seperti yang Anda lihat saya membuat faktur, membuat pembayaran (transaksi bank) dan menyimpan transaksi ke disk. Dalam pernyataan saya, saya memasukkan angka yang benar yang harus berakhir dalam transaksi Bank dan dalam Faktur tertaut. Saya memeriksa jumlah pembayaran, jumlah pembayaran, jumlah diskon dan saldo faktur setelah transaksi.

Setelah tes berjalan saya akan pergi ke database dan periksa apakah yang saya harapkan ada di sana.

Setelah Saya menulis tes, saya mulai mengkode metode pembayaran (bagian dari kelas BankHeader). Dalam pengkodean saya hanya repot dengan kode untuk membuat tes lulus pertama. Saya belum memikirkan skenario lain yang lebih kompleks.

Saya menjalankan tes pertama, memperbaiki bug kecil sampai tes saya akan berlalu.

Kemudian saya mulai menulis tes kedua, kali ini bekerja dengan diskon pembayaran. Setelah saya menulis tes saya memodifikasi metode pembayaran untuk mendukung diskon.

Saat menguji kebenaran dengan diskon pembayaran, saya juga menguji pembayaran sederhana. Kedua tes harus lulus tentu saja.

Lalu saya bekerja ke skenario yang lebih kompleks.

1) Pikirkan skenario baru

2) Tulis tes untuk skenario itu

3) Jalankan tes tunggal untuk melihat apakah itu akan lulus

4) Jika tidak, saya akan men-debug dan memodifikasi kode sampai lulus.

5) Sambil memodifikasi kode saya terus menjalankan semua tes

Inilah cara saya berhasil membuat metode pembayaran yang sangat rumit. Tanpa pengujian unit, saya tidak tahu cara memulai pengkodean, masalahnya tampak luar biasa. Dengan pengujian saya bisa mulai dengan metode sederhana dan memperluasnya langkah demi langkah dengan jaminan bahwa skenario yang lebih sederhana masih akan berfungsi.

Saya yakin bahwa menggunakan pengujian unit menyelamatkan saya beberapa hari (atau minggu) pengkodean dan lebih atau kurang menjamin kebenaran metode saya.

Jika nanti saya memikirkan skenario baru, saya bisa menambahkannya ke tes untuk melihat apakah itu berfungsi atau tidak. Jika tidak, saya dapat memodifikasi kode tetapi masih memastikan skenario lainnya masih berfungsi dengan benar. Ini akan menghemat berhari-hari dalam fase pemeliharaan dan perbaikan bug.

Ya, bahkan kode yang diuji masih dapat memiliki bug jika pengguna melakukan hal-hal yang tidak Anda pikirkan atau mencegahnya melakukan

Berikut adalah beberapa tes yang saya buat untuk menguji metode pembayaran saya.

public class TestPayments
{
    InvoiceDiaryHeader invoiceHeader = null;
    InvoiceDiaryDetail invoiceDetail = null;
    BankCashDiaryHeader bankHeader = null;
    BankCashDiaryDetail bankDetail = null;



    public InvoiceDiaryHeader CreateSales(string amountIncVat, bool sales, int invoiceNumber, string date)
    {
        ......
        ......
    }

    public BankCashDiaryHeader CreateMultiplePayments(IList<InvoiceDiaryHeader> invoices, int headerNumber, decimal amount, decimal discount)
    {
       ......
       ......
       ......
    }


    [TestMethod]
    public void TestSingleSalesPaymentNoDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 1, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 1, 119.00M, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(119M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(0M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSingleSalesPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 2, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 2, 118.00M, 1M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(1M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    [ExpectedException(typeof(ApplicationException))]
    public void TestDuplicateInvoiceNumber()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("100", true, 2, "01-09-2008"));
        list.Add(CreateSales("200", true, 2, "01-09-2008"));

        bankHeader = CreateMultiplePayments(list, 3, 300, 0);
        bankHeader.Save();
        Assert.Fail("expected an ApplicationException");
    }

    [TestMethod]
    public void TestMultipleSalesPaymentWithPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 11, "01-09-2008"));
        list.Add(CreateSales("400", true, 12, "02-09-2008"));
        list.Add(CreateSales("600", true, 13, "03-09-2008"));
        list.Add(CreateSales("25,40", true, 14, "04-09-2008"));

        bankHeader = CreateMultiplePayments(list, 5, 1144.00M, 0.40M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(4, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118.60M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(400, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(600, bankHeader.BankCashDetails[0].Payments[2].PaymentAmount);
        Assert.AreEqual(25.40M, bankHeader.BankCashDetails[0].Payments[3].PaymentAmount);

        Assert.AreEqual(0.40M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].PaymentDiscount);

        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSettlement()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("300", true, 43, "01-09-2008")); //Sales
        list.Add(CreateSales("100", false, 6453, "02-09-2008")); //Purchase

        bankHeader = CreateMultiplePayments(list, 22, 200, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(2, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(300, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(-100, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
    }
38
eroijen

Jika mereka benar-benar sepele, maka jangan repot-repot menguji. Misalnya, jika diterapkan seperti ini;

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Jika, di sisi lain, Anda melakukan sesuatu yang pintar, (seperti mengenkripsi dan mendekripsi kata sandi dalam pengambil/penyetel) maka berikan tes.

13
Steve Cooper

Aturannya adalah Anda harus menguji setiap bagian logika yang Anda tulis. Jika Anda menerapkan beberapa fungsi spesifik dalam getter dan setter saya pikir mereka layak untuk diuji. Jika mereka hanya memberikan nilai ke beberapa bidang pribadi, jangan repot-repot.

10
Slavo

Pertanyaan ini tampaknya menjadi pertanyaan di mana orang dapat menentukan metode apa yang diuji dan mana yang tidak.

Setter dan pengambil untuk penugasan nilai telah dibuat dengan konsistensi dan pertumbuhan masa depan dalam pikiran, dan meramalkan bahwa beberapa waktu kemudian pembuat setter/pengambil dapat berkembang menjadi operasi yang lebih kompleks. Masuk akal untuk menerapkan unit test terhadap metode-metode tersebut, juga demi konsistensi dan pertumbuhan di masa depan.

Keandalan kode, terutama saat mengalami perubahan untuk menambah fungsionalitas tambahan, adalah tujuan utama. Saya tidak mengetahui ada orang yang pernah dipecat karena memasukkan setter/getter dalam metodologi pengujian, tetapi saya yakin ada orang yang berharap mereka telah menguji metode yang terakhir mereka sadari atau ingat adalah set/pembungkus sederhana tetapi itu tidak ada. lagi kasusnya.

Mungkin anggota tim lain memperluas metode set/get untuk memasukkan logika yang sekarang perlu diuji tetapi tidak kemudian membuat tes. Tapi sekarang kode Anda memanggil metode ini dan Anda tidak tahu mereka berubah dan perlu pengujian mendalam, dan pengujian yang Anda lakukan dalam pengembangan dan QA tidak memicu cacat, tetapi data bisnis nyata pada hari pertama rilis tidak memicu itu.

Kedua rekan satu tim sekarang akan berdebat tentang siapa yang menjatuhkan bola dan gagal melakukan tes unit ketika set/mendapat morphed untuk memasukkan logika yang bisa gagal tetapi tidak tercakup oleh tes unit. Rekan setim yang awalnya menulis set/mendapat akan memiliki waktu yang lebih mudah keluar dari clean ini jika tes dilaksanakan sejak hari pertama pada set/dapatkan sederhana.

Pendapat saya adalah bahwa beberapa menit waktu "terbuang" yang meliputi SEMUA metode dengan tes unit, bahkan yang sepele, dapat menghemat berhari-hari sakit kepala di jalan dan kehilangan uang/reputasi bisnis dan kehilangan pekerjaan seseorang.

Dan fakta bahwa Anda membungkus metode sepele dengan tes unit dapat dilihat oleh rekan setim junior ketika mereka mengubah metode sepele menjadi yang non-sepele dan Meminta mereka untuk memperbarui tes, dan sekarang tidak ada yang dalam kesulitan karena cacat itu terkandung dari mencapai produksi.

Cara kita kode, dan disiplin yang bisa dilihat dari kode kita, dapat membantu orang lain.

6
Thomas Carlisle

Jawaban kanonik lainnya. Saya yakin ini dari Ron Jeffries:

Hanya uji kode yang ingin Anda kerjakan.

4
user9397

Benar-benar kode sepele seperti getter dan setter yang tidak memiliki perilaku ekstra daripada menetapkan bidang pribadi terlalu sulit untuk diuji. Dalam 3.0 C # bahkan memiliki beberapa gula sintaksis di mana kompiler menangani bidang pribadi sehingga Anda tidak perlu memprogramnya.

Saya biasanya menulis banyak tes yang sangat sederhana untuk memverifikasi perilaku yang saya harapkan dari kelas saya. Bahkan jika itu hal-hal sederhana seperti menambahkan dua angka. Saya banyak beralih antara menulis tes sederhana dan menulis beberapa baris kode. Alasan untuk ini adalah bahwa saya kemudian dapat mengubah sekitar kode tanpa takut saya memecahkan hal-hal yang tidak saya pikirkan.

3
Mendelt

Anda harus menguji semuanya. Saat ini Anda memiliki getter dan setter, tetapi suatu hari Anda mungkin mengubahnya sedikit, mungkin untuk melakukan validasi atau sesuatu yang lain. Tes yang Anda tulis hari ini akan digunakan besok untuk memastikan semuanya berjalan seperti biasa. Saat Anda menulis tes, Anda harus melupakan pertimbangan seperti "sekarang ini sepele". Dalam konteks lincah atau digerakkan oleh tes Anda harus menguji dengan asumsi refactoring masa depan. Juga, apakah Anda mencoba memasukkan nilai yang sangat aneh seperti string yang sangat panjang, atau konten "buruk" lainnya? Seharusnya Anda ... jangan pernah berasumsi betapa buruknya kode Anda dapat disalahgunakan di masa mendatang.

Secara umum saya menemukan bahwa menulis tes pengguna yang luas di satu sisi, melelahkan. Di sisi lain, meskipun selalu memberi Anda wawasan yang sangat berharga tentang bagaimana aplikasi Anda harus bekerja dan membantu Anda membuang asumsi yang mudah (dan salah) (seperti: nama pengguna akan selalu kurang dari 1000 karakter).

3
Sklivvz

Untuk modul sederhana yang mungkin berakhir di toolkit, atau dalam jenis proyek sumber terbuka, Anda harus menguji sebanyak mungkin termasuk getter dan setter sepele. Hal yang ingin Anda ingat adalah bahwa menghasilkan unit test saat Anda menulis modul tertentu cukup sederhana dan mudah. Menambahkan getter dan setter adalah kode minimal dan dapat ditangani tanpa banyak berpikir. Namun, begitu kode Anda ditempatkan di sistem yang lebih besar, upaya ekstra ini dapat melindungi Anda terhadap perubahan dalam sistem yang mendasarinya, seperti mengetikkan perubahan di kelas dasar. Menguji segala sesuatu adalah cara terbaik untuk memiliki regresi yang lengkap.

3
Dirigible

Menguji kode boilerplate adalah buang-buang waktu, tetapi seperti yang dikatakan Slavo, jika Anda menambahkan efek samping pada getter/setter Anda, maka Anda harus menulis tes untuk menyertai fungsi itu.

Jika Anda melakukan pengembangan berbasis tes, Anda harus menulis kontrak (misalnya antarmuka) terlebih dahulu, kemudian menulis tes untuk melatih antarmuka yang mendokumentasikan hasil/perilaku yang diharapkan. Lal tulis metode Anda sendiri, tanpa menyentuh kode di unit test Anda. Terakhir, ambil alat cakupan kode dan pastikan tes Anda menggunakan semua jalur logika dalam kode Anda.

3
warren_s

secara umum, ketika suatu metode hanya didefinisikan untuk nilai-nilai tertentu, uji untuk nilai-nilai pada dan lebih dari batas dari apa yang dapat diterima. Dengan kata lain, pastikan metode Anda melakukan apa yang seharusnya dilakukan, tetapi tidak lebih . Ini penting, karena ketika Anda akan gagal, Anda ingin gagal lebih awal.

Dalam hierarki warisan, pastikan untuk menguji LSP kepatuhan.

Menguji getter dan setter default sepertinya tidak terlalu berguna bagi saya, kecuali jika Anda berencana untuk melakukan validasi nanti.

2
Rik

nah kalau menurut Anda itu bisa pecah, tulis tes untuk itu. Saya biasanya tidak menguji setter/pengambil, tetapi katakanlah Anda membuat satu untuk User.Name, yang menggabungkan nama depan dan belakang, saya akan menulis tes jadi jika seseorang mengubah urutan untuk nama belakang dan nama depan, setidaknya dia akan tahu dia mengubah sesuatu yang diuji.

2
pmlarocque

Jawaban kanonik adalah "uji apa pun yang mungkin bisa pecah." Jika Anda yakin properti tidak akan pecah, jangan mengujinya.

Dan sekali ada sesuatu yang ditemukan rusak (Anda menemukan bug), jelas itu berarti Anda perlu mengujinya. Tulis tes untuk mereproduksi bug, lihat gagal, lalu perbaiki bug, lalu tonton tes lulus.

2
Eric Normand

Tidak ada ruginya menulis unit test untuk getter dan setter Anda. Saat ini, mereka mungkin hanya melakukan field get/sets di bawah tenda, tetapi di masa depan Anda mungkin memiliki logika validasi, atau dependensi antar-properti yang perlu diuji. Lebih mudah untuk menulisnya sekarang saat Anda memikirkannya lalu ingat untuk memperbaikinya jika saatnya tiba.

2
Bob King

Idealnya, Anda akan melakukan tes unit saat Anda menulis kelas. Beginilah seharusnya Anda melakukannya saat menggunakan Test Driven Development. Anda menambahkan tes saat Anda menerapkan setiap titik fungsi, memastikan bahwa Anda menutupi kasus Edge dengan tes juga.

Menulis tes sesudahnya jauh lebih menyakitkan, tetapi bisa dilakukan.

Inilah yang akan saya lakukan di posisi Anda:

  1. Tulis satu set tes dasar yang menguji fungsi inti.
  2. Dapatkan NCover dan jalankan di tes Anda. Cakupan tes Anda mungkin sekitar 50% pada saat ini.
  3. Terus tambahkan tes yang mencakup kasus Tepi Anda hingga Anda mendapatkan cakupan sekitar 80% -90%

Ini akan memberi Anda seperangkat unit kerja yang bagus yang akan bertindak sebagai penyangga yang baik terhadap regresi.

Satu-satunya masalah dengan pendekatan ini adalah bahwa kode harus dirancang untuk dapat diuji dengan cara ini. Jika Anda membuat kesalahan pemasangan sejak dini, Anda tidak akan bisa mendapatkan cakupan tinggi dengan sangat mudah.

Inilah sebabnya mengapa sangat penting untuk menulis tes sebelum Anda menulis kode. Ini memaksa Anda untuk menulis kode yang longgar digabungkan.

1
Simon Johnson

Itu membuat kode kita lebih baik ... titik!

Satu hal yang dilupakan oleh para pengembang perangkat lunak saat melakukan pengembangan yang didorong oleh tes adalah tujuan di balik tindakan kami. Jika tes unit sedang ditulis setelah kode produksi sudah ada, nilai tes turun (tetapi tidak sepenuhnya hilang).

Dalam semangat sejati untuk pengujian unit, pengujian ini bukan terutama di sana untuk "menguji" lebih banyak kode kita; atau untuk mendapatkan cakupan kode 90% -100% lebih baik. Ini semua manfaat pinggiran dari menulis tes terlebih dahulu. Keuntungan besar adalah bahwa kode produksi kami akhirnya ditulis jauh lebih baik karena proses alami TDD.

Untuk membantu mengomunikasikan ide ini dengan lebih baik, berikut ini mungkin membantu dalam membaca:

The Flawed Theory of Unit Tests
Pengembangan Perangkat Lunak Bertujuan

Jika kita merasa bahwa tindakan menulis lebih banyak tes unit adalah apa yang membantu kita mendapatkan produk yang lebih berkualitas, maka kita mungkin menderita dari Cargo Cult Pengembangan Berbasis Tes.

1
Scott Saad

Jangan menguji kode yang jelas bekerja (boilerplate). Jadi jika setter dan getter Anda hanya "propertyvalue = value" dan "return propertyvalue", tidak masuk akal untuk mengujinya.

1
erlando

Bahkan get/set dapat memiliki konsekuensi aneh, tergantung pada bagaimana mereka telah diterapkan, sehingga mereka harus diperlakukan sebagai metode.

Setiap pengujian ini perlu menentukan set parameter untuk properti, mendefinisikan properti yang dapat diterima dan tidak dapat diterima untuk memastikan panggilan kembali/gagal dengan cara yang diharapkan.

Anda juga perlu mengetahui adanya masalah keamanan, sebagai contoh injeksi SQL, dan uji untuk ini.

Jadi ya, Anda perlu khawatir tentang pengujian properti.

1
CestLaGalere

Saya percaya itu konyol untuk menguji getter & setter ketika mereka hanya melakukan operasi sederhana. Secara pribadi saya tidak menulis tes unit yang rumit untuk mencakup pola penggunaan apa pun. Saya mencoba menulis cukup tes untuk memastikan saya telah menangani perilaku eksekusi normal dan sebanyak kasus kesalahan yang dapat saya pikirkan. Saya akan menulis lebih banyak unit test sebagai tanggapan terhadap laporan bug. Saya menggunakan unit test untuk memastikan kode memenuhi persyaratan dan untuk membuat modifikasi di masa depan lebih mudah. Saya merasa jauh lebih bersedia untuk mengubah kode ketika saya tahu bahwa jika saya memecahkan sesuatu tes akan gagal.

1
Andrei Savu

Meskipun dimungkinkan untuk menebak dengan benar di mana kode Anda perlu pengujian, saya biasanya berpikir Anda perlu metrik untuk mendukung dugaan ini. Pengujian unit dalam pandangan saya sejalan dengan metrik cakupan kode.

Kode dengan banyak tes tetapi cakupan kecil belum diuji dengan baik. Yang mengatakan, kode dengan cakupan 100% tetapi tidak menguji kasus-kasus batas dan kesalahan juga tidak bagus.

Anda ingin keseimbangan antara cakupan tinggi (minimum 90%) dan data input variabel.

Ingatlah untuk menguji "sampah masuk"!

Juga, unit-test bukan unit-test kecuali itu memeriksa kegagalan. Tes unit yang tidak memiliki konfirmasi atau ditandai dengan pengecualian yang diketahui hanya akan menguji bahwa kode tidak mati saat dijalankan!

Anda perlu mendesain tes Anda sehingga selalu melaporkan kegagalan atau data yang tidak terduga/tidak diinginkan!

1
Ray Hayes

Saya akan menulis tes untuk apa pun yang Anda tulis kode untuk itu dapat diuji di luar antarmuka GUI.

Biasanya, setiap logika yang saya tulis yang memiliki logika bisnis apa pun saya tempatkan di dalam lapisan lain atau lapisan logika bisnis.

Kemudian menulis tes untuk apa pun yang melakukan sesuatu itu mudah dilakukan.

Lulus pertama, tulis uji unit untuk setiap metode publik di "Lapisan Logika Bisnis" Anda.

Jika saya memiliki kelas seperti ini:

   public class AccountService
    {
        public void DebitAccount(int accountNumber, double amount)
        {

        }

        public void CreditAccount(int accountNumber, double amount)
        {

        }

        public void CloseAccount(int accountNumber)
        {

        }
    }

Hal pertama yang akan saya lakukan sebelum saya menulis kode apa pun mengetahui bahwa saya memiliki tindakan untuk dilakukan adalah mulai menulis tes unit.

   [TestFixture]
    public class AccountServiceTests
    {
        [Test]
        public void DebitAccountTest()
        {

        }

        [Test]
        public void CreditAccountTest()
        {

        }

        [Test]
        public void CloseAccountTest()
        {

        }
    }

Tulis tes Anda untuk memvalidasi kode yang Anda tulis untuk melakukan sesuatu. Jika Anda mengulangi kumpulan hal-hal, dan mengubah sesuatu tentang masing-masing, tulis tes yang melakukan hal yang sama dan Tegaskan bahwa itu benar-benar terjadi.

Ada banyak pendekatan lain yang dapat Anda ambil, yaitu Behavoir Driven Development (BDD), yang lebih terlibat dan bukan tempat yang bagus untuk memulai dengan keterampilan pengujian unit Anda.

Jadi, moral dari cerita ini adalah, uji apa pun yang melakukan apa pun yang Anda khawatirkan, pertahankan unit ini menguji hal-hal tertentu yang berukuran kecil, banyak tes yang baik.

Simpan logika bisnis Anda di luar lapisan Antarmuka Pengguna sehingga Anda dapat dengan mudah menulis tes untuk mereka, dan Anda akan menjadi baik.

Saya merekomendasikan TestDriven.Net atau ReSharper karena keduanya mudah diintegrasikan ke dalam Visual Studio.

1
Dean Poulin

Seperti yang saya pahami unit test dalam konteks pengembangan lincah, Mike, ya, Anda perlu menguji getter dan setter (dengan asumsi mereka terlihat secara publik). Seluruh konsep pengujian unit adalah untuk menguji unit perangkat lunak, yang merupakan kelas dalam kasus ini, sebagai kotak hitam . Karena getter dan setter terlihat secara eksternal, Anda perlu mengujinya bersama dengan Otentikasi dan Simpan.

1
Onorio Catenacci

Jika metode Otentikasi dan Simpan menggunakan properti, maka pengujian Anda secara tidak langsung akan menyentuh properti. Selama properti hanya menyediakan akses ke data, maka pengujian eksplisit tidak diperlukan (kecuali Anda akan mendapatkan cakupan 100%).

1
Tom Walker

Saya akan menguji getter dan setter Anda. Bergantung pada siapa yang menulis kode, beberapa orang mengubah arti metode pengambil/penyetel. Saya telah melihat inisialisasi variabel dan validasi lainnya sebagai bagian dari metode pengambil. Untuk menguji hal semacam ini, Anda ingin tes unit mencakup kode itu secara eksplisit.

1
Peter Bernier

Secara pribadi saya akan "menguji apa pun yang dapat merusak" dan pengambil sederhana (atau properti otomatis yang lebih baik) tidak akan rusak. Saya tidak pernah mengalami kegagalan pernyataan pengembalian yang sederhana dan karenanya tidak pernah memiliki tes untuk mereka. Jika getter memiliki perhitungan di dalamnya atau beberapa bentuk pernyataan lainnya, saya pasti akan menambahkan tes untuk mereka.

Secara pribadi saya menggunakan Moq sebagai kerangka kerja objek tiruan dan kemudian memverifikasi bahwa objek saya memanggil objek di sekitarnya seperti yang seharusnya.

1
tronda

Anda harus membahas pelaksanaan setiap metode kelas dengan UT dan memeriksa nilai pengembalian metode. Ini termasuk pengambil dan penyetel, terutama jika anggota (properti) adalah kelas kompleks, yang membutuhkan alokasi memori besar selama inisialisasi mereka. Panggil setter dengan beberapa string yang sangat besar misalnya (atau sesuatu dengan simbol yunani) dan periksa hasilnya benar (tidak terpotong, pengkodean baik dll)

Dalam hal bilangan bulat sederhana yang juga berlaku - apa yang terjadi jika Anda melewati panjang bukannya bilangan bulat? Itulah alasan Anda menulis UT untuk :)

1
m_pGladiator

Pengujian suatu kelas harus memverifikasi bahwa:

  1. metode dan properti mengembalikan nilai yang diharapkan
  2. Pengecualian yang sesuai dilemparkan ketika argumen yang tidak valid diberikan
  3. Interaksi antara kelas dan objek lain terjadi seperti yang diharapkan ketika metode yang diberikan dipanggil

Tentu saja jika getter dan setter tidak memiliki logika khusus maka pengujian metode Otentikasi dan Hemat harus mencakup mereka, tetapi jika tidak, tes ledakan harus ditulis

1
Crippledsmurf

Saya akan merekomendasikan menulis beberapa tes untuk metode Otentikasi dan Simpan Anda. Selain kasus sukses (di mana semua parameter disediakan, semuanya dieja dengan benar, dll), ada baiknya untuk melakukan tes untuk berbagai kasus kegagalan (parameter salah atau hilang, koneksi database tidak tersedia jika berlaku, dll). Saya merekomendasikan Pengujian Unit Pragmatis dalam C # dengan NUnit sebagai referensi.

Seperti yang telah dinyatakan orang lain, pengujian unit untuk getter dan setter berlebihan, kecuali ada logika kondisional pada getter dan setter Anda.

1
Scott Lawrence

Saya tidak akan menguji pengaturan properti yang sebenarnya. Saya akan lebih peduli tentang bagaimana properti-properti itu dihuni oleh konsumen, dan dengan apa mereka mengisinya. Dengan pengujian apa pun, Anda harus menimbang risiko dengan waktu/biaya pengujian.

1
Bloodhound

Anda harus menguji "setiap blok kode non-sepele" menggunakan tes unit sejauh mungkin.

Jika properti Anda sepele dan tidak mungkin seseorang akan memperkenalkan bug di dalamnya, maka aman untuk tidak mengujinya.

Metode Otentikasi () dan Simpan () Anda tampak seperti kandidat yang baik untuk pengujian.

1
user7015

Menulis kode yang tidak memiliki nilai selalu merupakan ide yang buruk. Karena tes yang diusulkan tidak menambah nilai pada proyek Anda (atau sangat dekat dengan itu). Maka Anda membuang-buang waktu berharga bahwa Anda bisa menghabiskan kode menulis yang benar-benar membawa nilai.

0
pjesi

Saya yang kedua ji apa pun yang mungkin dapat merusak dan jangan menulis tes konyol. Tetapi prinsip yang paling penting adalah ji apa pun yang Anda temukan rusak: jika beberapa metode berperilaku aneh, tulis tes untuk menguraikan kumpulan data yang membuatnya gagal, lalu perbaiki bug dan lihat bilah berubah menjadi hijau. Juga menguji nilai data "batas" (null, 0, MAX_INT, daftar kosong, apa pun).

0
Manrico Corazzi

Saat menulis tes unit, atau benar-benar tes apa pun, Anda menentukan apa yang harus diuji dengan melihat kondisi batas dari apa yang Anda uji. Misalnya, Anda memiliki fungsi bernama is_prime. Untungnya, ia melakukan apa yang tersirat namanya dan memberi tahu Anda apakah objek integernya prima atau tidak. Untuk ini saya mengasumsikan Anda menggunakan objek. Sekarang, kita perlu memeriksa bahwa hasil yang valid terjadi untuk rentang objek prima dan non-prima yang diketahui. Itulah titik awal Anda.

Pada dasarnya, lihat apa yang harus terjadi dengan fungsi, metode, program, atau skrip, dan kemudian pada apa yang seharusnya tidak terjadi dengan kode yang sama. Itulah dasar untuk ujian Anda. Bersiaplah untuk memodifikasi tes Anda saat Anda menjadi lebih tahu tentang apa yang harus terjadi dengan kode Anda.

0
Dan

Aturan praktis terbaik yang pernah saya lihat adalah untuk menguji segala sesuatu yang tidak dapat Anda ketahui, pasti, akan bekerja dengan baik. Ada lagi dan akhirnya Anda menguji bahasa/lingkungan.

0
user74754