Monday, 2 July 2007

Debugging NUnit tests in Visual Studio 2005 Express

VS2005 Express imposes many limitations on it's users as a trade-off for being free. It's main disadvantage IMHO is that it provides no support at all for unit tests. Fortunately there is a simple workaround for this. No, I am not talking about hacking VS to accept plugins as TestDriven.NET used to do. What I wanted to have was the ability to click "Debug" on a library project containing test and have it launched - inside the Visual Studio debugger.


This trick requires adding a tiny bit of magic code to the .csproj file:



<PropertyGroup>
<Nunit_Path Condition="'$(NUNIT_PATH)' == ''">C:\Program Files\NUnit</Nunit_Path>
<StartAction>Program</StartAction>
<StartProgram>$(NUNIT_PATH)\bin\nunit.exe</StartProgram>
<StartArguments>/run $(TargetFileName)</StartArguments>
<!--.csproj.user overwrites those values!-->
</PropertyGroup>

This should be pasted at the end of the project file, after <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> and just before </Project>


Save the changes and open the project in Visual Studio. You can now launch the tests by clicking "Debug->Start Without Debugging" and debug them with "Debug->Start Debugging". One caveat, though - this assumes that NUnit is installed in C:\Program Files\NUnit. If your instalation directory is different, you have to set the environment variable NUNIT_PATH accordingly.


On a side note, some MSBuild/VS2005 quirks:


  • StartProgram has to point to an absolute location (i.e. not to a program in PATH)

  • StartWorkingDirectory has to be unset (or it could point to $TargetDir, if only I could get it to resolve instead of returning "@(_OutputPathItem->'%(FullPath)')" literally)

  • all those properties can be set from Professional version - Express does not show edit boxes for most of them

Tuesday, 26 June 2007

Krótkie lekcje

Elektronika. Zasilacza 12V, 1000mA nie można zastąpić zasilaczem 12V, 1200mA mimo takich samych wtyczek. Próba kończy się głośnym pyknięciem i dymem unoszącym się z routera.


Marketing. Warto przyjmować reklamację produktu bez zbytniego wybrzydzania. Klient zapamięta miłą obsługę, a nie uszkodzony produkt i wróci po kolejne zakupy. Zwłaszcza, jeśli produkt został uszkodzony "tak nie do końca z winy sklepu".

Tuesday, 5 June 2007

hi5 - kolejny spammer

Po niedawnej historii z automatycznym rozsyłaniem zaproszeń przez Netlog, ta sama taktyka stosowana jest przez stronę hi5. Zachęcam do przeczytania przestróg Piotra Koniecznego odnośnie poprzedniego przypadku.


Jeśli dałeś/aś się złapać, koniecznie zmień hasło do GMail'a. A na przyszłość pamiętaj, że regulamin google (i większości innych serwisów) zabrania ujawniania hasła.

Monday, 19 March 2007

YaKuake dla Windows?

Pod linuxem bardzo szybko przyzwyczaiłem się do jednej prostej aplikacji: YaKuake. Genialne jest w niej to, że po naciśnięciu jednego przycisku (domyślnie F12) pojawia się schowana dotychczas konsola, po naciśnięciu go ponownie - chowa się. No i oczywiście możliwe jest uruchomienie kilku konsol w osobnych kartach. Teraz zmuszony jestem do korzystania z windows i cierpię ;-) Czy znane jest komuś podobne narzędzie dla tego "cudownego" systemu?


Update: znalazłem PoshConsole. Spełnia wymagania... teraz tylko czekam, aż pojawi się wersja, która nie pada po trzech poleceniach.

Sunday, 4 February 2007

Sane defaults

Tytuł można przetłumaczyć jako "rozsądna konfiguracja domyślna", ale to sformułowanie nie brzmi niestety tak dobrze jak angielski oryginał. O co chodzi? O to, że spora część programistów nie zdaje sobie sprawy jak ważne jest, by zaraz po instalacji oprogramowanie działało poprawnie i bezpiecznie. Spora część użytkowników nie będzie w ogóle zaglądać w rozbudowane opcje konfiguracyjne. A jeśli to nawet zrobi, to dopiero po dłuższym korzystaniu z programu. Dlatego ważne jest, aby świeżo zainstalowany software nie tworzył luk w bezpieczeństwie systemu. Przykłady zdecydowanie złych pomysłów domyślnej konfiguracji (głównie z projektów, w których uczestniczyłem, ale nie tylko):



  • użytkownik bazy danych: root, brak hasła

  • zapisywanie danych w / lub d:/ lub dowolnej innej absolutnej lokacji (za wyjątkiem /tmp albo %TMP%, zależnie od systemu)

  • kasowanie wszystkich danych z takiej lokacji (czyszczenie dysku twardego uszczęśliwia mało którego użytkownika)

  • zapis do /tmp albo %TMP% przez aplikację wieloplatformową

  • zakładanie, że aplikacja będzie uruchamiana z uprawnieniami administratora / roota

  • używanie / lub \ w zapisie ścieżek do podkatalogów

Rozsądne alternatywy:


  • użytkownik kojarzący się z nazwą programu, hasło najlepiej generowane losowo w trakcie instalacji

  • zapis w podkatalogu %APPDATA% lub ~ (nie dotyczy demonów / usług, zazwyczaj nie posiadających katalogu domowego)

  • kasowanie tylko plików utworzonych przez aplikację

  • korzystanie z File.createTempFile lub Path.GetTempFileName

  • zakładanie, że program zazwyczaj nie ma praw zapisu do katalogu, w którym jest zainstalowany

  • korzystanie z File.separator lub Path.DirectorySeparatorChar


Zdaję sobie sprawę, że nie ma szans, by użytkownicy windowsów przestali wykorzystywać konto administratora do normalnej pracy (próba częściowego wymuszenia tego przez Vistę jest chyba głównym źródłem problemów z uruchamianymi na niej programami). Ale programista powinien pamiętać, że usługi / demony uruchamiane są zazwyczaj z kont stworzonych dla nich osobnych użytkowników o okrojonych uprawnieniach. A jedynym elementem aplikacji, który próbuje cokolwiek zapisywać do jej katalogu instalacyjnego powinien być updater.


Jeszcze jedna ważna uwaga: pliki konfiguracyjne nie powinny być wersjonowane. Zamiast tego, do kontroli wersji najlepiej dodać plik z rozszerzeniem w rodzaju .example, zawierający przykładową konfigurację wraz z komentarzem, a właściwy plik konfiguracyjny oznaczyć jako ignorowany. W ten sposób programiści nie ryzykują przypadkowego wysłania do repozytorium swoich indywidualnych plików z ustawieniami. Oczywiście, przy takim podejściu aplikacja musi sobie radzić z brakiem pliku konfiguracyjnego - informując, że należy go stworzyć na podstawie przykładu lub robiąc to automagicznie. Fallback do wbudowanej konfiguracji jest często spotykanym złym pomysłem - użytkownik nie ma wtedy możliwości modyfikacji opcji, musi albo stworzyć konfigurację od zera albo zaakceptować ją w całości.

Thursday, 25 January 2007

Koniec monopolu?

Dobre wieści dla korzystających z Neostrady TP. Zgodnie z zawartą w zeszłym roku umową między TPSA a Netią, od 15 marca zasięg usługi Net24 (ADSL) ulegnie rozszerzeniu praktycznie na wszystkich aktualnie korzystających z Neostrady. Netia przygotowała specjalny cennik dla chętnych do zmiany dostawcy dostępu do internetu. Oferta jest bardzo atrakcyjna cenowo (125 złotych miesięcznie, brutto, za łącze 6Mbps/256kbps !) a co więcej, nie posiada limitu transferu. Jeśli choć raz TPSA przycięła Ci kurek do 4KBps - wiesz, jak to boli.


Cała sprawa jest o tyle bardziej interesująca, że TPSA została właśnie zmuszona do zmiany regulaminu świadczenia usługi Neostrada. A to oznacza (patrz § 33 p. 1,3 - pdf), że abonent może wypowiedzieć umowę, nawet zawartą na czas określony, bez płacenia molochowi odszkodowania. W takim wypadku należy zgłosić rozwiązanie umowy do 14 lutego, 15 lutego wejdzie ono w życie. Haczyk jest jeden - czy jesteś w stanie przeżyć miesiąc (15 lutego - 15 marca) bez sieci?


Korzystanie z Net24 nie oznacza rozwiązania umowy z TPSA o abonament telefoniczny, ale pozwala zmniejszyć go nawet do planu socjalnego. Jest też możliwość przeniesienia abonamentu do np. Tele2, o ile nie zmieni to parametrów technicznych łącza (czyli wg. Biura Obsługi Klienta Tele2 - będzie działać).


Nie, to nie jest artykuł sponsorowany. To tylko wynik wściekłości osobnika, którego łącze nagle nie pozwala czytać stron internetowych, jeśli nie wyłączy się w przeglądarce pobierania obrazków. A i wtedy jest kiepsko. Tak, przekroczyłem limit...

Saturday, 20 January 2007

Sprawdzanie wydajności

Często zdarza się sytuacja, gdy programista ma kilka pomysłów na zaimplementowanie jednej operacji. Albo do jednego problemu pasuje parę algorytmów, każdy ma swoje zalety i nie do końca wiadomo, który wybrać. Zazwyczaj pisze się wtedy kawałek kodu do szybkiego zmierzenia czasu wykonywania i zapomina o nim po wykorzystaniu. Celem zaoszczędzenia kilku minut następnym razem, wrzucam w sieć prostą klasę do porównywania wydajności.


Mały wyjaśnienie dla dociekliwych: klasa napisana jest tak, by pomiary nie uwzględniały czasu pierwszej kompilacji wykonywanych metod oraz czasu ładowania potrzebnych bibliotek do pamięci. Pomiar wykonywany jest za pomocą DateTime.UtcNow - ta metoda jest nieco szybsza od zwykłego Now, ponieważ nie musi uwzględniać stref czasowych. Ma też tą przewagę nad odwołaniami do API windows, że działa pod linuksem. A mniejszą nieco dokładność łatwo zniwelować odpowiednio zwiększając liczbę wykonań testu.


Przykład wykorzystania:


static void Main(string[] args)
{
PerformanceTestRunner ptr = new PerformanceTestRunner(100000); // liczba przebiegów do wykonania
ptr["Something Old"] = new TestMethod(TestSomething);
ptr["Something New"] = new TestMethod(TestOtherWay);
ptr.Run(1000); // parametr do przekazania metodzie testującej
}

private static void TestSomething(Object o)
{ // tutaj trafia kod do sprawdzenia
}

private static void TestOtherWay(Object o)
{ // tutaj trafia kod do sprawdzenia
}