2010-04-09 10 views
35

Zarządzam dość dużą aplikacją (50k + linie kodu) samemu i zarządzam pewnymi krytycznymi działaniami biznesowymi. Aby opisać program w prosty sposób, powiedziałbym, że jest to wymyślny interfejs użytkownika z możliwością wyświetlania i zmieniania danych z bazy danych, a zarządza około 1000 jednostkami do wynajęcia, około 3 tys. Lokatorów i wszystkimi finansami.Aplikacja do testowania bazy danych z logiką biznesową przeprowadzoną w interfejsie użytkownika

Kiedy dokonuję zmian, ponieważ jest tak duża z bazy kodu, czasami coś łamam gdzieś indziej. Zazwyczaj testuję to, przechodząc przez rzeczy, które zmieniłem na poziomie funkcjonalnym (tj. Uruchamiam program i pracuję przez interfejs użytkownika), ale nie mogę testować dla każdej sytuacji. Właśnie dlatego chcę zacząć od testów jednostkowych.

Jednak nie jest to prawdziwy, trójwarstwowy program z warstwą bazy danych, warstwą biznesową i warstwą interfejsu użytkownika. Wiele logiki biznesowej jest wykonywanych w klasach interfejsu użytkownika, a wiele rzeczy odbywa się na wydarzeniach. Aby komplikować wszystko, wszystko opiera się na bazie danych i nie widziałem (jak dotąd) dobrych sugestii na temat jednostkowych interakcji z bazą danych.

Jaki byłby dobry sposób na rozpoczęcie testów jednostkowych dla tej aplikacji. Pamiętać. Nigdy wcześniej nie testowałem jednostki ani TDD. Czy powinienem przepisać go, aby usunąć logikę biznesową z klas UI (dużo pracy)? Czy jest jakiś lepszy sposób?

+1

@Malfist: 50K + linie kodu nie są duże: w najlepszym razie średnie. Napisałem w większości samodzielnie aplikację 200KLOC + (nie biorąc pod uwagę linii testowych) i uważam ją za średnią, niezbyt dużą :) – SyntaxT3rr0r

Odpowiedz

16

Zacznę od użycia narzędzia, które przetestuje aplikację za pośrednictwem interfejsu użytkownika. Istnieje szereg narzędzi, za pomocą których można tworzyć skrypty testowe symulujące klikanie aplikacji przez użytkownika.

Proponuję również, aby rozpocząć dodawanie testów jednostkowych po dodaniu nowych funkcji. Po opracowaniu aplikacji czasochłonne jest tworzenie pełnego zasięgu, ale jeśli robisz to stopniowo, rozprowadzasz wysiłek.

Testujemy interakcje z bazami danych, korzystając z oddzielnej bazy danych, która jest używana tylko do testów jednostkowych. W ten sposób mamy statyczny i kontrolowany zestaw danych, dzięki któremu można zagwarantować żądania i odpowiedzi. Następnie tworzymy kod C# do symulacji różnych scenariuszy. Do tego używamy nUnit.

+0

+1 dodawanie testów jednostkowych podczas dodawania funkcjonalności –

+2

+1 do testowania jednostki w miarę dodawania funkcjonalności, ale myślę, że dodając nową funkcjonalność, powinieneś oportunistycznie refaktoryzować stary nietestowany kod i dodawać nowe testy dla refaktoryzowanych bitów . Może to również stanowić "punkt wejścia" do dodawania kolejnych testów i stopniowego zwiększania zasięgu testów. – Pete

6

Jedną z opcji jest to, że za każdym razem, gdy pojawia się błąd, napisz test, który pomoże ci znaleźć błąd i rozwiązać problem. Spraw, aby test zakończył się, gdy błąd zostanie naprawiony. Następnie, po usunięciu błędu, masz narzędzie, które pomoże Ci wykryć przyszłe zmiany, które mogą wpłynąć na fragment kodu, który właśnie naprawiłeś. Z biegiem czasu zakres testowy ulegnie poprawie i będziesz mógł uruchamiać ciągle rosnący zestaw testów za każdym razem, gdy podejmiesz potencjalnie daleko idącą zmianę.

+0

To zawsze dobry pomysł, ale to nie pomoże w testowaniu dziwnych interakcji, które mogą być nieoczekiwane. –

6

TDD oznacza, że ​​budujesz (i uruchamiasz) testy jednostkowe w trakcie pracy. Za to, co próbujesz zrobić - dodaj testy jednostkowe po fakcie - możesz rozważyć użycie czegoś takiego jak Typemock (produkt komercyjny). Możliwe, że zbudowałeś system, który nie nadaje się do testowania jednostkowego, i w tym przypadku niektóre (lub wiele) refaktoryzacji mogą być w porządku.

3

Refaktoryzacja to lepszy sposób. Mimo że proces ten jest zniechęcający, zdecydowanie należy oddzielić prezentację od logiki biznesowej. Nie będziesz w stanie napisać dobrych testów jednostkowych przeciwko twojej logiki biz, dopóki nie dokonasz rozstania. To takie proste.

W procesie refaktoryzacji prawdopodobnie znajdziesz błędy, o których istnieniu nawet nie wiedziałeś, a na koniec będziesz o wiele lepszym programistą!

Ponadto, po przeliczeniu kodu zauważysz, że testowanie interakcji z db stanie się znacznie łatwiejsze. Będziesz mógł napisać testy, które wykonają takie działania jak: "dodaj nowego dzierżawcę", co będzie wymagało stworzenia pozornego obiektu dzierżawcy i zapisania "go" do bazy danych.Dla następnego testu napiszesz "GetTenant" i spróbujesz uzyskać tego lokatora, który właśnie utworzyłeś z bazy danych i do reprezentacji w pamięci ... Następnie porównaj pierwszego i drugiego dzierżawcę, aby upewnić się, że wszystkie pola odpowiadają wartościom. Itd. Itd.

0

Myślę, że zawsze dobrze jest oddzielić logikę biznesową od interfejsu użytkownika. Istnieje wiele korzyści, w tym łatwiejsze testowanie jednostkowe i rozszerzalność. Możesz również odwołać się do programowania opartego na wzorcach. Oto link http://en.wikipedia.org/wiki/Design_pattern_(computer_science), który pomoże Ci zrozumieć wzorce projektowe.

Jedną rzeczą, którą możesz zrobić na razie, jest to, że w obrębie twoich klas UI są izolowane wszystkie logiki biznesowe i różne funkcje baz biznesowych, a w każdym konstruktorze UI lub page_load są wywoływane testy jednostkowe, które testują każdą z funkcji biznesowych. W celu zwiększenia czytelności można zastosować znacznik #region wokół funkcji biznesowych.

Aby uzyskać długoterminowe korzyści, należy przestudiować wzorce projektowe. Wybierz wzór, który odpowiada Twoim potrzebom projektu i przerób swój projekt za pomocą wzoru projektu.

+0

Jeden wzór wzoru nie będzie pasował do tak dużej aplikacji, a także dopasowany na siłę wzór projektu, w przypadku gdy nie jest potrzebny, jest uważany za wzór zapobiegający. Co robią nowicjusze, kiedy jeszcze się uczą. W razie potrzeby w tej aplikacji stosowane są wzorce projektowe. – Malfist

0

To zależy od języka, którego używasz. Zwykle jednak zacznij od prostej klasy testowej, która wykorzystuje niektóre dane (ale nadal coś "prawdziwego"), aby przetestować kod. Spraw, aby symulował to, co stanie się w aplikacji. Jeśli robisz zmiany w konkretnej części aplikacji, napisz coś, co zadziała, zanim zmienisz kod. Skoro już napisałeś kod, testowanie się będzie sporym wyzwaniem podczas próby przetestowania całej aplikacji. Proponuję zacząć od małego. Ale teraz, kiedy piszesz kod, napisz najpierw test jednostkowy, a następnie napisz swój kod. Możesz także rozważyć refaktoryzację, ale rozważałbym koszty refaktoryzacji i przepisywania trochę, podczas gdy po drodze przechodzi się testy jednostkowe.

5

Po pierwsze, polecam lekturę dobrej książki o testowaniu jednostkowym, np. The Art Of Unit Testing. W twoim przypadku, to trochę późno, aby wykonać Test-Driven Development w istniejącym kodzie, ale jeśli chcesz pisać testy jednostkowe wokół niego, to tutaj jest to, co polecam:

  1. Izolowanie kodu chcesz przetestować do bibliotek kodu (jeśli nie są jeszcze w bibliotekach).
  2. Zapisać najczęstsze scenariusze użycia scenariuszy i przetłumaczyć je na aplikację korzystającą z bibliotek kodu.
  3. Upewnij się, że program testowy działa zgodnie z oczekiwaniami.
  4. Konwertuj swój program testowy na testy jednostkowe przy użyciu szkieletu testowego.
  5. Zdobądź zielone światło. Jeśli nie, to twoje testy jednostkowe są błędne (zakładając, że działają biblioteki kodów) i powinieneś zrobić trochę debugowania.
  6. Zwiększyć kod i zakres scenariuszy testów jednostki: Co zrobić, jeśli wprowadzono nieoczekiwane wyniki?
  7. Zbierz zielone światło ponownie. Jeśli test jednostkowy nie powiedzie się, prawdopodobnie biblioteka kodu nie obsługuje rozszerzonego zakresu scenariuszy, więc jest to czas refaktoryzacji!

A dla nowego kodu, proponuję wypróbować go za pomocą Test Driven Development.

Powodzenia (trzeba go!)

+1

+1 dla testu Art of Unit - dobra książka! – TrueWill

0

Nie ma lepszego sposobu na rozpoczęcie testów jednostkowych niż na wypróbuj go - to nie potrwa długo, jest zabawne i uzależniające. Ale tylko jeśli pracujesz nad testowalnym kodem.

Jeśli jednak spróbujesz nauczyć się testowania jednostkowego, poprawiając aplikację, taką jak ta opisana od razu, prawdopodobnie poczujesz się sfrustrowany i zniechęcony - i jest duża szansa, że ​​pomyślisz, że testowanie jednostkowe jest strata czasu.

Polecam pobranie architektury testowania jednostkowego, takiej jak NUnit lub XUnit.Net. Większość tych frameworków posiada dokumentację online, która zawiera krótkie wprowadzenie, takie jak NUnit Quick Start. Przeczytaj to, a następnie wybierz prostą, niezależną klasę, która:

  • Ma niewiele lub nie ma zależności w innych klasach - przynajmniej nie na klasach złożonych.
  • Ma pewne zachowanie: prosty pojemnik z wieloma właściwościami nie pokaże zbyt wiele na temat testów jednostkowych.

Spróbuj napisać kilka testów, aby uzyskać dobre pokrycie tej klasy, a następnie skompiluj i uruchom testy.

Gdy już to zrozumiesz, zacznij szukać okazji do refactor your existing code, zwłaszcza podczas dodawania nowych funkcji lub naprawiania błędów. Kiedy te refaktoryzacje prowadzą do klas, które spełniają powyższe kryteria, napisz dla nich kilka testów. Kiedy już się przyzwyczaisz, you can start by writing tests.

0

Nie próbowałem dodawać testów dla starszych aplikacji, ponieważ jest to naprawdę trudne zadanie. Jeśli planujesz przenieść część logiki biznesowej z interfejsu użytkownika i na osobnej warstwie, możesz dodać tutaj swoje początkowe jednostki testowe (refaktoryzacja i TDD). W ten sposób otrzymasz wprowadzenie do tworzenia testów jednostkowych dla twojego systemu. To naprawdę dużo pracy, ale myślę, że to najlepsze miejsce na początek. Ponieważ jest to aplikacja bazująca na bazie danych, sugeruję użycie niektórych narzędzi szyderczych i narzędzi DBunit podczas tworzenia testu w celu symulacji problemów związanych z bazą danych.

Powiązane problemy