Formatowanie kodu szybko i bezboleśnie

formatowanie kodu

Formatowanie kodu to jedna z podstawowych czynności jaką możemy zrobić w ramach refaktoryzacji. Jest proste i bezbolesne (pod warunkiem, że w Twoim języku programowania nie programuje się białymi znakami*). Daje szybki efekt w postaci czytelniejszego kodu a to jest bardzo ważne, zresztą pisałem już o tym tutaj.

Formatowanie kodu z automatu

Visual Studio posiada bardzo bogaty system dodatków a jednym z podstawowych to Productivity Power Tools a w nim dwa ustawienia, które nas interesują formatowanie kodu i usuwanie niepotrzebnych usingów. Instalacja jest banalnie prosta. W Tools -> Extensions and Updates szukamy power toolsów i instalujemy.

instalacja power tools

A potem ustawiamy dwie opcje, Tools -> Options -> Productivity Power Tools -> Power Commands

To wystarczy aby automatycznie formatować kod przy zapisywaniu pliku. Proste? Banalnie proste. Od teraz przed zapisem pliku Visual Studio automatycznie będzie formatować nasz kod i juz będziemy kroczek bliżej do trochę bardziej czytelnego kodu.

Jak formatować istniejący już kod

 

Co jeśli mamy już dużo kodu? Co jeśli chcemy sformatować wszystkie pliki w istniejącym – całkiem sporym projekcie? Nie trzeba otwierać każdego pliku w projekcie, wystarczy odpalić ReSharper-a czyli prawdopodobnie najlepsze narzędzie do refaktoryzacji. Później wystarczy mając wybrane na drzewku solution z menu wybrać ReSharper -> Edit -> Code Cleanup i patrzeć jak się samo robi 🙂 Preste? Banalnie proste. Tak posprzątany kod to dobry początek. Jeśli w zespole macie jakieś standardy kodowania, jeśli wąsy wrzucacie na koniec linii albo do nowej linii to te wszystkie rzeczy ustawisz w Resharper -> Settings -> ……. -> Code Style i oczywiście można ustawić różne ustawienia dla różnych języków.

resharper settings

 

*) programowanie białymi znakami to według mnie jeden z gorszych pomysłów bo konia z rzędem temu kto znajdzie błąd w programie jak mu kod wydrukujemy. Konia z rzędem temu kto szybko w najprostszym edytorze znajdzie spacje zamienione na tabulatory albo tabulatory na spacje. Czego nie widać nie powinno być elementem języka programowania i basta. Mamy dosyć problemów z domeną aby jeszcze dorzucać do pieca. Nie zmienia to faktu, że dobrze się tak programuje – nie trzeba tych cholernych nawiasów sadzać tyle, ale co z tego jak się gorzej utrzymuje.

Umarł GitLab niech żyje Git czyli co zrobić jak zepsuje się repozytorium Git-a

git sie zepsul co robic

Git to repozytorium kodu a repozytorium kodu to jedno z podstawowych narzędzi pracy programisty. Dzisiaj pół internetu pisze, że GitLab – serwis do hostowania repozytoriów git – zaliczył poważną wpadkę. Trudno, zdarza się ale jakie można z tego wyciągnąć wnioski?


Single Point Of Failure

Centralne repozytorium kodu ma tą wielką zaletę, że jest centralne. SVN-y, SourceSafe-y i inne tego typu repozytoria kodu mają wielką zaletę – jedno źródło prawdy. To też najsłabsza strona – bo jak padnie serwer to nie ma nic. Na komputerach programistów pozostanie wprawdzie kod źródłowy ale bez jakiejkolwiek historii. Na ten wypadek warto mieć zbudowany odpowiedni plan backupu a właściwie kilku backupów – w chmurze, w szafie ogniotrwałej, offsite. Warto by było od czasu do czasu sprawdzić czy z backupu da się cokolwiek odzyskać. Generalnie w sytuacji awarii serwera odgrzebujemy backup, przywracamy repozytorum i pracujemy dalej no chyba, że padł sprzęt a my nie mamy zapasu, wtedy zamawiamy nowy, przywracamy co trzeba i pracujemy dalej. Już po kilku godzinach lub dniach spokojnie sobie pracujemy. Czy nie da się tego jakoś usprawnić?

Git na ratunek!

Dzisiejsza awaria GitLaba przeraziła całkiem sporą część internetu. Nie ma się co dziwić, bo wyobraź sobie, że nagle nie masz dostępu do swojego repozytorium. Mi się taka akcja zdarzyła w najgorszym możliwym momencie – w czasie wdrożenia przy sporej presji czasowej. Nagle repozytorium git-owe padło a dokładniej padł vpn do serwera ileś tam kilometrów dalej. Dwie osoby pracują nad kodem – wiadomo, ostatnie poprawki – czas ucieka, zmęczenie doskwiera a tu co? mamy ręcznie kod mergować? Na szczęście git to rozproszone repozytorium kodu a nie jak wspomniane w pierwszym akapicie „centralne repozytoria”. Rozproszone repozytorium oznacz tyle, że masz lokalną kopię całego repozytorium na komputerze. To oznacz, że bardzo szybko możesz postawić inne repozytorium. W moim przypadku sprowadziło się to do założenia repozytorium na bitbuckecie (bo tam można za darmo hostować prywatne repozytorum) a potem wykonania dwóch komend:

[code]

    git remote add backup git@bitbucket.org:.../.....git

    git push backup master

[/code]

To spowodowało, że w chmurze pojawiła się pełna kopia repo i mogliśmy spokojnie pracować dalej. Cała operacja trwała może 5 minut razem z założeniem konta i wysłaniem danych.

Czy awaria gita to jakaś tragedia?

No właśnie, wracając do samej awarii gitlab-a (ale i innch, githuba, bitbucket-a i tych wszystkich tajnych firmowych „bezpiecznych” repozytoriów), jeśli tylko nasze repozytorium jest rozproszone to w 5 minut jesteśmy wstanie postawić kopię i pracować dalej. Taka awaria będzie dla nas mikro przeszkodą a nie tragedią blokującą pracę na godziny a czasem nawet na dni. To jest siła posiadania kopii repozytorium lokalnie…

… z małym zastrzeżeniem, jeśli regularnie commitujemy i regularnie pushujemy do zewnętrznego repozytorium.

Visual Studio 2015 i upgrade projektu za każdym razem

Visual Studio 2015 jest już od jakiegoś czasu. Instalacja, odpalenie projektu i do przodu. Coś tam się zaktualizowało w projekcie i mogę dalej pracować z nowymi zabawkami. Problem jaki mi się pojawił to w jednym solution ze sporą ilością projektów jeden z nich aktualizował się przy każdym otwarciu projektu.

Projekt, który chciał się aktualizować przy każdym otwarciu Visual Studio to MVC3, który później był migrowany do MVC4. Przy każdym otwarciu upgrade i kopia wszystkich plików i raport w html-u. Zanim na to zwróciłem uwagę, wrzuciłem całkiem sporo gnoju do repozytorium. Poszukując rozwiązania okazało się, że w trefnym pliku csproj wystarczy usunąć:

<FileUpgradeFlags>40</FileUpgradeFlags>
<UpgradeBackupLocation>Upgrade20</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>

Pozostało jeszcze wywalenie gnoju z repo i już można pracować jak człowiek.

SpecFlow + XUnit

Specflow fajny jest, piszemy scenariusze czytelne dla ludzi a pod spodem szaleje xunit i sprawdza. Jest tylko jedne problem, aktualnie specflow.xunit instaluje xunit 2.0 a do pliku .feature.cs generuje kod:

[csharp]
MyProjFeature : Xunit.IUseFixture
[/csharp]

No i klops, IUseFeature już nie jest dostępny w xunit 2. Można jednak sobie poradzić mieszając trochę w pakietach. Po prostu trzeba po instalacji specflow.xunit odinstalować wszystko związane z xunit 2.0 (use the –Force Luke) i zainstalować xunit 1.9.2 i wszystko śmiga. Poniżej zestaw magicznych zaklęć:

[powershell]
install-package -ProjectName "MyProj.Specs" specflow.xunit
uninstall-package -ProjectName "MyProj.Specs" xunit –Force
uninstall-package -ProjectName "MyProj.Specs" xunit.abstractions –Force
uninstall-package -ProjectName "MyProj.Specs" xunit.extensions –Force
uninstall-package -ProjectName "MyProj.Specs" xunit.assert –Force
uninstall-package -ProjectName "MyProj.Specs" xunit.core –Force
uninstall-package -ProjectName "MyProj.Specs" xunit.extensibility.core –Force
install-package -ProjectName "MyProj.Specs" xunit -Version "1.9.2"
install-package -ProjectName "MyProj.Specs" xunit.extensions -Version "1.9.2"
[/powershell]

Jeszcze słowo o TDD

O TDD napisano wiele, sam napisałem całkiem sporo i mówiłem całkiem sporo podczas kilku prelekcji. Używam TDD od ponad 5 lat już. Powinienem być super mega ninja pro TDD master. Mimo tego jakiś czas temu, pisząc bardzo prosty kod, na prawdę super prosty, naszła mnie taka refleksja:

Jest zielone, jest ok.

[csharp]
[Fact]
public void Example_test()
{
    _pinger.Ping().Returns(c =>
    {
        throw new Exception();
    });
    Assert.DoesNotThrow(()=>_monitor.CheckAvaliability());
    _destinationSystem.Received(1).Ping(Arg.Is<IDiagnostics>(diag => diag.State == ""));
}
[/csharp]

Powyższy kawałek kodu używa NSubstitute (.Ping().Returns(c=>…..) do mockownia. Oraz XUnit-a do testów. Napisałem test jak wyżej, napisałem kod. Niby wszystko zielone, niby ok. Jakimś cudem jednak pokusiło mnie, żeby dorzucić AutoData. AutoData to taki sprytny atrybut, który pozwala generować dane testowe. W moim przypadki Message z wyjątki ma znaczenie, dlatego stwierdziłem, że Message można spokojnie generować – tutaj kod jest taki, że mam pudełko, które jak zrobi coś złego to to złe ma wyjść z drugiej strony – case dla AutoData jak malowany.

[csharp]
[Theory,AutoData]
public void Example_test(string exceptionMessage)
{
    _pinger.Ping().Returns(c =>
    {
        throw new Exception(exceptionMessage);
    });<
    Assert.DoesNotThrow(()=>_monitor.CheckAvaliability());
    _destinationSystem.Received(1).Ping(Arg.Is<IDiagnostics>(diag => diag.State == exceptionMessage));
}
[/csharp]

No i zonk!!! Test już nie bardzo to przechodzi. Pomyślałem, bez jaj, przecież implementacja jest tak prosta, że tego nie da się zepsuć – nawet nie wiem po co pisałem na to test, ale nie uprzedzajmy faktów…. Debug testu i….. okazało się, że jednak w kodzie gdzie łapię wyjątek, to oprócz logowania tak jak to powinno być to już message-a  nie przepisuję. Kto by pomyślał.

Testy jednostkowe nie dają 100% gwarancji, że powstanie kod bez bugów, nie dają nawet jakiejkolwiek gwarancji, co jednak dają, to dużo wyższą szansę, że powstały kod będzie miał mniej bugów niż bez testów. W moim przypadku, okazało się, ze prosta refaktoryzacja – lub bez AutoData dodanie kilku przypadków testowych, pozwoliła złapać buga zanim kod poszedł na produkcję.

100 dni kodowania

Założenia:

codziennie przez 100 dni będę pisał kawałek kodu

kod musi zostać opublikowany na GitHub-ie

zmiana musi mieć jakąś wartość – nie liczy się commit  z samymi zmianami nazw

wszędzie gdzie to możliwe, nowy kod powinien wprowadzać zmianę w interfejsie użytkownika (bądź api)

kod pisany w pracy się nie liczy (nie leci do GitHuba)

minimum 30 minut kodowania

Historia:

Jakiś czas temu dostałem link do bloga John-a Resig-a – tego który jest ojciem jQuery gdzie opisuje swoje 180 dni z pisaniem kodu – CODZIENNIE. Zainspirowała go Jennifer Dewalt,  która w ramach nauki postanowiła przez 180 dni tworzyć strony www. Stwierdziłem, że dlaczego by samemu nie spróbować. No i tak postanowiłem codziennie kodować. Do podobnego projektu podchodziłem ale w fotografii – 365 zdjęć, codziennie minimum jedno zdjęcie. Niestety nie udało się wytrwać, dlatego do obecnego projektu zmieniłem założenia, 100 dni (a jak się uda przeżyć 100 to 180) – tyle musi się udać. Na dzień dzisiejszy jestem na dniu 14-stym, jest ok, jest moc, trzeba pomyśleć co się napisze, trzeba to dobrze zaplanować bo w ciągu tygodnia jakoś łatwiej idzie ale  weekend muszę dobrze zaplanować kiedy i co napiszę aby spełnić wymagania.

Trzymajcie kciuki, aby się udało.

 

Aktualizacja:

  • Verbalizer – zamiana liczby całkowitej na słownie (aktualnie wspiera wartości do milionów), C#
  • FizzBuzz – przykładowa aplikacja webowa z odseparowanymi warstwami, ASP.NET MVC5 + AngularJS + Autofac + WebApi2
  • BreakOut – pierwsze eksperymenty z Unity w celu zbudowania klasyka – Breakout – teraz wiem, że powstanie z tego coś zupełnie innego, Unity + X
  • Mono – eksperymenty z mono, czyli czy to w ogóle działa, czy działa na tym Nancy i pewnie jeszcze kilka innych rzeczy, do tej pory Mono, Nancy
  • X – Eksperymenty z czymś o czym za bardzo jeszcze nie mogę mówić (NDA) ale mam nadzieję, że niedługo będę mógł udostępnić filmik, repo już jest na githubie ale ciągle jeszcze mocno prywatne.

 

foto: Rodrigo Denúbila

Debuggowanie – Make Object ID

Czasem zwykłe metody debugowania nie wystarczają, czasem watch-e i sprawdzanie krok po kroku jest nie wystarczające. Czasem chciało by się sprawdzić wartość obiektu, do którego nie mamy referencji. No właśnie, wszystkie normalne narzędzia debuggowania jakie udostęnia Visual Studio pozwalają na oglądanie wszystkiego co mamy w zasięgu referencji albo gdzieś po callstack-u możemy się do “tego” dorwać. Co jednak jeśli i to za mało? Na pomoc Make Object ID. Zatrzymując program w momencie gdy mamy dostęp do rzeczonego obiektu (new NaszPodgladanyObject ??) wystarczy utworzyć sobie referencję 🙂

vsObjectId

Po dodaniu watch-a wystarczy z menu context-owego wybrać Make Object ID, co powoduje dodanie numerka do obiektu – takiego 1# (kolejna będzie 2#, 3# etc). Teraz możemy w watch-u oglądać obiekt 1#, co więcej przez całe życie programu ten obiekt będzie dostępny przez 1#, co więcej 1# możemy używać również w moim ulubionym immediate window Uśmiech

Debugowanie w Visual Studio

Ostatnio widzę dużo wpisów na temat debugowania aplikacji. Nie trafiłem jednak na opis dwóch rzeczy, które bardzo tą czynność ułatwiają, mianowicie, zmiana kolejności wykonywania kodu oraz GetHashCode()

Zmiana kolejności wykonywania kodu

Czy zdarzyło Ci się podczas debugowania przejechać o tą jedną linijkę za daleko? Nic prostszego, chwyć żółtą strzałkę i przesuń kilka linijek do tyłu i wykonaj kod jeszcze raz. To jest tak proste, że aż niebywałe, że niektórzy o tym nie wiedzą. Teraz już wiecie.

vsdebugger.gif

Możemy przesuwać się na początek i na koniec funkcji, do przodu i do tyłu. Krok dalej to w przypadku wyjątku, który zatrzymał nam program, możemy przenieść się na koniec funkcji, wyjść z niej, cofnąć się linijkę do góry (w kawałku kodu, który tą funkcję wywołał) i wywołać jeszcze raz, próbując zrozumieć dlaczego program “się sypnął”. Dzięki czemu nie trzeba restartować aplikacji i przeklikiwać się. Rozwinięciem tego jest możliwość edycji kodu w trakcie debugowania. Szczęśliwcy z VS2008 (bodajże) na maszynach 32bit mogą to robić od dawna. Jeśli używacie x64 to dopiero VS2013 pozwala modyfikować kod w locie. Świetna sprawa, oszczędza sporo czasu (chociaż ma swoje ograniczenia).

GetHashCode()

GetHashCode to funkcja, któraz zwraca nam unikalny (teoretycznie) identyfikator obiektu. Do czego to może być przydatne przy debugowaniu? Ano czasem jest tak, że kod robi coś dziwnego i za bardzo nie wiadomo dlaczego, bo niby jest ok ale działa dziwacznie. I jak już wszystko zawiedzie, to okazuje się, że warto sprawdzać Hash obiektów, bo może się okazać, że w jednej części aplikacji mamy jeden obiekt a w innej części drugi obiekt mimo tego, że myślimy, że to ten sam. Sam więcej niż raz wpadłem w taką pułapkę, że myślałem, że mam do czynienia z  jakimś obiektem danej klasy, a okazywało się, że gdzieś po drodze się podpinała inna instancja i tak naprawdę miałem te same dane ale inne referencje wewnątrz i koniec końców program działał trochę inaczej. Mi najwygodniej użyć do tego Immediate Window (ALT+CTRL+I) i po prostu klepię ?  nazwaZmiennej.GetHashCode(). Proste jak budowa cepa a bardzo skuteczne, zadziwiająco skuteczne.

Dając Ci te dwa (nowe) narzędzia, życzę owocnych łowów.

NSubstitute czyli lepsza wersja Moq

NSubstitute to (dla tych co nie znają jeszcze) taki Moq na sterydach. Sytuacja wygląda tak, mamy klasę, która potrzebuje jakiś zależności, mniej więcej tak:

[csharp]
public class SomeClass
{
public SomeClass(INeedSomeStuff stuff)
{
// …….
}
}

public interface INeedSomeStuff
{
string DoSomeStuff(string param);
void DoSomeOtherStuff();
}
[/csharp]

Możemy użyć moq i napisać:
[csharp]
var moq = new Mock<INeedSomeStuff>();
moq.Setup(m => m.DoSomeStuff("Hello")).Returns(r => "World");

INeedSomeStuff someStuff = moq.Object;
var someObj = new SomeClass(someStuff);
[/csharp]

lub za pomocą NSubstitue napisać dokładnie to samo tak:
[csharp]
var someStuff = Substitute.For<INeedSomeStuff>();
someStuff.DoSomeStuff("Hello").Returns("World");

var someObj = new SomeClass(someStuff);
[/csharp]

poza tym, że pozbywamy się lambd, to jeszcze nie mamy dodatkowego .Object o którym trzeba pamiętać, ot mamy zamiennik naszej klasy. Ale to nie wszystko, jest jeszcze lepiej, NSubstitute działa od razu, więc nie trzeba robić setupów w miejscach, gdzie czasem moq tego wymaga ale najlepsze to kwiatek na jaki się nadziałem przy przechodzeniu z Moq na NSubstitute. Jest kawałek kodu, który zwraca kolorki z zadanej palety, po kolej – ColorGenerator. Metoda GetColor() zwraca kolor z tablicy. Za każdym wywołaniem bierze następny kolor. Tyle teorii. Sytuacja taka, że trzeba to zamockować:

[csharp]
_mockColorGenerator.Setup(x => x.GetColor()).Returns(_colors[0])
     .Callback(() => _mockColorGenerator.Setup(x => x.GetColor()).Returns(_colors[1])
     .Callback(() => _mockColorGenerator.Setup(x => x.GetColor()).Returns(_colors[2])
     .Callback(() => _mockColorGenerator.Setup(x => x.GetColor()).Returns(_colors[3]))));
[/csharp]

Może, za pomocą moq można to napisać lepiej no ale jest (było) i działało. W NSubstitute można to zapisać tak:
[csharp]
_colorGenerator.GetColor().Returns(_colors[0], _colors[1], _colors[2], _colors[3]);
[/csharp]

Efekt ten sam tylko 6 lambd mniej, 3 callbacki mniej, ogólniej wielokronie czytelniej.

P.S. NSubstitute jest na nugecie więc instalacja jest bezproblemowa, dodatkowo można używać równolegle z moq i małymi kroczkami wycinać tego ostatniego.