class: center, middle, first # Software-Entwicklung 3 ## Container, CI/CD --- # Agenda 1. Recap 2. Container 3. CI/CD Container * Was sind die Probleme? * Was sind die Alternativen? Z.B. VM * Warum keine VM? * Lösung der Probleme mit Containern * Wie unterscheiden sich Container von VMs? * "Anwendungsvirtualisierung" * Kernel des Hosts wird durchgereicht * Container-Grundprinzipien * Keine Daten im Container speichern * Persistente Daten werden außerhalb des Containers abgelegt * Container mit Docker * Kurze Historie * Probleme (root, Lizenz für Desktop-Client in Unternehmen) * Alternativen (z.B. Podman) * Demo: Aufruf von CLI-Tools per Docker-Container * Wie wird ein Container definiert? `Dockerfile`, `docker-compose.yml` * Demo: Start von `node`-Server inkl. Mounts des working-dir * Wie kommen Daten in und aus den Container? * Volume-Mounts * Bind Mounts * Port-Tunneling * Ausblick: * Microservices * Containerregistry CI/CD * Was ist CI? * Was ist CD? * Warum ist CI/CD sinnvoll? Was ist die Konsequenz wenn man darauf verzichtet? --- # Recap: Was haben wir letzte Woche besprochen? * Build Management mit Maven * Testing mit JUnit > Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt) --- class: center, middle # Was muss getan werden um eine (Server-)Anwendung zu starten? Was sind die Probleme? ??? * Umgebung einrichten * Unterschiedliche Versionen (Libraries, OS) * Kompatibilitätsprobleme --- # Build Management Tools * Unterstützung bei Projekterstellung * Standardisierung: Reproduzierbare Builds * Automatisierung * Verwaltung von Abhängigkeiten * Durchführen von Tests * Bündeln der Software * Bereitstellung > Unterstützung des Entwicklungszyklus --- # Beispiele * Java: Maven, Gradle * NodeJS: `npm`, `yarn` (Packagemanager) * Unix: `make` * Python: `pip` (Packagemanger), PyBuilder * ... --- # Build Management Tool: Maven * Grundprinzipien: Phasenmodell/Build Lifecycle & Konvention über Konfiguration & DRY * Template-basierte (Java-)Projekterstellung mit **Archetypes** * Dependeny Management * Erweiterbar durch Plugins * Unterstützung durch IDEs ## Standardverzeichnisstruktur ```bash . project-root ├── pom.xml # Projektkonfiguration ├── src # Source Code │ ├── main │ │ ├── java # Java Code und Packages │ │ └── resources # Dateien, die zur Laufzeit benötigt werden │ └── test # Test Code │ └── java └── target ``` --- # Maven: Build Lifecycle Werden bis zur angegebenen Phase durchgeführt. 1. `validate`: Überprüfen, ob alle Informationen vorhanden sind. 2. `compile`: Kompilieren der in `src` vorhandenen Dateien 3. `test`: Durchführen der in `test` vorhandenen Tests 4. `package`: Erstellen von z.B. `jar`-Dateien 5. `verify`: Nutzbar z.B. für statische Codeanalyse 6. `install`: Kopieren der `jar` nach `~/.m2/repository` 7. `deploy`: Veröffentlichen der `jar` in ein öffentliches Repo Beispielaufruf: `mvn package` Weitere Informationen: [Maven Build Lifecycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) --- # `pom.xml` Beispiel - General ```xml
4.0.0
de.hdm.jordine
musicmanager
0.1.0-SNAPSHOT
17
17
``` --- # `pom.xml` Beispiel - Dependencies ```xml
org.junit.jupiter
junit-jupiter-engine
5.8.2
test
org.mockito
mockito-core
4.4.0
test
org.apache.logging.log4j
log4j-api
2.17.2
org.apache.logging.log4j
log4j-core
2.17.2
``` --- # `pom.xml` Beispiel - Plugins ```xml
org.apache.maven.plugins
maven-jar-plugin
3.2.2
true
de.hdm.jordine.musicmanager.app.MusicManagerApp
``` --- class: center, middle # Warum ist Testing wichtig? --- class: center, middle # Welche Testarten kennen Sie? --- # Testarten * Usabilitytests * **Softwaretests** * Hardwaretests * Securitytests * ... --- # Testebenen * **Unittests**: Test einzelner Funktionen und Methoden * **Integrationtests**: Test des Zusammenspiels mehrerer Module * **Funktionstests**: Überprüfen der Geschäftslogik * **End-to-End-Tests**: Testen echter Benutzungsszenarien (bspw. von UI bis DB) * **Leistungstests**: Überprüfung der Performance * **Reggressionstests**: Sicherstellung nach Änderungen, dass Bestandsfunktionen weiterhin funktionieren * **Smoketests**: Grundlegende Funktionsüberprüfung, z.B. nach Release _nach: https://www.atlassian.com/de/continuous-delivery/software-testing/types-of-software-testing_ --- # Testprinzip F.I.R.S.T * **F**ast: Tests sollen schnell durchlaufen, damit diese häufig durchgeführt werden. * **I**solated: Jeder Test sollte unabhängig sein und sein eigenes Enviroment mitbringen. * **R**epeatable: Auch nach mehrfachen Durchläufen soll das Ergebnis identisch sein. * **S**elf-validating: Automatische Überprüfung, ob Test erfolgreich war. * **T**imely: Test sollte beim Entwickeln der Funktionalität geschrieben werden. > Blick auf Demo-Projekt --- # Unittests mit JUnit * Nutzen der `assert`-Methoden, zum Überprüfen von erwarteten und tatsächlichen Werten * Nutzen der Test-Annotations, z.B. * `@Test` * [`@RepeatedTest`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-repeated-tests) * [`@ParameterizedTest`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests) * `@BeforeEach`/`@AfterEach` * `@BeforeAll`/`@AfterAll` * [`@DisplayName`](https://junit.org/junit5/docs/current/user-guide/#writing-tests-display-names) * Integration in CI/CD-Prozesse Dokumentation: https://junit.org/junit5/docs/current/user-guide/ --- # Was sollte getestet werden? * "Happy path" - der einfachste Fall * Randbedingungen * Fehlerfälle --- # Testing: Begrifflichkeiten ## Mock * Objekt, dass ein bestimmtes Verhalten simuliert * Erlaubt schnelleres Testen -> **F**.I.R.S.T * Framework-Beispiel: [Mockito](https://site.mockito.org) ## Code coverage * Gibt an, wieviel Prozent des Codes durch Tests abgedeckt sind * Je höher der Wert, umso besser --- # Testdriven Development (TDD) * Entwicklungsmethode * Tests werden vor dem eigentlichen Code entwickelt * Mögliches Vorgehen (_nach: [it-agile.de](https://www.it-agile.de/agiles-wissen/agile-entwicklung/was-ist-testgetriebene-entwicklung/)): * **Test "rot"**: Test erstellen, der auf einfachste Art und Weise die gewünschte Funktionalität erfüllt. Da kein Code besteht, der die Funktion abdeckt, schlagen die Tests fehl. * Einfachste Umsetzung der Funktionalität bis der **Test "grün"** wird. * **Refactoring** des Codes. Tests werden weiterhin regelmäßig durchgeführt und müssen grün bleiben. --- # Projektdemo