piątek, 23 marca 2012

WrocNet - Team Foundation Server to nie SVN - Materiały

Przedwczoraj (środa 21.03) debiutowałem w roli "wykładowcy" na spotkaniu Wrocławskiej grupy .NET. Zaprezentowałem tam rozwinięcie moich wpisów związanych z połączeniem SCRUM z Team Foundation Server. 
Mnie jako prezentującemu na pewno podobało się zaangażowanie słuchaczy, za co serdecznie dziękuję. Nie wiem jak było w drugą stronę, jeżeli ktoś był i chce się podzielić swoimi wrażeniami (nawet najbardziej negatywnymi) to bardzo proszę o komentarze.
Obiecałem, że przedstawię materiały, z których dociekliwi mogliby się dowiedzieć więcej o przedstawianym przeze mnie temacie.
Jako pierwsze zareklamuje swoje wcześniejsze wpisy:
A teraz linki z których korzystałem:
Polecam również dwie świetne książki (dotyczą one co prawda TFS 2010, ale większość porad i opisów ma również zastosowanie w przypadku nowej wersji):
Miłej lektury!
   

niedziela, 11 marca 2012

Prism na WP7 - Silverlight Unit Test Framework / Mocking

W poprzednim poście przedstawiłem migrację Prisma na WP7. Dziś chciałbym przetestować zmigrowany kod za pomocą testów jednostkowych dołączonych do Prisma. Bardzo fajną sesje Jeffa Wicox'a nt testów jednostkowych na WP7 możemy znaleźć pod tym linkiem. Będziemy używać Silverlight Unit Test Framework i binarek dostępnych tutaj. Przede wszystkim musimy zmigrować projekty testów do projektów Windows Phone Application. Następnie dołączamy wspomniane binarki a code behind MainPage'a powinniśmy zmienić w ten sposób:
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;

}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
SystemTray.IsVisible = false;

var testPage = UnitTestSystem.CreateTestPage() as IMobileTestPage;
BackKeyPress += (x, xe) => xe.Cancel = testPage.NavigateBack();
(Application.Current.RootVisual as PhoneApplicationFrame).Content = testPage;
}

W powyższym kodzie nie dzieje się nic specjalnego. Po prostu ustawiamy stronę z poziomu której wykonujemy testy. Silverlightowa wersja testów Prisma używa Silverlight.Moq.dll. A więc, aby projekt się skompilował musimy dołączyć bibliotekę Silverlight.Moq.dll. Teraz możemy odpalić testy. Ekran powitalny wygląda w ten sposób:

Możemy odpalić wszystkie testy lub wpisać tag, który przefiltruje testy. Radzę nie uruchamiać testów w trybie debug, ponieważ jest to wyjątkowo irytujące jeżeli korzystamy z bibliotek silverlightowych, które nie wiadomo jak się zachowają (np. Silverlight.Moq.dll). Ani razu nie udało mi się dojść do końca testów, gdyż Visual wywalał się mniej więcej w połowie testowania (za chwilę poznamy tego przyczynę). Poradziłem sobie z tym uruchamiając testy bez debugowania CTRL+F5. No i wówczas otrzymałem następujący wynik:

84% testów przeszło. Wszystkie testy, które nie przeszły spowodowała biblioteka Moq, która też była odpowiedzialna za wywalanie się mojego visuala w trybie debug. Za pomocą Silverlight Unit Test Framework możemy normalnie podejrzeć szczegóły testu:

Generalnie na WP7 do tej pory nie można było korzystać z biliotek mockujących. Nie skorzystamy więc z RhinoMock lub Moq gdyż korzystają one z Reflection.Emit, który jest mocno okrojony w Mango (polecam ten topic). Jedynym rozwiązaniem jakie znalazłem jest biblioteka MoqaLate. Jest to "niby"-biblioteka pozwalająca tworzyć mocki pod Mango. Przede wszystkim MoqaLate nie jest żadnym frameworkiem tylko generatorem Mocków. Generuje klasy mocków na podstawie interfejsów projektu. Pakiet należy dodać do normalnego projektu, który będzie testowany czyli jest to w naszym przypadku Prism.Phone. Potem w zdarzeniach post build'a dodajemy linijke która odpala generator. Mocki wygenerują się w wyznaczonym folderze. Jednak jest to na tyle słabe rozwiązanie, że wywala się podczas generacji mocków prisma. Mówiąc szczerze to się zawiodłem :( Jedyne co mi zostało to stworzyć wszystko ręcznie (ale nie w tym odcinku;P). Projekt z testami dostępny jest tutaj - PRISM 4.1 / WP7.

sobota, 10 marca 2012

Prism 4.1 na Windows Phone

Zasadnicze pytanie: jaki jest sens używania Prism na Windows Phone? O zaletach prisma nie będę pisać. Jest ich wiele. Natomiast z mojego punktu widzenia sens przeniesienia Prisma na Phona jest zasadniczy: projekt wieloplatformowy oparty na Prismie - test jego wydajności, zalet i wad. Projekt jest tworzony na WP7, Silverlighta oraz WPF. Podchodząc do tematu od strony reużywania kodu i jego spójności sprawą kluczową staje się wspólny framework.

Przede wszystkim spotkałem się w necie z krytyką mówiącą, że prism na phona jest mega ciężki i lepiej korzystać z caliburn'a micro lub innych bibliotek. Ok, ok, ok... zacznijmy od początku.
Prism na phona tak naprawde nie istnieje - dlatego nie wiem skąd wzięły się opinie że jest za ciężki. W prismie na phone'a znajdziemy dosłownie 3 klasy na krzyż i brakuje tam wszystkiego dzięki czemu Prism jest używany przez wielu ludzi na świecie czyli brak IoC, modułów i regionów. Ughh... ciężki kawałek chleba. Postanowiłem zmigrować prisma silverlightowego na Phone'a. Ograniczyłem się do minimum czyli kompilowalność kodu i zachowanie elementarnej logiki.
Zaczynamy od głównego projektu. Prism.Silverlight. Przede wszystkim pozbywamy się wszelkich powiązań z kontrolką TabControl. Następnie docieramy do powiązania z klasą HashSet (której nie ma w wp7), czym się nie należy przejmować bo za chwile trzeba będzie przeorać całego ModuleManagera i HashSet będzie nie potrzebny. Zasadniczy problem przy migracji jest taki, że na WP7 nie możemy dynamicznie ładować assembly (zainteresowanych odsyłam tu i tu). Dochodzimy do funkcji LoadModuleTypes ModuleManager'a w której trzeba przyjąć że modułu nie zaciągamy z nikąd tylko on po prostu już jest. Wtedy po moich zmianach funkcja LoadModuleTypes wygląda tak:
private void LoadModuleTypes(IEnumerable moduleInfos)
{
if (moduleInfos == null)
{
return;
}

foreach (ModuleInfo moduleInfo in moduleInfos)
{
if (moduleInfo.State == ModuleState.NotStarted)
{
bool isUnavailable = Type.GetType(moduleInfo.ModuleType) == null;
if (isUnavailable)
{
throw new ModuleTypeLoadingException(string.Format
(Resources.FailedToGetType, moduleInfo.ModuleType));
}

moduleInfo.State = ModuleState.ReadyForInitialization;
}
}

this.LoadModulesThatAreReadyForLoad();
}

Jest to kluczowa zmiana w migracji. Jak widać zaciąganie modułu zamieniłem na rzucanie wyjątkiem jeżeli moduł jest niedostępny. Teraz całą resztę niepotrzebnego kodu związanego z ładowaniem modułów możemy spokojnie usunąć :) Nie będę dokładnie pisać co wywaliłem (dynamiczne ładowanie modułów i inicjalizacje modułu na żądanie). Projekt można ściągnąć i porównać kody z oryginalnym Prismem Silverlightowym.
Następnie możemy się zająć biblioteką Interactivity dla Prisma. Tutaj wystarczy wywalić wszystkie pliki powiązane z ChildWindow, który na WP7 nie jest używany (przynajmniej takie jest założenie:)
I to tak naprawdę wszystko. Dodatkowo jeżeli potrzebujemy zrobić testy jednostkowe powinniśmy zmigrować sobie Prism.Silverlight.TestSupport. Reszty bibliotek nie potrzebuję. Dodatkowo do tego zestawu wybrałem Ninject, który pomoże mi z DI. W następnym poście opisze testy jednostkowe dla WP7 na przykładzie Prisma. Cały projekt można ściągnąć pod tym linkiem

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Online Project management