Zostałem poproszony o wykonanie małego projektu pobocznego, aby dostarczyć prostą aplikację jednemu z naszych klientów. Normalnie pracowałbym nad kodem zaplecza, w którym mam wszystkie moje potrzeby związane z testowaniem, i nie miałem jeszcze wątpliwej przyjemności pisania testów dla GUI, więc nie jest dla mnie jasne, jak powinienem skonfigurować kod testujący i narzędzia dla EXE.
Moim pierwszym instynktem było po prostu dołączenie testów z kodem aplikacji, jednak wymagałoby to podania szeregu zależnych od testu zależności, których poinstruowano mnie, aby nie wysyłać do klienta. Nie jestem również w stanie wydobyć żadnej gotówki za specjalnie zaprojektowane narzędzie testowe, więc muszę użyć narzędzi, które mam pod ręką ( StoryQ , RhinoMocks i NUnit), co naprawdę powinno wystarczyć do przetestowania działania prostej aplikacji GUI. Z tego, co widzę, pozostawia mi to próbę znalezienia właściwej równowagi między utrzymaniem projektu naprawdę prostym lub celowym nadmiernym opracowaniem na potrzeby testów. Wygląda na to, że albo buduję aplikację z logiką biznesową w osobnej bibliotece i testuję bibliotekę, jak zwykle, albo znajduję jakiś inny mechanizm, który pozwala mi na wykonanie pliku bez rozbijania dodatkowych modułów, których projekt aplikacji nie ma naprawdę potrzebuję.
Edycja:
Należy pamiętać, że to pytanie dotyczy sposobu strukturyzowania relacji między NUnit a moim plikiem wykonywalnym - w przeciwieństwie do biblioteki DLL - a nie sposobu oddzielenia prezentacji i logiki biznesowej.
/Edytować
Więc moje pytanie brzmi:
- Czy istnieje konkretna / zalecana metoda konfiguracji prostej aplikacji GUI z testami jednostkowymi, która pozwala mi odpowiednio sprawdzić stan i zachowanie, używając dostępnych narzędzi i bez nadmiernej inżynierii?
- Czy przeoczyłem coś fundamentalnego w sposobie, w jaki NUnit powinien być wywoływany / konfigurowany podczas testowania EXE (w przeciwieństwie do DLL)?
- Czy możesz podać lub wskazać mi przykłady, jak to wszystko osiągnąć?
Zdaję sobie sprawę, że może to być więcej niż jeden sposób, dlatego szukam konkretnych wskazówek dotyczących implementacji w oparciu o twoje doświadczenia.
Odpowiedzi:
W jednym z moich komentarzy do odpowiedzi simoramana wspomniałem, że wymyśliłem kilka sposobów, aby to zrobić. Jedna z moich opcji była podobna do sugestii w odpowiedzi Jalayna, aby utworzyć duplikat projektu i wygenerować bibliotekę DLL, podczas gdy moim drugim pomysłem było po prostu połączenie z plikami w projekcie, w którym znajdował się kod, który chciałem przetestować. Chociaż obie opcje mogą sprawić, że zadziałają, są one mniej niż idealne.
W drugim przypadku miałbym do czynienia z bałaganem zależności jednostek, chyba że naprawdę mogłem rozdzielić architekturę w celu zminimalizowania zależności. Jest to dobre w przypadku mniejszych projektów, ale większe mogą z łatwością stać się prawdziwym bałaganem do zarządzania. Jednak moim największym oporem wobec tej opcji jest sama nieelegancja. Jasne, że mógłbymaby działało, ale robiąc to, muszę skutecznie przerwać enkapsulację, aby przetestować wewnętrzne elementy zestawu bezpośrednio przez źródło, zamiast testować za pośrednictwem publicznych interfejsów, co moim zdaniem jest dużym nie-nie. Podobnie posiadanie dodatkowego pliku projektu oznaczałoby albo duplikowanie wysiłków w dwóch projektach na raz, albo znalezienie sposobu na automatyczne dodanie ustawień pliku projektu do dwóch plików na raz, lub pamiętanie o kopiowaniu i zmianie nazwy pola projektu za każdym razem, gdy buduję. Może to być zautomatyzowane na serwerze kompilacji, ale zarządzanie IDE byłoby uciążliwe. Znowu może działać, ale w najlepszym wypadku jest to kludge, a gorzej, jeśli się pomylisz.
Wydaje się, że najlepszym sposobem jest zrobienie tego, co skomentowała nazwa mojego pytania, i po prostu włączenie EXE jako referencji w projekcie testowym. Okazuje się, że w tym przypadku EXE jest skutecznie traktowany tak samo jak DLL, i jestem w stanie uzyskać dostęp do wszystkich moich klas warstwowych , aby przetestować wszystko, co płynie moją łodzią.
źródło
Myślę, że:
Są to zasady, które lubię stosować, niezależnie od tego, czy jest to Java, czy C # (oczywiście, że nie ma problemu z Javą w Javie :-))
Jeśli chodzi o konfigurację środowiska testowego, wydaje mi się, że masz przynajmniej te dwie opcje:
Korzystanie z MSBuild
Utwórz klon pliku .proj (powiedz myproject-as-dll.proj ). Zmień
OutputType
sklonowany plik z „EXE
” na „Library
”. Za pomocą polecenia MSBuild możesz teraz utworzyć bibliotekę, którą możesz ustawić jako odniesienie w swoim projekcie zawierającą przypadki testowe NUnit.Wydaje mi się to możliwe, ale nigdy nie używałem go tak szczerze, więc nie jestem pewien. Ponadto możesz nie mieć MSBuild na serwerze testowym integracji i nie wiem, czy można go oddzielić od Visual Studio ...
Korzystanie z NAnt
Jeśli nie jesteś zaznajomiony z NAnt, będziesz musiał przejść do Google, jak skonfigurować z nim kompilacje projektu. Może sprawdź to , że jest trochę stary, ale autor skomentował pliki NANT Jeśli go znaleźć i wymowne (. Edit: badając jego akta bardziej szczegółowo, znaleźć swój plik konfiguracyjny niezwykle wielokrotnego użytku ). Robi także znacznie więcej niż tylko kompilację, ponieważ wykonuje przypadki testowe i uruchamia narzędzia do pokrywania kodu. Przyznaję, że nigdy nie korzystałem z NAnt, w przeciwieństwie do jego odpowiednika w Javie i ojca „Anta”, z którego często korzystałem, ale widzę, że to całkiem to samo i nie sądzę, że jest to trudne do nauczenia się.
Za pomocą tego narzędzia możesz wymyślić konfigurację, która pozwoli Ci:
Przy odrobinie więcej kodu możesz nawet:
Wszystko odbywa się bez zmiany czegokolwiek w plikach Visual Studio. I tak naprawdę nie wygląda mi to na nadmierną inżynierię, to tylko jeden plik. Może to potrwać jeden, może dwa dni, aby wszystko działało, ale moim zdaniem będziesz mieć dobrą konfigurację.
Na koniec dałbym klientowi wszystko, co niezbędne do zbudowania, przetestowania i uruchomienia projektów. Wydaje mi się, że pokazuje to twój profesjonalizm i fakt, że piszesz kod z myślą o jakości (co wydaje mi się, że robisz, ponieważ szukasz eleganckich rozwiązań)
źródło
Tylko dlatego, że projekt jest mały (początkowo), nie oznacza, że odpowiednia architektura jest nadmiernie inżynierska. Fakt, że chcesz pisać testy, świadczy o tym, że Twój projekt nie jest całkowicie trywialnym jednorazowym włamaniem.
Nie wspomniałeś, którego GUI-Framework używasz. WPF MVVM (Model-View-ViewModel) jest dobry i pozwala dość łatwo pisać testy dla całej logiki. Dzięki WinForms słyszałem dobre rzeczy o MVP (Model-View-Presenter)
źródło
Spójrz na moją odpowiedź na to pytanie: Jak skonfigurować MVP dla rozwiązania Winforms?
Napisałem przykładową aplikację, która pokazuje, w jaki sposób nakładam warstwy i jak testuję, mój GUI.
czytanie twojej edycji: użyj testera, który integruje się ze środowiskiem programistycznym. Używam ReSharper.
źródło
Napisałem Nunit WinForms kilka lat temu (chyba 6 lat). Jedną rzeczą, którą szczególnie pamiętam, jest to, że chociaż jest to jednostkowy przypadek testowy, działa on również jako przypadek końcowy. Czasami nie ma wiele do przetestowania na interfejsie (prosty formularz). Nawet jeśli próbujesz sprawdzić, czy po kliknięciu przycisku pojawia się okno komunikatu, nieumyślnie testujesz różne inne metody z innych warstw. Jest kilka rzeczy, których nie można również zautomatyzować. Wygląd, działanie i użyteczność nie mogą być zautomatyzowane przy użyciu zautomatyzowanych testów jednostkowych. Będziesz musiał uruchomić kilka testów ręcznych przed wydaniem.
źródło