Unit testing internal classes

While working on class libraries, it’s a common and a good practice to unit test it before publishing. If you think about making implementation of interfaces hidden from other assemblies you may mark the class as internal. Unfortunately, it will make testing more difficult. Luckily there’s a way to handle it. All we need to do is finding our class library a friend. Friend assemblies can access internal types of another assembly.

I’ll present two ways of making a friend for the assembly:

  1. Use attribute [assembly: InternalsVisibleTo("FriendAssemblyName")] on any of classes
  2. Add following section to csproj file
    <ItemGroup><AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"><_Parameter1>FriendAssemblyName</_Parameter1></AssemblyAttribute></ItemGroup>

Polityka prywatności

W niniejszej polityce prywatności znajdziesz informacje czy i w jaki sposób są przetwarzane Twoje dane osobowe oraz ciastka.

Dane osobowe

Twoje dane osobowe są zbierane w przypadku gdy pozostawisz komentarz pod artykułem. Dane te nie są przekazywane przeze mnie do firm trzecich.

Gdyby się to miało zmienić to powstanie na ten temat osobny post z informacją o tym.

Gdybyś Drogi Czytelniku zapragnął usunięcia swoich danych osobowych, daj proszę znać na adres bartosz.clapa@gmail.com. Usunę wszystko co powinienem.

Pliki cookies – ciasteczka

Ciasteczka to informacje tekstowe, które są zapisywane w Twojej przeglądarce. Pozwalają na zapisanie informacji o Twoich preferencjach i ewentualnie pomóc dostosować stronę do Twoich potrzeb.

Na tej witrynie ciastka zbierają następujące informacje:

  • Dane potrzebne do statystyk odwiedzin, między innymi o czasie ostatniej wizyty, czy odwiedzający był już wcześniej na tej witrynie, urządzeniu z jakiego się łączy, lokalizacji na podstawie adresu IP, itp.

Jeśli nie wyrażasz na to zgody, wyłącz proszę obsługę cookies w używanej przez siebie przeglądarce.

 

Google Analytics

W celu analizy statystyk strony jest zainstalowany skrypt Google Analytics.

Danych osobowych nie zbiera, a mi miło jest od czasu do czasu obejrzeć ładne wykresy z liczbą odwiedzających 😉

 

Moje obowiązki a Twoje prawa w związku z danymi osobowymi

Jeśli dodałeś jakiś komentarz to przekazałeś mi swoje dane osobowe. Moim obowiązkiem, w odpowiedzi na Twoją prośbę jest przesłanie Twoich osobistych, w szczególności tych dostarczonych przez Ciebie. Gdybyś zarządał usunięcia swoich danych to oczywiście to zrobię. Dane autora i jego komentarze zostaną pozbawione cech umożliwiających identyfikację osoby za nimi strojącej. Oczywiście jeśli jakieś dane będą mi potrzebne ze względów administracyjnych, prawnych lub bezpieczeństwa to je pozostawię.

 

Podziękowania

Dziękuję autorce bloga blog.anoriell.eu za inspirację i nieświadome wpłynięcie na mobilizację by usunąć obrazek „Closed due to GDPR”.

 

 

 

Zamiast wskaźnika – Office Remote

Jakiś czas temu prowadziłem warsztaty wprowadzające w tematykę testów jednostkowych.
W trakcie wstępnej prezentacji nie chciałem sztywno stać przy komputerze, a szybko sprawdzone ceny prezenterów(tak się fachowo nazywa w sklepie „pilot do slajdów”) spowodowały, że zacząłem się rozglądać za alternatywą.

Czytaj dalej Zamiast wskaźnika – Office Remote

Testy jednostkowe – czy warto?

Myślę, że każdy w mniejszym lub większym stopniu miał styczność z hasłem „testy jednostkowe”, „unit tests” (UT). Dla niektórych być może jest to strata czasu na niepotrzebne rzeczy. Moim zdaniem wykorzystanie testów jednostkowych w projekcie ma pozytywny wpływ na ostateczny rezultat. Oczywiście, zastosowanie testów jednostkowych ma swoje pozytywne i negatywne strony.

Bez dłuższych rozmyślań – wymagają poświęcenia czasu, którego często nam brakuje. Zazwyczaj gonią nas terminy, czy to dostarczenia całej funkcjonalności, czy po prostu sprintu. Napisanie testów wymaga czasu, bo to wciąż pisanie kodu, które wymaga choćby odrobiny zastanowienia.
Kolejną kwestią jest sama treść testów. Testy jednostkowe powinny sprawdzać jak najmniejszą logicznie powiązaną część funkcjonalności aplikacji jak np. wyliczenie sumy pozycji na fakturze. Czasami logika stojąca za funkcjonalnością jest na tyle skomplikowana, że jest ją trudno przetestować przy pomocy UT, zwłaszcza w projekcie, który istnieje od lat. Być może prościej będzie przetestować różne przypadki manualnie zamiast spędzać godziny na ewentualnej reorganizacji kodu.

Przejdźmy do pozytywnych stron. Gdy postanowimy sobie, że każda nowa funkcjonalność powinna zostać pokryta testami jednostkowymi będziemy pisali kod w taki sposób, aby był łatwo testowalny. Takie podejście umożliwi nam takie rozbicie funkcjonalności aby było możliwe łatwe przetestowanie najmniejszego jej fragmentu w jak najłatwiejszy sposób.
Pisanie testów jednostkowych do kodu, który należy do starych funkcjonalności tak naprawdę możemy pominąć. Dla ułatwienia można uznać stary, nietestowany kod za zewnętrzną bibliotekę i testować funkcje, z których korzystamy przy pisaniu nowych części aplikacji. Inną opcją jest pisanie testów w momencie otrzymania zgłoszenia o błędzie – by powtórzyć błędogenny scenariusz. Mamy w ten sposób część oprogramowania i tak zostanie pokryta testami, bo bądźmy szczerzy – która firma rozwijająca projekt od jakiegoś czasu jest w stanie przerwać jego rozwój na jakiś czas by pokryć testami całą aplikację?

W poprzednich akapitach pisałem, że testy jednostkowe wymagają poświęcenia dodatkowego czasu – jest to prawda. Zwróćmy jednak uwagę na to jak wygląda rozwój oprogramowania. Programiści kończą rozwój pewnej części aplikacji, następnie przekazują ją do testerów. Tester sprawdza co programiści wymyślili i ewentualnie zgłasza błędy. Części z nich, udałoby się uniknąć gdyby były stosowane testy jednostkowe. Tester zamiast sprawdzać po raz n-ty czy podstawowe scenariusze testów są spełnione mógłby po pierwszej weryfikacji sprawdzić inne opcje, które nie przyszły programiście do głowy. Można się także pokusić o pisanie testów do zgłoszonych błędów. Jeśli nasza poprawka zostanie zaakceptowana to nasz test jednostkowy będzie mógł w przyszłości służyć do sprawdzania, czy kolejne zmiany nie zaburzyły działania aplikacji. Wniosek z tego – oszczędzamy czas testerów, co skutkuje oszczędnością pieniędzy.

Krótko podsumowując – pomimo „przepalania” czasu na testy jednostkowe możemy ostatecznie go zyskać. Części błędów możemy uniknąć, a część znacznie szybciej naprawić i zadbać by więcej nie wróciły. Dzięki temu zaoszczędzimy czas naszego działu testów.
Kod, który nie został podczas pisania pokryty testami może zostać chociaż częściowo o nie uzupełniony – wystarczy zadbać o to by podczas naprawiania defektów napisać testy potwierdzające jego występowanie przed pracami nad poprawką. Tak więc nie taki diabeł straszny jak go malują. Moim zdaniem pomimo kosztów używania warto wykorzystywać testy jednostkowe.

It’s (almost) alive!

W piątkowym wpisie opisałem pokrótce bibliotekę JDOM Parser. Jak już wspomniałem wykorzystałem ją przy okazji przebudowy zbioru wzorców. Było to konieczne, ponieważ chciałem powiększyć zbiór wzorców, które wykorzystuję do korelacji. Po gruntownym rozszerzeniu i przebudowie zbioru danych uruchomiłem algorytm rozpoznawania znaków.

Dla niektórych paragonów możliwe było już zrozumienie zeskanowanej treści. Niestety nadal brakuje wzorców dla znaków interpunkcyjnych oraz rozpoznawania odstępów między wyrazami – będę nad tym pracował.

Mimo wszystko mogę powiedzieć: It’s (almost) alive!

Czytaj dalej It’s (almost) alive!

Prosty przepis na obsługę dokumentów XML – JDOM Parser

Przy okazji prac nad wzorcami do rozpoznawania znaków natworzyłem masę plików z obrazkami zawierającymi znaki. Nie chciałem wczytywać każdego pliku z osobna, więc postanowiłem utworzyć zbiór w pliku XML. Jako, że nie orientuję się zbyt dobrze w ekosystemie Javowym wyruszyłem na łowy – wujek Google był moim przewodnikiem. Podczas wędrówki w otchłaniach „internetów” natrafiłem na opis biblioteki JDOM. Zagłębiłem się w opis i przykłady – spełniała moje niewygórowane wymagania. Miała być zwyczajnie prosta w obsłudze.

Utworzenie nowego dokumentu XML sprowadza się do wywołania dwóch linijek, które tak naprawdę można było skrócić do jednej.

Element rootNode = new Element("rootNode");
Document doc = new Document(rootNode);

Dodawanie atrybutów odbywa się przy użyciu funkcji setAttribute(…):

Element node= new Element("node");

node.setAttribute("attributeName", "attributeValue");

Jeśli chcielibyśmy dodać jakąś zawartość do elementu wystarczy wywołać addContent(…).

node.addContent('zawartosc');

 

W analogiczny sposób dodajemy gotowy element do jego elementu nadrzędnego, czyli np..:

rootNode.addContent(node);

Zapis do pliku nie jest moim zdaniem skomplikowany. Wystarczy wywołać:

XMLOutputter xmlOutput = new XMLOutputter();

xmlOutput.setFormat(Format.getPrettyFormat()); // ustawiamy m. in. wcięcia w dokumencie na 2 spacje, kodowanie na UTF-8
xmlOutput.output(doc, new FileWriter("path\to\the\file.xml"));

 

Prawda, że proste?

Odczyt danych z pliku jest na podobnym poziomie trudności:

File inputFile = new File("file.xml");

SAXBuilder saxBuilder = new SAXBuilder();

Document document = saxBuilder.build(inputFile);

Zamiast pliku możemy także podać np. URL lub strumień danych.

Po otwarciu dokumentu pozostaje dobrać się do jego zawartości. Wystarczy pobrać „korzeń” (root) dokumentu przy pomocy funkcji getRootElement() wywoływanej na dokumencie.

W moim konkretnym przypadku dobrałem się do wszystkich potomków elementu nadrzędnego wywołaniem:

Element rootElement = document.getRootElement();
List<Element> children = rootElement.getChildren();

 

Następnie pobrałem atrybuty potomka przy pomocy funkcji getAttributeValue(final String attname), a zawartość getContent(final int index).

Przykładowe wykonanie:

String character = child.getAttributeValue("name");

String content = child.getContent(0).getValue();

 

 

Strona biblioteki: http://www.jdom.org/

 

PS. To jedna z tych sytuacji w których użycie słowa „potomek” w sformułowaniach jest bezpieczniejsze niż „dziecko” 😉

Rozpoznawanie znaków i częściowy sukces – współczynnik korelacji #2

Połowiczny sukces – program rozpoznaje znaki, ale jeszcze nie w 100% poprawnie.
Po kilku godzinach walki ze złośliwością rzeczy martwych (instalacja Linuxa obok Windowsa 10 przy aktywnym UEFI) udało mi się w końcu rozbudować kod o funkcję rozpoznawania znaków.

Czytaj dalej Rozpoznawanie znaków i częściowy sukces – współczynnik korelacji #2

Rozpoznawanie znaków – współczynnik korelacji #1

Ostatnie parę dni spędziłem na przygotowywaniu obrazków dużych liter oraz cyfr, które posłużą jako wzorzec przy rozpoznawaniu znaków wykrytych przy pomocy histogramu. Nie było to nic wartego dłuższego wspominania, ale dzięki temu mogę zacząć pisanie serca systemu.

Czytaj dalej Rozpoznawanie znaków – współczynnik korelacji #1