Pertanyaan Pengujian unit: mengapa argumen yang diharapkan selalu pertama dalam tes kesetaraan?


Mengapa setiap unit pengujian kerangka (saya tahu :) mengharuskan bahwa nilai yang diharapkan dalam tes kesetaraan selalu merupakan argumen pertama:

Assert.AreEqual(42, Util.GetAnswerToLifeTheUniverseAndEverything());

assertEquals(42, Util.GetAnswerToLifeTheUniverseAndEverything());

dll.

Saya cukup terbiasa sekarang, tetapi setiap programmer saya mencoba untuk mengajar pengujian unit membuat kesalahan dengan membalikkan argumen, yang saya pahami dengan sempurna. Google tidak membantu, mungkin salah satu penguji unit hard-core di sini tahu jawabannya?


32
2018-02-17 15:45


asal


Jawaban:


Saya pikir itu hanya sebuah konvensi sekarang dan seperti yang Anda katakan itu diadopsi oleh "setiap unit pengujian kerangka (saya tahu)". Jika Anda menggunakan kerangka kerja, akan sangat mengganggu untuk beralih ke kerangka lain yang menggunakan konvensi yang berlawanan. Jadi (jika Anda menulis kerangka pengujian unit baru misalnya) akan lebih baik bagi Anda untuk mengikuti konvensi yang ada. Saya percaya ini berasal dari cara beberapa pengembang lebih suka menulis tes kesetaraan mereka:

if (4 == myVar)

Untuk menghindari penugasan yang tidak diinginkan, secara tidak sengaja, menulis satu "=" alih-alih "==". Dalam hal ini compiler akan menangkap kesalahan ini dan Anda akan menghindari banyak masalah mencoba memperbaiki bug runtime yang aneh.


9
2018-02-17 15:54



Tampaknya sebagian besar kerangka kerja awal digunakan diharapkan sebelum sebenarnya (untuk beberapa alasan yang tidak diketahui meskipun, dadu gulung mungkin?). Padahal dengan perkembangan bahasa pemrograman, dan meningkat kelancaran kode, urutan itu terbalik. Kebanyakan antarmuka yang lancar biasanya mencoba untuk meniru bahasa alami dan kerangka pengujian unit tidak berbeda.

Dalam pernyataannya, kami ingin memastikan bahwa beberapa objek cocok dengan beberapa kondisi. Ini adalah bentuk bahasa alami, seolah-olah Anda menjelaskan kode tes Anda mungkin akan mengatakan

"Dalam tes ini, saya pastikan bahwa nilai yang dihitung sama dengan 5"

dari pada

"Dalam tes ini, saya pastikan bahwa 5 sama dengan nilai yang dihitung".

Perbedaannya mungkin tidak besar, tetapi mari kita dorong lebih jauh. Pertimbangkan ini:

Assert.That(Roses, Are(Red));

Kedengarannya benar. Sekarang:

Assert.That(Red, Are(Roses));

Hm ..? Anda mungkin tidak akan terlalu terkejut jika seseorang mengatakan itu pada Anda bunga mawar itu berwarna merah. Sebaliknya, merah adalah mawar, menimbulkan pertanyaan yang mencurigakan. Yodasiapa saja?

That doesn't sound natural at all

Yoda membuat poin penting - urutan terbalik memaksa Anda berpikir.

Itu mendapat lebih banyak lagi tidak wajar ketika pernyataan Anda lebih kompleks:

Assert.That(Forest, Has.MoreThan(15, Trees));

Bagaimana Anda akan membalikkan yang satu itu? Lebih dari 15 pohon dimiliki oleh hutan?

Klaim ini (kelancaran sebagai faktor pendorong untuk modifikasi) entah bagaimana tercermin dalam perubahan yang NUnit telah lalui - awalnya (Assert.AreEqual) Itu digunakan diharapkan sebelum sebenarnya (gaya lama). Ekstensi lancar (atau menggunakan terminologi NUnit, berdasarkan kendala - Assert.That) membalik urutan itu.


26
2018-02-17 15:58



Tidak ada yang tahu dan itu adalah sumber kebingungan yang tak pernah berakhir. Namun tidak semua kerangka kerja mengikuti pola ini (ke kebingungan yang lebih besar):

  1. FEST-menegaskanmenggunakan normal memesan:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything()).isEqualTo(42);
    
  2. Hamcrest:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything(), equalTo(42))
    
  3. ScalaTest tidak benar-benar membuat perbedaan:

    Util.GetAnswerToLifeTheUniverseAndEverything() should equal (42)
    

5
2018-02-17 15:47



Saya tidak tahu, tetapi saya telah menjadi bagian dari beberapa diskusi animasi tentang urutan argumen untuk tes kesetaraan secara umum.

Ada banyak orang yang berpikir

if (42 == answer) {
  doSomething();
}

lebih baik daripada

if (answer == 42) {
  doSomething();
}

dalam bahasa berbasis C. Alasannya adalah jika Anda secara tidak sengaja meletakkan tanda sama dengan:

if (42 = answer) {
  doSomething();
}

akan memberi Anda kesalahan kompiler, tapi

if (answer = 42) {
  doSomething();
}

mungkin tidak, dan pasti akan memperkenalkan bug yang mungkin sulit untuk dilacak. Jadi siapa yang tahu, mungkin orang / orang yang mengatur kerangka pengujian unit digunakan untuk memikirkan tes kesetaraan dengan cara ini - atau mereka menyalin kerangka pengujian unit lain yang sudah diatur dengan cara ini.


3
2018-02-17 15:55



Saya pikir itu karena JUnit adalah pelopor dari sebagian besar unit pengujian kerangka kerja (bukan bahwa itu adalah unit pengujian unit pertama, tetapi itu memulai ledakan dalam pengujian unit). Karena JUnit melakukannya dengan cara itu, semua kerangka kerja berikutnya menyalin formulir ini dan itu menjadi konvensi.

kenapa JUnit melakukannya seperti itu? Saya tidak tahu, tanya Kent Beck!


1
2018-02-17 15:56



Mereka harus memilih satu konvensi. Jika Anda ingin membalikkannya, coba lawan Hamcrest. Mereka dimaksudkan untuk membantu meningkatkan keterbacaan. Berikut ini contoh dasar:

import org.junit.Test;
import static org.junit.Assert.assertThat;
import static org.hamcrest.core.Is.is;

public HamcrestTest{
   @Test
   public void matcherShouldWork(){
       assertThat(   Math.pow( 2, 3 ),  is( 8 )  );
   }
}

0
2018-02-17 17:41



Karena, sayangnya, tidak banyak programmer yang membaca Kemandirian oleh Ralph Waldo Emerson.


0
2017-08-06 18:54



Tentunya itu masuk akal logis untuk menempatkan nilai yang diharapkan pertama, karena itu nilai pertama yang diketahui.

Pikirkan itu dalam konteks tes manual. Tes manual akan memiliki nilai yang diharapkan ditulis, dengan nilai aktual yang tercatat sesudahnya.


-1
2018-04-20 10:13