Kwiecień
10
2009

Drzewo sortujące – testy

Słowa kluczowe: , , | Kategorie: Java
No Gravatar

Postanowiłem przetestować działanie drzewa sortującego przy wykorzystaniu mechanizmów, jakie udostępnia biblioteka JUnit 4. Jednak moja klasa jest typem generycznym i chciałbym mieć możliwość przetestowania jej funkcjonalności dla różnych elementów – liczb całkowitych i rzeczywistych, ale też np. dat.

Najszybszym sposobem wykonania tych samych testów dla różnych drzew sortujących jest użycie parametryzacji. Zacznę od pustej klasy:

import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class SortingTreeTest {
}

Do wykonania testu będzie potrzebne drzewo oraz posortowana lista wartości do sprawdzenia wyniku:

private SortingTree<?> tree;
private List<?> sortedItems;

Testowanie składa się z pobrania listy posortowanej przez drzewo (3–5), wypisaniu tej listy na konsolę (7–9) oraz porównaniu wyniku z zadaną listą posotrowaną (11–13):

@Test
public void testSorting() {
 List<Object> list =
  new ArrayList<Object>();
 this.tree.addSortedItems(list);

 for (Object item : list)
  System.out.printf("%s, ", item);
 System.out.println();

 assertArrayEquals(
   list.toArray(),
   this.sortedItems.toArray());
}

Najpierw utworzę metodę statyczną, zwracającą listę zestawów parametrów:

@Parameters
public static Collection<Object[]> getParameters() {
 return Arrays.asList(new Object[][] {
 });
}

Parametrami będą kolejno:

  • drzewo sortujące,
  • lista elementów,
  • posortowana lista elementów.

Dodaję kolejne zestawy parametrów – dla liczb całkowitych:

{
 new SortingTree<Integer>(),
 Arrays.asList(new Integer[] {
   0, 100, 20, 10, 15, 30}),
 Arrays.asList(new Integer[] {
   0, 10, 15, 20, 30, 100})
},

dla liczb rzeczywistych:

{
 new SortingTree<Double>(),
 Arrays.asList(new Double[] {
   0.0, 100.0, 20.0,
   10.0, 15.0, 30.0}),
 Arrays.asList(new Double[] {
   0.0, 10.0, 15.0,
   20.0, 30.0, 100.0})
},

dla wartości bajtów:

{
 new SortingTree<Byte>(),
 Arrays.asList(new Byte[] {
   5, 2, 7, 1, 9, 3}),
 Arrays.asList(new Byte[] {
   1, 2, 3, 5, 7, 9})
},

dla dat i czasów:

{
 new SortingTree<Date>(),
 Arrays.asList(new Date[] {
   new Timestamp(1234567890),
   new Time(3600000),
   new Date(),
   new Timestamp(100000000),
   new Timestamp(94000000),
   new Timestamp(-1000),}),
 Arrays.asList(new Date[] {
   new Timestamp(-1000),
   new Time(3600000),
   new Timestamp(94000000),
   new Timestamp(100000000),
   new Timestamp(1234567890),
   new Date(),})
},

Pozostało tylko utworzenie konstruktora, przyjmującego zdefiniowane parametry:

public <T extends Comparable<? super T>>
SortingTreeTest(
  SortingTree<T> tree,
  List<T> items,
  List<T> sortedItems) {
 tree.addAll(items);
 this.tree = tree;
 this.sortedItems = sortedItems;
}

Konstruktor dodaje elementy do drzewa i inicjuje pola klasy testowej. Zastosowanie generycznego konstruktora pozwala na zapewnienie jednego porównywalnego (Comparable) typu elementów drzewa i obu list.

Po uruchomieniu testy zwróciły mi następujące wyniki:

0, 10, 15, 20, 30, 100,
0.0, 10.0, 15.0, 20.0, 30.0, 100.0,
1, 2, 3, 5, 7, 9,
1970-01-01 00:59:59.0, 02:00:00, 1970-01-02 03:06:40.0, 1970-01-02 04:46:40.0, 1970-01-15 07:56:07.89, Fri Apr 10 00:07:53 CEST 2009,

Jeszcze krótkie wyjaśnienie dotyczące dat i czasów. Czas liczony jest w milisekundach od północy 1 stycznia 1970 roku. Polska znajduje się w strefie GMT+1. Zatem Timestamp(0) to 1970-01-01 00:00:00.0 GMT, czyli 1970-01-01 01:00:00.0 czasu polskiego.

1970-01-01 00:59:59.0
sekunda (1000 ms) przed północą GMT, czyli sekunda przed godziną 01:00 czasu polskiego,
02:00:00
godzina druga czasu polskiego (użyta została klasa Time, nie Timestamp),
1970-01-02 03:06:40.0
Timestamp(94000000),
1970-01-02 04:46:40.0
Timestamp(100000000),
1970-01-15 07:56:07.89
Timestamp(1234567890),
Fri Apr 10 00:07:53 CEST 2009
konstruktor java.util.Date() tworzy obiekt z bieżącym czasem – testy wykonywałem w piątek 10 kwietnia 2009 roku 7 minut i 53 sekundy po północy czasu letniego (ang. CEST).

Wykorzystując jedną klasę testową wykonałem ten sam test na drzewach sortujących obiekty różnych typów. W podobny sposób można przetestować także inne typy generyczne pod kątem wszechstronności.

Napisz Komentarz

*