Jeśli chodzi o testy, mogę wymyślić dwie opcje:
- Umieść test i aplikację w jednym obrazie.
- Uwzględnij tylko kod aplikacji na obrazie. Utwórz kontener specyficzny dla testu, który buduje po głównym obrazie i dodaje do niego kilka warstw (kod testowy, zależności itp.).
W przypadku pierwszej opcji mogę przetestować pojemnik i wysłać go dokładnie tak, jak został przetestowany. Oczywistym minusem jest to, że obraz zawiera niepotrzebny kod (i potencjalnie dane testowe).
W przypadku drugiej opcji wysyłany obraz nie jest dokładnie taki sam jak ten, który jest testowany.
Oba wyglądają jak złe strategie. Czy istnieje trzecia, lepsza strategia?
Odpowiedzi:
Do uruchamiania testów w czasie kompilacji preferowanym sposobem byłoby użycie kompilacji wieloetapowej . Wielostopniowe pliki dokowania pozwalają uzyskać większy etap ze wszystkimi zależnościami do budowania i testowania, a następnie skopiować dokładnie przetestowane artefakty na inny etap w celu uzyskania mniejszego obrazu środowiska wykonawczego.
Chcesz również na poziomie systemu testów wielu kontenerów, używając ich zewnętrznych interfejsów zamiast uruchamiać się w kontenerze. Ponieważ testy te wymagają koordynacji między usługami, wymagają różnych zależności, takich jak dostęp do Twojej aranżacji, nie są tak dokładne jak testy kompilacyjne i często są pisane w zupełnie innych językach, nie jest wielkim problemem, aby uruchamiać je z osobnego Dockera pojemnik dedykowany tylko do testowania systemu.
źródło
Istnieje trzeci sposób, jak sam powiedziałeś. Myślę, że mieszasz rozwój, testowanie i wdrażanie. Proponuję, aby spojrzeć na całość SDLC jako całość, po pierwsze, aby zrozumieć, co próbujesz osiągnąć. To duży temat, ale dołożę wszelkich starań, aby podsumować.
TL; DR;
Krótko mówiąc, musisz oddzielić:
Każdy musi być od siebie niezależny i odpowiednio:
Dłuższa wersja
Po pierwsze, masz aplikację złożoną z kodu i (oddzielnych zestawów) konfiguracji. Należy to przetestować, zarówno dla funkcji kompilacji, jak i celowej - nazywa się to ciągłą integracją (CI). Istnieje wielu dostawców tej usługi, zarówno online, jak i lokalnie - na przykład CircleCI dla dostawcy usług w chmurze, który łączy się z Twoim repozytorium oraz buduje i testuje za każdym razem, gdy się zgadzasz. Jeśli Twoje repozytorium jest dostępne na miejscu i nie może korzystać z usług dostawcy chmury, coś takiego jak Jenkinsbyłoby równoważne. Jeśli aplikacja jest dość standardowa, prawdopodobnie istnieje obraz Docker, z którego może korzystać usługa CI. Jeśli nie, musisz utworzyć taki klaster lub taki, aby można było wdrożyć kod aplikacji i konfigurację. Prawidłowo skonfigurowany, będziesz mieć mnóstwo statystyk dotyczących jakości kodu aplikacji.
Następnie, gdy będziesz zadowolony z funkcjonalności i poprawności aplikacji, podstawa kodu powinna być odpowiednio oznaczona dla konkretnego wydania. Tę kompilację należy następnie wdrożyć w środowisku testowym. Pamiętaj, że kod będzie taki sam, jak testowany w twoim CI (oczywiście, jeśli zrobiłeś to poprawnie), ale twoja konfiguracja może się różnić. Ponownie niektórzy dostawcy CI mogą zaoferować ten krok, aby przetestować wdrożenie aplikacji w pakiecie i dyskretną konfigurację. Ten etap zazwyczaj obejmuje testy funkcjonalne użytkownika (w przypadku nowej funkcjonalności), a także testy automatyczne (w przypadku znanej funkcjonalności). Jeśli wersja przejdzie ten etap, masz kandydata do testowania integracji. Możesz uruchomić testy automatyzacji z innego kontenera Docker,niektóre wskaźniki określające wysiłek testowania to 1: 1 do wysiłku kodowania (chociaż sam nie jestem tego pewien).
Przedostatnio następnym krokiem jest zbudowanie środowiska (systemowego) tak, jakby było produkcją. Jeśli używasz Dockera w środowisku produkcyjnym, tutaj pomyślisz o wzmocnieniu bezpieczeństwa, optymalizacji sieci i serwera itp. Twoje obrazy Dockera mogą być oparte na tych, które wykorzystałeś w rozwoju (najlepiej), ale mogą wystąpić zmiany w zakresie skalowania i bezpieczeństwa , Tak jak powiedziałem. Do tej pory testy funkcjonalne aplikacji powinny być zakończone, bardziej zależy Ci na bezpieczeństwie i wydajności. Jeśli chodzi o testy funkcjonalne, tutaj można opracować, wdrożyć i uruchomić testy z innych obrazów Docker. Ten krok był strasznie drogi i rzadko wykonywany, dlatego potrzebny był dedykowany sprzęt, który odtwarzał produkcję. Obecnie jest to całkowicie wykonalne, ponieważ na żądanie można wstać i zburzyć całe środowisko o dowolnej skali.
Wreszcie, masz wersję, która powinna być gotowa do produkcji, z niewielkim zestawem różnic konfiguracyjnych w porównaniu z testami integracji (adresy IP, identyfikatory URI bazy danych, hasła itp.) Baza kodu została przetestowana w co najmniej trzech różnych środowiskach punkt i większość konfiguracji systemu przynajmniej raz.
źródło
Myślę, że mieszasz różne rodzaje testów. Zasadniczo musisz zadać sobie pytanie: jaka jest tutaj testowana jednostka?
Najczęstszym scenariuszem, gdy pracujesz jako programista, jest pisanie testów jednostkowych / integracyjnych dla jakiegoś fragmentu kodu, nad którym pracujesz, gdzie ten fragment kodu jest testowaną jednostką. Testy przeprowadzasz lokalnie i / lub w CI.
Po zbudowaniu nowego obrazu dokera staje się on nową jednostką, którą możesz przetestować. Jakie rzeczy chciałbyś przetestować dla tego obrazu? Jaki interfejs API zapewnia? Jak to testujesz?
Jeśli jest to aplikacja internetowa, możesz uruchomić kontener na podstawie obrazu i wykonać kilka żądań HTTP i sprawdzić, czy odpowiedzi są zgodne z oczekiwaniami. Myślę, że problem polega na tym, że jesteś bardzo przyzwyczajony do struktury testowej powiązanej z kodem aplikacji. Nie ma to problemu podczas programowania, ale teraz chcesz przetestować obraz dokera, więc potrzebujesz nowego rodzaju środowiska testowego, które może to zrobić i nie jest powiązane z kodem aplikacji.
Myślę więc, że trzecią opcją, której szukasz, jest:
Zatem kroki CI / CD byłyby następujące:
Skonfiguruj środowisko programistyczne -> Uruchom testy na kodzie -> Zbuduj końcowy obraz -> Uruchom testy na obrazie -> Wdróż obraz.
źródło