Softwarequalitätsmanagement: Unterschied zwischen den Versionen

Aus CCWiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Zeile 164: Zeile 164:
==== checkout ====
==== checkout ====
Der Befehl {{BSL|git checkout}} hat mehrere Funktionen:
Der Befehl {{BSL|git checkout}} hat mehrere Funktionen:
# Änderungen von Dateien können rückgängig gemacht werden. Die Änderungen die passiert sind bis zum letzten {{Link|Commit}}. Gleich wie bei {{Link|add}}, kann dies ein regulärer Ausdruck, mehrere Dateinamen oder ein '''.''' sein.
# Änderungen von Dateien können rückgängig gemacht werden. Dies betrifft nur die Änderungen die passiert sind seit dem letzten {{Link|Commit}}. Gleich wie bei {{Link|add}}, kann dies ein regulärer Ausdruck, mehrere Dateinamen oder ein '''.''' sein.
# Neue Branches können mittels {{BSL|git checkout -b [Branchname]}} erstellt werden, oder es kann zu einem anderen {{Link|Branch}} mit {{BSL|git checkout [Branchname]}} gewechselt werden.
# Neue Branches können mittels {{BSL|git checkout -b [Branchname]}} erstellt werden, oder es kann zu einem anderen {{Link|Branch}} mit {{BSL|git checkout [Branchname]}} gewechselt werden.
==== push ====
==== push ====
==== pull ====
==== pull ====

Version vom 3. Februar 2021, 15:22 Uhr

Im folgenden sollen einige Maßnahmen erläutert werden, welche der Erhöhung der Softwarequalität dienen.

Testing

Softwaretesting beschreibt den Prozess des verifizierens einer Anwendung, oder Teile davon, gegenüber einer gewissen Spezifikation, oder gegen ein erwartetes Verhalten. Durch Testing kann ein hohes Maß an Softwarequalität gewährleistet werden, natürlich nur wenn Tests gut spezifiert und auch ausgeführt werden. Gerade im Bereich des automatisierten Testens kann durch eine hohe Testabdeckung des Quellcodes, Regression, verhindert werden.

Eine hohe Testabdeckung, beschreibt, wieviel Code durch Testfälle auch wirklich erreicht wird. Werden alle Verzweigungen in Methoden erreicht? Werden überhaubt alle Methoden getestet?
Unter Regression wird eine Verschlechterung des Quellcodes verstanden. Im Laufe des Entwicklungsprozesses funktioniert Code, der zuvor funktionert hat, auf einmal nicht mehr.

Beispiel mit JUnit

Anhand von folgendem Beispiel soll die Testabdeckung einer Java Klasse mit dem Testframework JUnit veranschaulicht werden:

public class DateUtils {
  public String getDayOfWeekName(int month) {
    if(month == 1) {
      return "Montag";
    } else if(month == 2) {
      return "Dienstag";
    } else if(month == 3) {
      return "Mittwoch";
    } else if(month == 4) {
      return "Donnerstag";
    } else if(month == 5) {
      return "Freitag";
    } else if(month == 6) {
      return "Samstag";
    } else if(month == 7) {
      return "Sonntag";
    }
    return "Unbekannt";
  }
}

Das Programm verfügt über eine Methode, welche 8 verschieden Verzweigungen hat.
Testabdeckung von 50%:

@Test
public void testDayOfWeekName() {
  DateUtils utils = new DateUtils();
  assertEquals("Montag", utils.getDayOfWeekName(1));
  assertEquals("Dienstag", utils.getDayOfWeekName(2));
  assertEquals("Mittwoch", utils.getDayOfWeekName(3));
  assertEquals("Donnerstag", utils.getDayOfWeekName(4));
}

Testabdeckung von 100%:

@Test
public void testDayOfWeekName() {
  DateUtils utils = new DateUtils();
  assertEquals("Montag", utils.getDayOfWeekName(1));
  assertEquals("Dienstag", utils.getDayOfWeekName(2));
  assertEquals("Mittwoch", utils.getDayOfWeekName(3));
  assertEquals("Donnerstag", utils.getDayOfWeekName(4));
  assertEquals("Freitag", utils.getDayOfWeekName(5));
  assertEquals("Samstag", utils.getDayOfWeekName(6));
  assertEquals("Sonntag", utils.getDayOfWeekName(7));
  assertEquals("Unbekannt", utils.getDayOfWeekName(8));
}

Testabdeckung von 0%:

@Test
public void testDayOfWeekName() {
  DateUtils utils = new DateUtils();
}

Testansätze

Es gibt verschiedene Ansätze wie Tests entwickelt und ausgeführt werden können. Im folgenden sollen die Box Ansätze kurz erläutert werden.

White Box

Der zu testende Quellcode ist bekannt, das Test Design kann sich am Code orientieren um alle Verzweigungen zu erreichen. Weiters können auch Teile des Codes, welche nicht nach außen hin Sichtbar sind, getestet werden. Unit Tests fallen normalerweise in diese Kategorie. Durch White Box Tests kann eine hohe Testabdeckung des Codes erreicht werden.

Black Box

Über den Quellcode sind keine Informationen bekannt. Die Tests richten sich lediglich nach den nach außenhin sichtbaren Schnittstellen, die ein Programm bereitstellt. Dieser Ansatz ist für alle Teststufen geeignet.

Grey Box

Informationen über den Quellcode sind vorhanden, beispielsweise über Reverse Engineering. Zum Testen werden jedoch wie bei den Black Box Tests, lediglich die nach außenhin sichtbaren Schnittstellen werden verwendet.

Teststufen

Testing kann in verschiedene Stufen unterteilt werden, die im folgenden Angeführt werden. Im folgenden von fein bis grob:

Unit Test

Beschreibt das Testen auf Modul- oder Komponentenebene. Hierbei sollen abgrenzbare Teile eines Programmes getestet werden. Dies wäre Beispielsweise das Testen von einer Klasse. Ein konkretes Beispiel hierfür ist hier zu finden.

Integration Test

Beim Integrations Test wird das zusammenspiel unterschiedlicher Komponenten miteinander getestet.

System Test

Beim System Test wird das gesamte System gegen alle Anforderungen getestet. Beim Test soll die Produktivumgebung des Kunden simuliert werden.

Abnahme Test

Der Abnahme Test ist das testen des gesamten Systems durch den Kunden.

CI/CD

Continous Integration und Continous Delivery sind eng verknüpft miteinander. Durch Continous Integration wird ein höheres maß an Qualität erreicht, Continous Delivery bietet durch automatisiertes ausliefern der Software hohen Komfort und Zeitersparnis, da dies nicht mehr manuell gemacht werden muss.

Continous Integration

Continous Integration beschreibt einen kontinuierlichen, automatisierten Prozess der im wesentlichen aus zwei Bestandteilen besteht:

  1. Dem kontinuierlichen Bauen der Software - Der Quellcode wird automatisch kompiliert, zusammengebaut. Dadurch können schwere Fehler, die das erstellen des Programmes verhindern direkt erkannt werden.
  2. Dem kontinuierlichen Testen der Software - Automatisierte Tests werden automatisch ausgeführt. Somit können effektiv Regressionen verhindert werden und die Softwarequalität bleibt hoch.
Unter kontinuierlich wird in diesem Kontext immer fortwährend oder andauernd verstanden. Natürlich läuft die Continous Integration nicht immer, sondern wird durch gewisse Ereignisse getriggert (gestartet). 

Dieser kontinuierliche Prozess wird sehr oft in Kombination mit Git verwendet. Über Git Hooks, kann der Integrationsprozess gestartet werden, z.B. wenn Änderungen auf einen gewissen Branch gepusht werden. Anwendungen für Continous Integration verfügen oft über ein integriertes Git und bieten die Möglichkeit, Repositories anzulegen und zu verwalten.
Schlägt die Continous Integration nach einer Änderung fehl, so kann der Entwickler der für diese Änderung verantwortlich ist, beispielsweise via Email automatisch informiert werden.

Anwendungen

Continous Delivery

Continous Delivery beschreibt den automatisierten Prozess des Deployments. In diesem Kontext beschreibt Deployment das ausliefern der Software. Gleich wie Continous Integration wird Continous Delivery durch gewisse Ereignisse getriggert, und steht meist in der Pipeline hinter der Continous Integration.
Zuerst wird die Software gebaut, dann ausgeliefert.
Die Auslieferung der Software kann je nach Anwendung und Szenario variieren. Dies könnte Beispielsweise sein:

  • Hochladen auf den Playstore/Appstore
  • Versenden der Software per Email
  • Hochladen der Software auf eine Webseite
  • Eine neue Webseite zur Verfügung stellen
  • Einen Docker Container mit einem neuen Image aktualisieren

Anwendungen die Continous Integration anbieten, sind meist auch für Continous Delivery geeignet, deswegen sind die Beispiele gleich wie hier.

Versionskontrolle - Git

Git ist eine freie Software zur verteilten Versionsverwaltung von Dateiein, die durch Linus Torvalds initiert wurde.[1] Git wurde entwickelt um die Versionsverwaltung für den Quellcode des Linux Kernels durch die Versionsverwaltung BitKeeper zu ersetzen.

Eine Versionsverwaltung von Dateien soll es ermöglichen, die Änderungen, die an Dateien vorgenommen wurden, nachzuvollziehen. Weiters sollen diese unterschiedlichen Versionen abgerufen oder wiederhergestellt werden können.

Git ist eine verteilte Versionsverwaltung da das Repository selbst, nicht nur auf dem Server der dieses bereitstellt, sondern auch auf jedem Client der das Repository verwendet, vorhanden ist. Ein Repository kann somit, ohne große Probleme, durch den Client von einem Remote zu einem anderen Remote gewechselt werden.

Remote

Ein Git Repository kann mit einem oder mehreren Remotes verknüpft sein. Ein Remote ist ein Server der das Repository erstellt hat und dieses bereitstellt. Die Verbindung zum Remote vom Client aus, findet meist über die Protkolle HTTP oder SSH statt. Der initiale Remote wird als origin (Ursprung) bezeichnet. Weitere Remotes können mit beliebigen Namen hinzugefügt werden:

#Fügt ein weiteres Remote mit dem Namen asdf hinzu
git remote add asdf https://gitlab.drlue.at/root/webservice.git

Soll bei einer Aktion nun das Remote asdf angesprochen werden, so wird im Befehl anstatt origin asdf verwendet:

#Holen der änderungen von origin (vom Ursprung)
git pull origin main
#Holen der änderungen von asdf
git pull asdf main

Branch

Commit

Ein Commit beschreibt eine Abgeschlossene Einheit von Veränderungen. In einem Commit können neue, geänderte, oder gelöschte Dateien enthalten sein. Ein Commit enthält immer nur Deltas zum Vorhergehenden Commit, d.h. darin stehen nur die Änderungen. Ein Commit enthält zusätzlich zu den Änderungen noch Daten:

  • Autor
  • Datum
  • Eindeutiger Hash Wert. Über diesen kann ein Commit angesprochen bzw. referenziert werden

Im folgenden Beispiel ist das zurücksetzen der lokalen Dateien auf einen bestimmten Commit ersichtlich, weiters wird ein Beispiel Output von git log gezeigt:

git log
>>...
>>commit 29b645bf9c1a4dd54dcb51026390231729287cc8
>>Author: Luke <luke@luke.at>
>>Date:   Tue Feb 2 08:44:33 2021 +0100
>>
>>    - Fastlane update.
>>...
//Zurücksetzen des lokalen Codes auf obigen commit
git reset --hard 29b645bf9c1a4dd54dcb51026390231729287cc8

Wichtige Befehle

Folgend sollen einige wichtige Git Befehle erläutert werden. Diese beginnen immer mit git und sind somit eigentlich nur Parameter des Programmes git.

add

Um gelöschte, geänderte oder neue Dateien einem Commit hinzuzufügen, müssen diese zuerst gestaged, also der Staging Area hinzugefügt, werden. Dies geschieht mit dem Befehl git add. Den kann man sich wie ein Packet vorstellen, zuerst werden Dinge hineingegeben git add, ist alles gewünschte drinnen, wird das Packet mit git commit verschlossen. git add nimmt als Parameter reguläre Ausdrücke (*.txt), mehrere Dateinamen (a.txt b.txt c.txt) oder auch direkt einen . (Alles hinzufügen).

commit

Mit dem Befehl git commit werden alle Änderungen in der Staging Area in einen Commit verpackt und mit einem Text versehen.

checkout

Der Befehl git checkout hat mehrere Funktionen:

  1. Änderungen von Dateien können rückgängig gemacht werden. Dies betrifft nur die Änderungen die passiert sind seit dem letzten Commit. Gleich wie bei add, kann dies ein regulärer Ausdruck, mehrere Dateinamen oder ein . sein.
  2. Neue Branches können mittels git checkout -b [Branchname] erstellt werden, oder es kann zu einem anderen Branch mit git checkout [Branchname] gewechselt werden.

push

pull

merge

Siehe Merge.

rebase

Siehe Rebase.

log

Der Befehl git log zeigt die Commit History an. Also die Geschichte der Commits sortiert von neu bis alt.

status

Der Befehl git status, zeigt den aktuellen Status des Arbeitsverzeichnisses an:

  • Welche Dateien wurden gelöscht oder verändert
  • Welche Dateien sind neu hinzugefügt worden, also nicht nicht mit dem Git Repository verbunden
  • Welche Dateien wurden bereits getstaged und befinden sich somit in der Staging Area, siehe add
  • In welchem Branch befindet man sich gerade

reset

Hooks

Mittels Git Hooks kann auf gewisse Git Aktionen auf dem Server, welcher das Git Repository hostet, gehorcht werden.

Es gibt auch Client-Side Hooks. Diese ermöglichen auch das Horchen auf Aktionen auf dem Rechner des Clients, hierbei werden aber nicht alle Aktionen unterstützt, beispielsweise Post Push (nach dem gepusht wurde).

Tritt eine solche Aktion ein, so kann beispielsweise ein Programm ausgeführt werden. Git Hooks sind sehr nützlich für Continous Integration und Continous Delivery. Durch ein pushen von Änderungen, können diese gestartet werden.

Branches zusammenführen

Merge

Rebase

Pull/Merge Requests