Czy ktoś robi „prawdziwe” TDD z Visual-C ++, a jeśli tak, jak to robi? [Zamknięte]


10

Rozwój oparty na testach oznacza napisanie testu przed kodem i wykonanie określonego cyklu :

  • Napisz test
  • Sprawdź test (uruchom)
  • Napisz kod produkcji
  • Sprawdź test (uruchom)
  • Wyczyść kod produkcji
  • Sprawdź test (uruchom)

Moim zdaniem jest to możliwe tylko wtedy, gdy twoje rozwiązanie programistyczne pozwala bardzo szybko przełączać się między kodem produkcyjnym i testowym oraz bardzo szybko wykonywać test dla określonej części kodu produkcyjnego.

Teraz, mimo że istnieje wiele frameworków do testowania jednostek dla C ++ (używam bankomatu Bost.Test.), Wydaje się, że tak naprawdę nie istnieje żadne przyzwoite (dla natywnego C ++ ) rozwiązanie Visual Studio (Plugin), które tworzy TDD cykl znośny bez względu na zastosowane ramy.

„Znośny” oznacza, że ​​uruchamianie testu określonego pliku cpp odbywa się jednym kliknięciem bez konieczności ręcznego konfigurowania osobnego projektu testowego itp. „Znośny” oznacza również, że rozpoczyna się prosty test (łączenie!) I działa bardzo szybko .

Jakie narzędzia (wtyczki) i techniki są dostępne, dzięki czemu cykl TDD jest możliwy do tworzenia natywnego C ++ w Visual Studio?

Uwaga: Nie mam nic przeciwko darmowym lub „komercyjnym” narzędziom.

Proszę : Brak zaleceń ramowych. (Chyba że framework ma dedykowaną wtyczkę Visual Studio i chcesz ją polecić).


Edytuj notatkę : Dotychczasowe odpowiedzi zawierały łącza do sposobu zintegrowania frameworku testów jednostkowych z Visual Studio. Zasoby mniej więcej opisują sposób, w jaki środowisko UT kompiluje się i uruchamia pierwsze testy. Nie o to chodzi w tym pytaniu. Jestem zdania, że ​​aby naprawdę produktywnie pracować, mając Testy Jednostkowe w ręcznie utrzymywanym (!) Oddzielnym vcproj od twoich klas produkcyjnych dodasz tak dużo narzutu, że TDD „nie jest możliwe”. O ile mi wiadomo, nie dodajesz dodatkowych „projektów” do rzeczy Java lub C #, aby włączyć Testy Jednostkowe i TDD, i to nie bez powodu. To powinno być możliwe z C ++ przy odpowiednich narzędziach, ale wydaje się (chodzi o to pytanie), że jest bardzo mało narzędzi dla TDD / C ++ / VS.


Googlując się, znalazłem jedno narzędzie, VisualAssert , które wydaje się zmierzać we właściwym kierunku. Jednak afaiks nie wydaje się być w powszechnym użyciu (w porównaniu do CppUnit, Boost.Test itp.).


Edycja: Chciałbym dodać komentarz do kontekstu tego pytania. Myślę, że to dobre podsumowanie zarysowania (części) problemu: (komentarz Billy ONeal )

Program Visual Studio nie używa „skryptów kompilacji”, które użytkownik może w rozsądny sposób edytować. Jeden projekt tworzy jeden plik binarny. Co więcej, Java ma właściwość, że Java nigdy nie buduje pełnego pliku binarnego - plik binarny, który budujesz, jest tylko ZIP-em plików klas. Dlatego możliwe jest ręczne kompilowanie, a następnie JAR razem ręcznie (używając np. 7z). Zarówno C ++, jak i C # faktycznie łączą ich pliki binarne, więc ogólnie mówiąc, nie można napisać takiego skryptu. Najbliższe, co możesz uzyskać, to skompilować wszystko osobno, a następnie wykonać dwa połączenia (jedno dla produkcji, jedno dla testowania).


2
As far as I am aware, you do not add extra "projects" to a Java or C# thing to enable Unit Tests and TDD,<- Nie sądzę, żeby to było poprawne. Zwykle masz również wiele projektów w języku C #; nie chcesz wysyłać kodu testowego w produkcyjnym pliku binarnym.
Billy ONeal

2
Nigdy nie widziałem tego obsługiwanego przez framework. Generowanie pliku binarnego wymaga projektu. Chcesz dwa pliki binarne; jeden z kodem testowym i jeden z kodem produkcyjnym. Potrzebujesz zatem dwóch projektów. Nie można tego obejść.
Billy ONeal,

1
@BillyONeal, we wszystkich projektach oprócz Javy (oprócz jednego), projekt zawiera główne i testowe źródło - skrypt kompilacji wybiera następnie elementy do umieszczenia w artefaktach, które można rozmieścić.
Robert Mark Bram

2
@Robert: Visual Studio nie używa „skryptów kompilacji”, które użytkownik może w rozsądny sposób edytować. Jeden projekt tworzy jeden plik binarny. Co więcej, Java ma właściwość, że Java nigdy nie buduje pełnego pliku binarnego - plik binarny, który budujesz, jest tylko ZIP-em plików klas. Dlatego możliwe jest skompilowanie osobno, a następnie JAR razem ręcznie (przy użyciu np 7z.). Zarówno C ++, jak i C # faktycznie łączą ich pliki binarne, więc ogólnie mówiąc, nie można napisać takiego skryptu. Najbliższe, co możesz uzyskać, to skompilować wszystko osobno, a następnie wykonać dwa połączenia (jedno dla produkcji, jedno dla testowania).
Billy ONeal,

4
Poważnie? „Wskazówka: każdy test powinien zawierać jedną główną funkcję i generować jeden plik wykonywalny.” Brzmi to absurdalnie wolno dla każdej rozsądnej liczby testów. Nawet jeśli oznaczają tylko jedno urządzenie testowe na plik wykonywalny, to nadal głupia rada IMO. Spróbuj zrobić to z tysiącami testów (dla średniego projektu) lub setkami tysięcy testów (dla dużego projektu), a na pewno oszalejesz.
zalegalizować

Odpowiedzi:


4

Napisałem 5-częściową serię blogów na temat robienia TDD z C ++ i Visual Studio: część 1 , część 2 , część 3 , część 4 , część 5 .

Nie jestem pewien, dlaczego mówisz, że nie tworzysz dodatkowych projektów w języku C #, aby robić TDD, ponieważ zawsze tak robiłem z NUnit i wydaje się to typowe dla tego, co inni ludzie robią również z NUnit. Powód jest prosty: zawsze trzymaj kod testowy oddzielnie od kodu produkcyjnego. W przypadku C ++ z Visual Studio oznacza to oddzielne projekty, podobnie jak w przypadku C # i NUnit. Z tego, co wiem o świecie Java, jest to również powszechne.

Oczywiście każdy ma inne wyobrażenia na temat tego, co jest „do zniesienia” przy robieniu TDD. Ćwiczę metodę opisaną w moim blogu od wielu lat i uważam ją za bardzo znośną. C ++ jest językiem kompilowanym, a kompilacja może być powolna, gdy testowany system jest silnie sprzężony. Po prostu nie da się od tego uciec bez zmiany na bardziej luźny projekt.

Moje „działanie jednym kliknięciem” to „Kompiluj rozwiązanie”. Jeśli to za dużo buduje, zawsze możesz zwolnić nieistotne projekty podczas pracy, a następnie Build Solution zbuduje tylko minimalny podzbiór projektów, które należy zaktualizować w wyniku wprowadzonych zmian.

To prawda, że ​​czas kompilacji C ++ w czasie kompilacji sprawia, że ​​zajmuje to trochę więcej czasu w każdym cyklu procesu TDD niż w przypadku NUnit i C #, ale pewność, którą czerpię z dobrze przetestowanego kodu C ++ jest tego warta. W przeciwnym razie spędzę dużo więcej czasu w debuggerze. Zachowam ostrożność, aby oszczędzić na używaniu gmocka, ponieważ może to znacznie wydłużyć czas testowania kompilacji. Do tej pory głównie uciekałem od lekkich „fałszywych” obiektów i rzadko potrzebuję pełnej funkcjonalności makiet. Frameworki frameworków dla C ++ są w dużej mierze oparte na szablonach, co może znacznie wydłużyć czas kompilacji, więc powinny być zarezerwowane tam, gdzie naprawdę potrzebujesz makiety, a fałszywy po prostu tego nie zrobi.

Zastanawiałem się nad stworzeniem kreatora projektu testu jednostkowego Boost.Test, aby zautomatyzować część projektu tworzenia kodu testowego dla kodu produkcyjnego, ale po kilkukrotnym wykonaniu naprawdę nie jest to takie trudne ręcznie.

Jeśli chodzi o rozwiązania z wieloma (150?) Projektami, istnieją również sposoby radzenia sobie z tym. Jednym z oczywistych jest znalezienie grup powiązanych projektów i zebranie ich w całość oraz rozpoczęcie ich konsumpcji / publikowania jako całości. Jeśli naprawdę potrzebujesz przebudować / dotknąć wszystkich 150 projektów w celu wprowadzenia drobnych zmian, które wprowadzasz podczas cyklu TDD, to i tak kod jest tak bardzo sprzężony, że testy jednostkowe raczej nie będą miały większego znaczenia.

Patrząc na link NetBeans IDE, znajdę eye candy posiadania czegoś, analizuje wyjścia testowego i pokazuje mały test wiersz w oknie z zielonym lub czerwonym symbolem obok niej coś, co mi minie które pochodzą z NUnit, ale tak naprawdę nie przegapiłem. Uważam, że bardziej przydatne jest po prostu niepowodzenie kompilacji, a następnie mogłem kliknąć dwukrotnie w oknie błędów, aby umieścić kursor w miejscu nieudanego potwierdzenia.


„... nie jestem pewien, dlaczego mówisz, że nie tworzysz dodatkowych projektów w języku C # ... Z tego, co wiem o świecie Java, jest to również tam często spotykane ...” Mogłem się pomylić z mojej strony. (Przynajmniej dla .NET, ponieważ potrzebujesz pliku wykonywalnego dla .NET - dla java potrzebujesz tylko plików klas, więc nie bardzo wiem, gdzie zmieściłby się dodatkowy projekt.)
Martin Ba

Nie jestem pewien, jak Java współpracuje z projektami; Mam tam ograniczone doświadczenie. Z tego, co niewiele wiem, rozumiem projekty jako artefakt IDE, a nie język. (Ściśle mówiąc, dotyczy to również C #, ale nie znam nikogo, kto używa kompilatora wiersza poleceń do niczego innego niż krótkie artykuły na blogu lub demonstracje.) Jednak nawet w Javie zdecydowanie trzymasz kod testowy oddzielnie od kod produkcyjny, który robią dla Ciebie osobne projekty. Nigdy nie polecam warunkowego kompilowania C ++ w celu oddzielenia kodu produkcyjnego i testowego.
zalegalizować

1
„zachowaj kod testowy oddzielnie od kodu produkcyjnego, co robią dla Ciebie osobne projekty” - aha! Cóż, niezupełnie, IMHO. Oddzielny „projekt” jest koniecznością dla C ++ i .NET, ponieważ oba muszą stworzyć plik wykonywalny, aby cokolwiek uruchomić, i aby utworzyć (jeden) plik wykonywalny, potrzebujesz (jednego) projektu. Nie przeszkadza mi trzymanie kodu testowego oddzielnie (lub nie) od kodu produkcyjnego, ale muszę dodać (redundantny) „projekt”, aby wygenerować testowy plik wykonywalny irytujący. :-)
Martin Ba

1
Potrzebujesz dwóch wbudowanych produktów: kodu produkcyjnego (biblioteka statyczna, biblioteka współdzielona, ​​plik wykonywalny itp.) Oraz plik testowy. W Visual Studio każdy zbudowany produkt odpowiada projektowi, więc potrzebujesz dwóch projektów. To naprawdę nie jest bardziej skomplikowane. Projekt testu jednostkowego NIE jest zbędny.
zalegalizować

2

Nie używam Visual-C ++, ale wykonuję TDD z C ++, używając googletest i googlemock, z QtCreator jako moim IDE. Wiele lat temu miałem podobną konfigurację z Visual-C ++, ale używając innej struktury testów jednostkowych.

Za użyteczne uznałem podzielenie projektu na kilka podprojektów.

  1. Biblioteka statyczna lub dynamiczna, która zawiera 99% rzeczywistego kodu źródłowego projektu.
  2. Projekt składający się głównie z metody main () do uruchomienia normalnego programu.
  3. Projekt testowy, który zawiera main () do uruchomienia mojego środowiska testowego i wiele plików zawierających testy i obiekty próbne.

Dzięki tej konfiguracji moje IDE zajmuje się dodawaniem plików do różnych projektów, a jeśli zależności są poprawnie określone, mogę uruchomić wszystkie moje testy jednostkowe z częściową przebudową. Mam nawet tę konfigurację, aby uruchamiała wszystkie moje testy natychmiast po skompilowaniu. Jenkins, CI, którego obecnie używam, również działa i zapewnia wyniki testów oraz dane dotyczące zasięgu.

Możliwe jest dodanie niestandardowego programu uruchamiającego do IDE dla pliku, aby uruchomić testy jednostkowe dla pliku Foo.cpp, jeśli zdarzyło Ci się nazwać wszystkie testy jednostkowe dla Foo w urządzeniu testowym TestFoo. Jak skonfigurować to dokładnie dla Visual-C ++ Nie jestem pewien, ale myślę, że to możliwe.


Przydatne informacje, choć posunę się tak daleko, że nazwałbym to „powszechną radą” :-) ... również nie jest to wykonalne w przypadku naszych starszych materiałów, ale dodanie testów do starszych rzeczy jest i tak bolesne ( i chciałbym w najmniejszym stopniu ułatwić dodawanie zestawu testowego).
Martin Ba

2

Używam MSTest do testowania natywnego kodu C ++.
Oto świetny post na blogu na ten temat: http://blogs.msdn.com/b/jsocha/archive/2010/11/19/writing-unit-tests-in-visual-studio-for-native-c. aspx

Tak, będą co najmniej dwa projekty - jeden dla samej aplikacji, drugi dla testów.
Zamiast tworzyć trzeci projekt ze statyczną biblioteką, po prostu dodaję źródło aplikacji do testowania projektu, więc rozwiązanie wygląda następująco:

[-] Solution 'Foo'      Foo\Foo.sln
 |-[-] Foo              Foo\Foo\Foo.vcproj
 |  |-[-] include
 |  |  |- foo.h         Foo\Foo\foo.h
 |  |  |- bar.h         Foo\Foo\bar.h
 |  |
 |  |-[-] source
 |     |- foo.cpp       Foo\Foo\foo.cpp
 |
 |-[-] Foo.Tests        Foo\Foo.Tests\Foo.Tests.vcproj
    |                        (Additional include directory: "..\Foo")
    |-[-] include
    |  |- FakeBar.h     Foo\Foo.Tests\FakeBar.h
    |
    |-[-] source
       |-[-] app
       |  |- foo.cpp    Foo\Foo\foo.cpp    -- not in Foo.Tests\
       |
       |-[-] unit-tests
          |- foo_Tests.cpp   Foo\Foo.Tests\foo_Tests.cpp
          |- bar_Tests.cpp   Foo\Foo.Tests\bar_Tests.cpp

Uważam, że używanie rzeczy C ++ / CLI do testowania jednostkowego po prostu moczy wody podczas testowania czystego natywnego kodu C ++. Jednak użyłem NUnit do przetestowania kodu aplikacji C ++ / CLI. Napisałem swoje testy w C # i to działało dobrze. (Istniejącą bazą kodu był C ++ / CLI i nie chciałem przenosić go do C #.)
zalegalizuj

Ponadto, jeśli twoje testy są w C ++ / CLI, nie możesz uruchomić ich na innych platformach. W większości miejsc, w których korzystałem z C ++, potrzebna była umiejętność kompilacji między platformami. Oczywiście nie możesz ponownie użyć projektu VS na innych platformach, ale nie jest to nic wielkiego, aby mieć do niego Makefile lub SConscripts.
zalegalizować

@legalize Nie możemy ponownie wykorzystywać WinAPI (oraz COM i innych technologii specyficznych dla systemu Windows) również na platformach innych niż Windows.
Abyx 17.11.11

Tak, oczywiście nie można używać technologii specyficznych dla systemu Windows na platformach innych niż Windows. Moja obserwacja była po prostu taka, że ​​jeśli masz kod agnostyczny platformy, nie chcesz wiązać testów jednostkowych z konkretną platformą. U poprzedniego pracodawcy oceniliśmy dużą liczbę ram i metod testów jednostkowych. Wybraliśmy Boost.Test, ponieważ był on wieloplatformowy i jeśli cokolwiek miałoby się skończyć w standardowej bibliotece C ++ w zakresie testów jednostkowych, najprawdopodobniej byłby to Boost.Test.
zalegalizować

2

Może trochę późno w ciągu dnia, ale jeśli poprawnie przeczytam twoje pytanie, szukasz technik, które poprawią cykl TDD? Nie wspomniano tutaj, ale czy oglądałeś wydarzenia po kompilacji w VS?

Nasze rozwiązania są zazwyczaj zorganizowane (z pokazanymi zależnościami projektu) ...

MAIN-APP > LIB1, LIB2, UNIT-TEST-APP
UNIT-TEST-LIB1 > LIB1
UNIT-TEST-LIB2 > LIB2
UNIT-TEST-APP > UNIT-TEST-LIB1, UNIT-TEST-LIB2

Wydarzenie po kompilacji MAIN-APP uruchomi UNIT-TEST-APP

Zdarzenie po kompilacji UNIT-TEST-APP uruchomi się samo (wystarczy wpisać „$ (TargetPath)” jako polecenie do uruchomienia w zdarzeniu po kompilacji).

(Oznacza to, że podczas budowania GŁÓWNEJ APLIKACJI testy jednostkowe mogą przebiegać dwukrotnie, ale w naszym przypadku nie był to problem!)

Jak już wspomniano, tak, konfiguracja tej struktury wymaga trochę wysiłku, ale kiedy już się pojawi, dodawanie testów jest proste.

Wszystko, co musisz zrobić, to zbudować główną aplikację, a testy jednostkowe uruchomią się automatycznie!


1

Cóż, nie wiem, czy to pomaga, ale jest kilka świetnych filmów o TDD autorstwa Bretta L. Schucherta. Niestety nie pokazuje kombinacji „C ++” i „VS”, ale

TDD z C # i VS: http://vimeo.com/album/210446

TDD z C ++ i Eclipse: http://vimeo.com/13240481

Być może możesz to rozwiązać na podstawie tych dwóch.

EDYCJA: wideo w C ++ dotyczy oczywiście użycia ramy testowej CppUTest z Eclipse. Kiedy go opublikowałem, pomyślałem, że powinien być łatwo przystosowany do użycia w VS. Więc trochę google i znalazłem to:

http://schuchert.wikispaces.com/tdd.cpp.NotesOnCppUTest

który daje informacje, jak korzystać z CppUTest w Visual Studio.


2
Doc - obejrzałem (tylko) film TDD / Eclipse, ale będę go głosować. Film pokazuje dokładnie to, co mnie nie interesuje, a mianowicie sposób pisania kodu testu jednostkowego. Problem (tego pytania) nie polega na pisaniu testów jednostkowych, ale na tym, jak poprawnie je zintegrować z rozwojem produkcji w C ++ i nie widzę, jak te filmy tutaj pomagają.
Martin Ba

Chociaż głosowałem tę odpowiedź w kontekście tego pytania, chciałbym dodać, że filmy są całkiem fajne. Interesujące było obejrzenie Eclipse / TDD / C ++. To po prostu nie pomaga :-)
Martin Ba

@ Martin: zobacz moją edycję.
Doc Brown,

Doceniamy twój wysiłek i chociaż nie sądzę, aby ten dodatkowy link był naprawdę pomocny w kontekście tego pytania, myślę, że będę musiał sam dokonać edycji.
Martin Ba

@Martin: ok, ponownie przeczytałem twoje pytanie i twoją definicję „znośnego”, ale czy nie oczekujesz trochę za dużo? Utworzenie projektu testowania jednostkowego nie jest rozwiązaniem „jednym kliknięciem”, ale wysiłek napisania faktycznych testów jednostkowych przeważa nad rzędem wielkości, niezależnie od tego, jakiego używasz frameworka.
Doc Brown,

1

Googletest
Jak zintegrować z vc ++

Nie potrzebujesz wtyczki, test to kolejny cel. Nie ma wtyczek do generowania testu przy pomocy c ++, na przykład gdybyś mógł testować niepotrzebne rzeczy, takie jak przypisania


„nawet gdybyś mógł testować niepotrzebne rzeczy, takie jak zadania” - co to ma znaczyć? Czy naprawdę uważasz, że lepsza obsługa IDE testów jednostkowych w C ++ jest bezwartościowa?
Martin Ba

Mam na myśli w języku takim jak c ++, system nie może automatycznie tworzyć testów dla niczego innego niż oczywiste stwierdzenia
Martin Beckett,

2
Dlaczego nie? Co przeszkadza wtyczce w automatycznym generowaniu vcprojpliku w locie, ściągając plik testowy, który napisałem, i plik produkcyjny, do którego się odwołuje, i próbując go uruchomić? (Po prostu marzę, ale można go sprawić, że zadziała).
Martin Ba

2
Nie jestem pewien, czy mogę śledzić. oczywiście muszę sam napisać Testy . Ale ich uruchomienie może być znacznie łatwiejsze niż ręczne konfigurowanie (i utrzymywanie!) Oddzielnych plików projektów testowych.
Martin Ba

2
Nie, nie odnosiłem się do kodu testowego, ale raczej do rusztowania projektu / kompilatora potrzebnego do uzyskania kodu testowego i kodu produkcyjnego „jego” do uruchomienia.
Martin Ba

1

Nie mogę komentować narzędzi C ++, których nie dotknąłem od około 20 lat (obecnie .NET Dev) i wydaje mi się, że większość narzędzi w dzisiejszych czasach służy do kodu zarządzanego, ale jak do technik ...

Jak wspomnieli inni, kod testowy jest zawsze w zupełnie innym projekcie / zestawie niż kod produkcyjny i tak, zwykle musisz sam utrzymywać ten projekt, chociaż z pewnością w VS IDE nie jest to duży problem, ponieważ często masz kilka projektów, takich jak i tak część twojego rozwiązania.

Kod produkcyjny jest i musi być napisany nieco inaczej dla TDD. Podczas pisania testów najpierw musisz zaprojektować kod, aby był testowalny. Jest to zupełnie inny temat sam w sobie, ale na początku może wydawać się bardzo frustrujący, szczególnie jeśli twoje IDE / narzędzia nie dają ci szybkiej informacji zwrotnej, wystrzelenie w celu uruchomienia narzędzi wiersza poleceń do uruchomienia testów jest po prostu uciążliwe.

Istnieje wiele specyficznych technik umożliwiających testowanie kodu, ale większość z nich dzieli się na tworzenie małych obiektów, które niewiele robią, dzięki czemu można je testować w izolacji i możliwość wstrzyknięcia testowej wersji niektórych zachowań w bardziej złożone przedmioty Ramy MKOl mogą tu bardzo pomóc.

Przydatna jest książka; Michael Feathers, Efektywnie współpracujący ze starszym kodem. Używa wielu języków w swoich przykładach i może pomóc w określeniu konkretnych podejść do bezpiecznego dostosowania kodu / technik, które nie zostały pierwotnie zaprojektowane do testowania.

Małe zastrzeżenie: piłem z Agile Kool-Aid lata temu: D


Uwaga: mam już Working Effectively with Legacy Codena swoim biurku :-)
Martin Ba,

0

Maven nie jest powszechnie używany w C ++ (ale jest głównie używany w Javie, ale jest niezależny od języka), ale jest to bardzo potężne narzędzie i pozwala zachować wszystko w jednym projekcie (w tym testy, w rzeczywistości jest to zalecane podejście z Maven). Sugeruję to teraz, ponieważ z dotychczasowych odpowiedzi wygląda na to, że alternatywa dla wtyczki VS może nie istnieć.

W poszukiwaniu wtyczek znalazłem:

http://incubator.apache.org/npanday/

ale nie wygląda jeszcze na bardzo dojrzały. Z instalacją Maven wszystko, co musisz zrobić, aby uruchomić testy, jest uruchamiane mvn testz wiersza poleceń.

Jeśli jesteś zainteresowany, możesz dowiedzieć się o tym tutaj i (jednej z) wtyczek obsługujących C ++ tutaj (Maven ma architekturę wtyczek, więc wszystko jest wtyczką).


0

Zalecenia ramowe: w naszym biurze używamy TestDriven.NET, który integruje się z Visual Studio. Unittest klasy są napisane w C ++ / CLI, które mogą następnie wywoływać dowolny natywny kod, który potrzebujesz przetestować. Tak, klasy C ++ / CLI wchodzą we własny zestaw, dlatego do rozwiązania (rozwiązań) dodano projekt „testowania”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.