Bagaimana TDD Pelaksanaan Daftar di Jawa

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melalui implementasi Daftar khusus menggunakan proses Pengujian Bergerak (TDD).

Ini bukan pengenalan kepada TDD, jadi kami menganggap anda sudah memiliki beberapa idea asas tentang apa maksudnya dan minat berterusan untuk menjadi lebih baik.

Ringkasnya, TDD adalah alat reka bentuk, yang memungkinkan kami mendorong pelaksanaan kami dengan bantuan ujian .

Penafian cepat - kami tidak memberi tumpuan untuk mewujudkan pelaksanaan yang cekap di sini - hanya menggunakannya sebagai alasan untuk menunjukkan amalan TDD.

2. Bermula

Pertama, mari tentukan rangka untuk kelas kami:

public class CustomList implements List { private Object[] internal = {}; // empty implementation methods } 

The CustomList alat kelas Senarai antara muka, oleh itu ia mesti mengandungi pelaksanaan untuk semua kaedah diisytiharkan dalam antara muka itu.

Untuk memulakan, kami hanya dapat menyediakan badan kosong untuk kaedah tersebut. Sekiranya kaedah mempunyai jenis pengembalian, kita dapat mengembalikan nilai sewenang-wenang dari jenis itu, seperti nol untuk Objek atau salah untuk boolean .

Demi singkatnya, kami akan menghilangkan kaedah pilihan, bersama dengan beberapa kaedah wajib yang tidak sering digunakan.

3. Kitaran TDD

Mengembangkan pelaksanaan kami dengan TDD bermaksud bahawa kita perlu membuat kes ujian terlebih dahulu , dengan demikian menentukan syarat untuk pelaksanaan kita. Hanya dengan itu kita akan membuat atau memperbaiki kod pelaksanaan untuk membuat ujian tersebut lulus.

Dengan cara yang sangat mudah, tiga langkah utama dalam setiap kitaran adalah:

  1. Ujian penulisan - menentukan keperluan dalam bentuk ujian
  2. Melaksanakan ciri - membuat ujian lulus tanpa terlalu fokus pada keanggunan kod
  3. Pemfaktoran semula - tingkatkan kod agar lebih mudah dibaca dan dikekalkan semasa masih lulus ujian

Kami akan pergi melalui kitaran TDD bagi beberapa kaedah daripada Senarai muka, bermula dengan yang paling mudah.

4. Kaedah isEmpty

The isEmpty kaedah mungkin merupakan kaedah yang paling mudah yang ditakrifkan dalam Senarai antara muka. Inilah pelaksanaan permulaan kami:

@Override public boolean isEmpty() { return false; }

Definisi kaedah awal ini cukup untuk disusun. Bahagian kaedah ini akan "dipaksa" untuk bertambah baik apabila semakin banyak ujian ditambahkan.

4.1. Kitaran Pertama

Mari tulis kes ujian pertama yang memastikan bahawa kaedah isEmpty kembali benar apabila senarai tidak mengandungi unsur:

@Test public void givenEmptyList_whenIsEmpty_thenTrueIsReturned() { List list = new CustomList(); assertTrue(list.isEmpty()); }

Ujian yang diberikan gagal kerana kaedah isEmpty selalu kembali palsu . Kami dapat membuatnya lulus dengan membalikkan nilai pulangan:

@Override public boolean isEmpty() { return true; }

4.2. Kitaran Kedua

Untuk mengesahkan bahawa kaedah isEmpty mengembalikan salah apabila senarai tidak kosong, kita perlu menambahkan sekurang-kurangnya satu elemen:

@Test public void givenNonEmptyList_whenIsEmpty_thenFalseIsReturned() { List list = new CustomList(); list.add(null); assertFalse(list.isEmpty()); }

Pelaksanaan kaedah tambah kini diperlukan. Inilah kaedah tambah yang kita mulakan dengan:

@Override public boolean add(E element) { return false; }

Pelaksanaan kaedah ini tidak berfungsi kerana tidak ada perubahan pada struktur data dalaman senarai yang dibuat. Mari kita kemas kini untuk menyimpan elemen tambahan:

@Override public boolean add(E element) { internal = new Object[] { element }; return false; }

Ujian kami masih gagal kerana kaedah isEmpty belum ditingkatkan. Mari buat:

@Override public boolean isEmpty() { if (internal.length != 0) { return false; } else { return true; } }

Ujian tidak kosong lulus pada ketika ini.

4.3. Pemfaktoran semula

Kedua-dua kes ujian yang telah kita lihat sejauh ini berlalu, tetapi kod kaedah isEmpty mungkin lebih elegan.

Mari kita memperbaikinya:

@Override public boolean isEmpty() { return internal.length == 0; }

Kita dapat melihat bahawa ujian lulus, jadi pelaksanaan kaedah isEmpty sudah selesai sekarang.

5. Kaedah ukuran

Ini adalah permulaan kami untuk kaedah ukuran yang membolehkan kelas CustomList menyusun:

@Override public int size() { return 0; }

5.1. Kitaran Pertama

Dengan menggunakan kaedah tambah yang ada , kita dapat membuat ujian pertama untuk kaedah ukuran , mengesahkan bahawa ukuran senarai dengan satu elemen adalah 1 :

@Test public void givenListWithAnElement_whenSize_thenOneIsReturned() { List list = new CustomList(); list.add(null); assertEquals(1, list.size()); }

Ujian gagal kerana kaedah ukuran kembali 0 . Mari kita laksanakan dengan pelaksanaan baru:

@Override public int size() { if (isEmpty()) { return 0; } else { return internal.length; } }

5.2. Pemfaktoran semula

Kita boleh memperbetulkan kaedah ukuran agar lebih elegan:

@Override public int size() { return internal.length; }

Pelaksanaan kaedah ini kini selesai.

6. Kaedah mendapatkan

Inilah permulaan pelaksanaan get :

@Override public E get(int index) { return null; }

6.1. Kitaran Pertama

Mari kita lihat ujian pertama untuk kaedah ini, yang mengesahkan nilai elemen tunggal dalam senarai:

@Test public void givenListWithAnElement_whenGet_thenThatElementIsReturned() { List list = new CustomList(); list.add("baeldung"); Object element = list.get(0); assertEquals("baeldung", element); }

Ujian akan lulus dengan pelaksanaan kaedah get ini:

@Override public E get(int index) { return (E) internal[0]; }

6.2. Penambahbaikan

Biasanya, kami akan menambahkan lebih banyak ujian sebelum membuat penambahbaikan tambahan pada kaedah mendapatkan . Ujian tersebut akan memerlukan kaedah yang lain daripada Senarai antara muka untuk melaksanakan pernyataan yang betul.

Walau bagaimanapun, kaedah lain ini belum cukup matang, oleh itu, kami mematahkan kitaran TDD dan membuat pelaksanaan kaedah get lengkap , yang sebenarnya, tidak terlalu sukar.

Sangat mudah untuk membayangkan bahawa get mesti mengekstrak elemen dari tatasusunan dalaman di lokasi yang ditentukan menggunakan parameter indeks :

@Override public E get(int index) { return (E) internal[index]; }

7. Kaedah tambah

Ini adalah kaedah tambah yang kami buat di bahagian 4:

@Override public boolean add(E element) { internal = new Object[] { element }; return false; }

7.1. Kitaran Pertama

Berikut ini adalah ujian mudah yang mengesahkan nilai pulangan tambah :

@Test public void givenEmptyList_whenElementIsAdded_thenGetReturnsThatElement() { List list = new CustomList(); boolean succeeded = list.add(null); assertTrue(succeeded); }

Kita mesti mengubah kaedah tambah untuk kembali benar agar ujian lulus:

@Override public boolean add(E element) { internal = new Object[] { element }; return true; }

Although the test passes, the add method doesn't cover all cases yet. If we add a second element to the list, the existing element will be lost.

7.2. The Second Cycle

Here's another test adding the requirement that the list can contain more than one element:

@Test public void givenListWithAnElement_whenAnotherIsAdded_thenGetReturnsBoth() { List list = new CustomList(); list.add("baeldung"); list.add(".com"); Object element1 = list.get(0); Object element2 = list.get(1); assertEquals("baeldung", element1); assertEquals(".com", element2); }

The test will fail since the add method in its current form doesn't allow more than one element to be added.

Let's change the implementation code:

@Override public boolean add(E element) { Object[] temp = Arrays.copyOf(internal, internal.length + 1); temp[internal.length] = element; internal = temp; return true; }

The implementation is elegant enough, hence we don't need to refactor it.

8. Conclusion

Tutorial ini melalui proses pengembangan yang diuji untuk membuat sebahagian dari pelaksanaan Daftar khusus . Dengan menggunakan TDD, kami dapat menerapkan persyaratan secara bertahap, sambil menjaga liputan ujian pada tahap yang sangat tinggi. Juga, pelaksanaannya dijamin dapat diuji, karena dibuat untuk membuat ujian lulus.

Perhatikan bahawa kelas khusus yang dibuat dalam artikel ini hanya digunakan untuk tujuan demonstrasi dan tidak boleh diterima pakai dalam projek dunia nyata.

Kod sumber lengkap untuk tutorial ini, termasuk kaedah ujian dan pelaksanaan yang ditinggalkan demi kesingkat, boleh didapati di GitHub.