Tes unit: pernyataan ditangguhkan dengan Linq

18

Apakah boleh menambahkan pernyataan yang ditangguhkan seperti ini

var actualKittens = actualKittens.Select(kitten => {
    Assert.IsСute(kitten);
    return kitten
});

Mengapa? Jadi saya bisa mengulangi sekali saja dengan pernyataan yang mengharapkan koleksi terwujud misalnya:

CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Dan juga bisa tidak hanya Pilih tetapi metode dengan iterator didefinisikan dan memiliki banyak pemeriksaan dan logika (misalnya beberapa penghitungan dan penyaringan).

Benih keraguan adalah kerumitan membaca dan men-debug kode tersebut jika gagal uji.

SerG
sumber
1
Saya tidak akan mengandalkan ini untuk pengujian tetapi kadang-kadang OK untuk melakukan ini dalam kode produksi jika tidak ada solusi yang lebih baik. Anda bisa menjadikan diri Anda sebagai penolong sequence.WithSideEffect(item => Assert.IsCute(item))untuk membuatnya lebih bersih.
usr
@ usr Sepertinya Anda menangkap cacat kunci seperti itu - Efek samping dari iterator.
SerG
Apakah Anda masih harus mengulang dua kali, sekali untuk menghasilkan daftar dan lagi untuk membandingkannya expectedKittens? Anda baru saja menyembunyikan iterasi di balik pemanggilan metode.
IllusiveBrian
@IllusiveBrian Dalam hal ini, dalam contoh, ya. Ini masih kurang dibandingkan dengan tambahan .All().
SerG

Jawaban:

37

Apakah boleh menambahkan pernyataan yang ditangguhkan seperti ini [..]

Tidak . Mengapa? Karena jika Anda karena alasan apa pun menghapus yang kedua menegaskan tes akan tetap berubah menjadi hijau dan Anda akan berpikir itu masih berfungsi tetapi tidak karena koleksi tidak akan mendapatkan pencacahan. Jika Anda memiliki dua atau lebih pernyataan independen, mereka akan tetap melakukan pekerjaan mereka meskipun Anda menonaktifkannya.

Pertimbangkan kombinasi ini:

Assert.IsTrue(actualKittens.All(x => x.IsCute());
CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Sekarang bahkan jika Anda menonaktifkan atau menghapus salah satu yang menegaskan yang lain masih akan melakukan tugasnya. Juga jika Anda lupa untuk mematerialisasikan koleksi, mungkin perlu waktu lebih lama untuk menjalankannya tetapi itu masih berfungsi. Tes independen lebih kuat dan andal.

Ada juga no kedua . Saya tidak yakin bagaimana kerangka kerja lain menanganinya tetapi jika Anda menggunakan platform MS Test maka Anda tidak akan tahu tes mana yang gagal. Jika Anda mengklik dua kali tes gagal itu akan menunjukkan kepada Anda CollectionAssertsebagai gagal tetapi pada kenyataannya itu adalah sarang Assertyang salah dan itu akan sangat sulit untuk di-debug. Ini sebuah contoh:

    [TestMethod]
    public void TestMethod()
    {
        var numbers = new[] { 1, 2, 3 }.Select(x =>
        {
            Assert.Fail("Wrong number.");
            return x;
        });

        // This will fail and you won't be sure why.
        CollectionAssert.AreEqual(new[] { 1, 2, 3 }, numbers.ToList()); 

    }

Ini berarti bahwa tes pertama sebenarnya tidak berguna karena tidak membantu menemukan bug. Anda tidak tahu apakah itu gagal karena angka tidak valid atau karena kedua koleksi berbeda.


Mengapa? Jadi saya bisa mengulanginya sekali saja dengan pernyataan yang mengharapkan koleksi terwujud

Aku ingin tahu mengapa kamu peduli tentang itu? Ini adalah unit test. Anda tidak harus mengoptimalkan setiap bitnya dan biasanya pengujian tidak memerlukan jutaan item sehingga kinerja tidak perlu menjadi perhatian.

Anda harus mempertahankan tes semacam itu, jadi mengapa Anda harus membuatnya lebih kompleks daripada yang diperlukan? Tulis pernyataan sederhana yang berfungsi.

t3chb0t
sumber
Jika karena alasan tertentu penegasan tidak perlu dikubur dalam aliran kontrol, salah satu cara untuk memastikan bahwa itu dieksekusi adalah untuk menjaga counter / bendera yang bertambah / disetel ke true sebelum pernyataan bersarang. Kemudian, kita dapat menyatakan bahwa aliran kendali yang diharapkan telah diambil dengan memeriksa penghitung ini. Tidak sempurna, tetapi sebagian besar membahas kritik pertama Anda.
amon
1
Selain itu, Anda atau orang lain akan kembali ke pernyataan yang ditangguhkan dalam waktu 6 bulan dan harus membuang waktu untuk mengetahuinya.
DavidTheWin
Ada yang salah dengan contoh Anda. Memanggil ToListakan mengulangi enumerable, bukan?
RubberDuck
1
@ RubberDuck ya, itu akan dan itu juga akan gagal namun tidak di Assert.Failtetapi di CollectionAssertdan Anda tidak akan bisa mengatakan yang benar-benar salah. Maksud saya VS tidak akan fokus Assert.Failtetapi yang lain ... sekarang Anda bisa men-debug.
t3chb0t