Mam test jednostkowy (nUnit). Wiele warstw w dół stosu wywołań metoda zakończy się niepowodzeniem, jeśli zostanie uruchomiona za pośrednictwem testu jednostkowego.
Idealnie byłoby użyć czegoś takiego jak mockowanie do skonfigurowania obiektu, od którego zależy ta metoda, ale jest to kod innej firmy i nie mogę tego zrobić bez dużego nakładu pracy.
Nie chcę konfigurować metod specyficznych dla nUnit - jest tu zbyt wiele poziomów i jest to kiepski sposób wykonywania testów jednostkowych.
Zamiast tego chciałbym dodać coś takiego głęboko w stosie wywołań
#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
{
// Do some setup to avoid error
}
#endif
Więc jakieś pomysły na to, jak napisać IsRunningInUnitTest?
PS Jestem w pełni świadomy, że to nie jest świetny projekt, ale myślę, że jest lepszy niż alternatywy.
c#
reflection
nunit
Ryan
źródło
źródło
Odpowiedzi:
Robiłem to już wcześniej - musiałem trzymać nos, kiedy to robiłem, ale zrobiłem to. Pragmatyzm za każdym razem bije dogmatyzm. Oczywiście, jeśli nie jest to sposób miły byłaby można go uniknąć, że byłoby świetnie.
Zasadniczo miałem klasę „UnitTestDetector”, która sprawdzała, czy zestaw struktury NUnit został załadowany do bieżącej domeny AppDomain. Wystarczyło to zrobić tylko raz, a następnie zapisać wynik w pamięci podręcznej. Brzydki, ale prosty i skuteczny.
źródło
AppDomain.GetAssemblies
i sprawdzę odpowiedni zestaw - w przypadku MSTest musisz sprawdzić, które zestawy są załadowane. Spójrz na odpowiedź Ryana na przykład.Biorąc pomysł Jona, oto co wymyśliłem -
Z tyłu, wszyscy jesteśmy na tyle duzi, chłopcy, żeby rozpoznać, kiedy robimy coś, czego prawdopodobnie nie powinniśmy;)
źródło
Na podstawie odpowiedzi Ryana. Ten jest przeznaczony dla platformy testów jednostkowych MS.
Powodem tego jest to, że pokazuję MessageBox przy błędach. Ale moje testy jednostkowe testują również kod obsługi błędów i nie chcę, aby MessageBox pojawiał się podczas uruchamiania testów jednostkowych.
A oto test jednostkowy:
źródło
Upraszczając rozwiązanie Ryana, możesz po prostu dodać następującą właściwość statyczną do dowolnej klasy:
źródło
Stosuję podobne podejście jak tallseth
Jest to podstawowy kod, który można łatwo zmodyfikować, aby uwzględnić buforowanie. Innym dobrym pomysłem byłoby dodanie metody ustawiającej
IsRunningInUnitTest
i wywołanieUnitTestDetector.IsRunningInUnitTest = false
głównego punktu wejścia projektu, aby uniknąć wykonywania kodu.źródło
Może przydatne, sprawdzając bieżącą nazwę procesu:
I tę funkcję należy również sprawdzić przez unittest:
Źródła:
Matthew Watson w http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/
źródło
|| processName.StartsWith("testhost") // testhost.x86
dla VS 2019W trybie testowym
Assembly.GetEntryAssembly()
wydaje się , że taknull
.Zauważ, że jeśli
Assembly.GetEntryAssembly()
taknull
,Assembly.GetExecutingAssembly()
nie jest.Dokumentacja mówi: the
GetEntryAssembly
metoda może powrócićnull
, gdy udało montaż został załadowany z niezarządzanych aplikacji.źródło
Gdzieś w testowanym projekcie:
Gdzieś w projekcie testów jednostkowych:
Elegancki, nie. Ale prosto i szybko.
AssemblyInitializer
dotyczy testu MS. Spodziewałbym się, że inne ramy testowe będą miały odpowiedniki.źródło
IsRunningInUnitTest
nie jest ustawiany na true w tych AppDomains.Używam tego tylko do pomijania logiki, która wyłącza wszystkie TraceAppender w log4net podczas uruchamiania, gdy nie jest podłączony debugger. Dzięki temu testy jednostkowe mogą logować się do okna wyników Resharper, nawet jeśli działają w trybie innym niż debugowanie.
Metoda używająca tej funkcji jest wywoływana podczas uruchamiania aplikacji lub podczas uruchamiania urządzenia testowego.
Jest podobny do postu Ryana, ale używa LINQ, odrzuca wymóg System.Reflection, nie buforuje wyniku i jest prywatny, aby zapobiec (przypadkowemu) nadużyciu.
źródło
Odniesienie do frameworka nunit nie oznacza, że test faktycznie działa. Na przykład w Unity, gdy aktywujesz testy w trybie odtwarzania, odniesienia nunit są dodawane do projektu. A kiedy uruchamiasz grę, odniesienia istnieją, więc UnitTestDetector nie działałby poprawnie.
Zamiast sprawdzać, czy nunit jest asemblowany, możemy poprosić nunit api o sprawdzenie, czy kod jest w trakcie wykonywania testu, czy nie.
Edytować:
Uważaj, jeśli jest to wymagane, kontekst testowy może zostać wygenerowany automatycznie .
źródło
Po prostu użyj tego:
W trybie testowym zwróci fałsz.
źródło
Niedawno byłem niezadowolony z tego problemu. Rozwiązałem to w nieco inny sposób. Po pierwsze, nie chciałem zakładać, że framework nunit nigdy nie zostanie załadowany poza środowiskiem testowym; Szczególnie martwiłem się, że programiści uruchamiają aplikację na swoich komputerach. Więc zamiast tego przeszedłem przez stos wywołań. Po drugie, byłem w stanie założyć, że kod testowy nigdy nie zostanie uruchomiony na plikach binarnych wydania, więc upewniłem się, że ten kod nie istnieje w systemie wydania.
źródło
działa jak marzenie
.
źródło
Testy jednostkowe pominą punkt wejścia aplikacji. Przynajmniej dla wpf, winforms i aplikacja konsolowa
main()
nie są wywoływane.Jeśli wywoływana jest metoda główna, to jesteśmy w czasie wykonywania , w przeciwnym razie jesteśmy w trybie testu jednostkowego :
źródło
Biorąc pod uwagę, że twój kod jest normalnie uruchamiany w głównym wątku (gui) aplikacji formularzy systemu Windows i chcesz, aby zachowywał się inaczej podczas uruchamiania w teście, możesz sprawdzić
Używam tego do kodu, który chcę
fire and forgot
w aplikacji GUI, ale w testach jednostkowych mogę potrzebować obliczonego wyniku dla potwierdzenia i nie chcę zadzierać z wieloma uruchomionymi wątkami.Działa dla MSTest. Zaletą jest to, że mój kod nie musi sprawdzać samej struktury testowej i jeśli naprawdę potrzebuję zachowania asynchronicznego w pewnym teście, mogę ustawić własny SynchronizationContext.
Należy pamiętać, że nie jest to niezawodna metoda
Determine if code is running as part of a unit test
zgodnie z żądaniem OP, ponieważ kod może działać wewnątrz wątku, ale w niektórych scenariuszach może to być dobre rozwiązanie (również: jeśli już pracuję z wątku w tle, może to nie być konieczne rozpocząć nowy).źródło
Application.Current ma wartość null, gdy działa w ramach testera jednostkowego. Przynajmniej dla mojej aplikacji WPF przy użyciu testera MS Unit. W razie potrzeby to łatwy test. Warto też pamiętać o używaniu Application.Current w kodzie.
źródło
Użyłem poniższego w VB w moim kodzie, aby sprawdzić, czy jesteśmy w teście jednostkowym. w szczególności nie chciałem, aby test otwierał Worda
źródło
Co powiesz na użycie refleksji i coś takiego:
var underTest = Assembly.GetCallingAssembly ()! = typeof (MainForm) .Assembly;
Zestaw wywołujący będzie tam, gdzie są twoje przypadki testowe i po prostu zastąp MainForm jakiś typ, który jest w testowanym kodzie.
źródło
Jest też naprawdę proste rozwiązanie, gdy testujesz klasę ...
Po prostu podaj klasę, dla której testujesz, taką właściwość:
Teraz twój test jednostkowy może ustawić wartość logiczną „thisIsUnitTest” na true, więc w kodzie, który chcesz pominąć, dodaj:
Jest to łatwiejsze i szybsze niż przeglądanie zespołów. Przypomina mi Ruby On Rails, w którym chciałbyś sprawdzić, czy jesteś w środowisku TEST.
źródło