Experience Embedded

Professionelle Schulungen, Beratung und Projektunterstützung

Konsistente Metriken zur Ermittlung der Testaktivitäten

Autor: Ingo Nickles, Vector Software

Beitrag - Embedded Software Engineering Kongress 2016

 

In der modernen Softwareentwicklung gilt es, neue Funktionalitäten in immer kürzeren Zeitabständen zu implementieren. Der Quellcode wird immer umfangreicher und komplexer, dennoch wird erwartet, dass die Software Qualität gleich bleibt oder sich sogar noch verbessert. Die größte Herausforderung ist sicherlich, Release-Zyklen zuverlässig vorherzusagen und einzuhalten. Oft werden Aufwände falsch eingeschätzt und Ressourcen ungünstig verteilt, denn die Projektleiter wissen häufig nicht genau, welche Codeänderungen welche Ressourcen benötigen.

Natürlich tragen im Software-Entwicklungsprozess viele Dinge zur Software-Qualität bei. Neben einem funktionierenden Anforderungsmanagement sind dies z.B. eine entsprechende Software-Architektur und ein gutes Design. Nichts desto trotz wird die Software-Qualität aber am Ende im Testprozess gemessen bzw. nachgewiesen, und so ist es durchaus sinnvoll, sowohl den Testprozess als solches, als auch die sich daraus ergebenden Metriken näher zu beleuchten.

Durch kontinuierliches Testen, sowie die kontinuierliche Integration von Codeänderungen und angepassten Testfällen ins Configuration Management können häufig auftretende Terminverzüge vermieden werden. Änderungsbasiertes Ausführen der Testfälle erlaubt es jedem Entwickler, automatisiert alle Arten von Testfällen auszuführen, die von deiner Codeänderung betroffen sind.

Konsistente und nachvollziehbare Metriken können wichtige Hinweise auf den momentanen Entwicklungsstand, den Entwicklungsverlauf und den aktuellen Testfortschritt liefern. Durch Kenntnis dieser Daten ist es möglich, einen sehr genauen Überblick über den momentanen Projektstatus und die Software-Qualität zu erhalten. Dadurch lässt sich ein möglicher Release-Zeitpunkt genauer vorhersagen. Ebenso ist es zu jeder Zeit möglich, eventuelle Engpässe zu erkennen und Ressourcen besser zu planen. 

Einführung

Betrachtet man die Entwicklung von Software (SW)- zu Hardware (HW)-Anteilen in Produkten, so ist ein deutlicher Trend zu mehr SW erkennbar. SW wird mehr und mehr zum "Differentiator" - zu dem, was den Unterschied zwischen den Produkten zweier Hersteller und damit den Wettbewerbsvorteil ausmacht. Dadurch, dass mehr Funktionalität in die SW wandert, wird diese natürlich immer komplexer - aber auch wichtiger für den Produkthersteller. Eine hohe Produktqualität hängt immer mehr auch von fehlerfreier Software ab. Durch Einführung entsprechender Entwicklungsrichtlinien, kann die Implementierung von Fehlern ins Produkt sicherlich vermindert werden - dennoch kann und darf man auf einen ausführlichen Testprozess nicht verzichten. Betrachten wir also den Testprozess innerhalb eines Entwicklungsprozesses etwas genauer.

Softwaretest

Der wohl verbreiteste Entwicklungsprozess ist das V-Modell (siehe Abb. 1, PDF), das aufgeteilt ist in drei Phasen: 

  • Designphase
  • Codierungsphase
  • Testphase


Obwohl im V-Modell die Testphase an das Ende des Entwicklungszyklus gestellt ist, hat man bald erkannt, dass es durchaus sinnvoll ist, sehr viel früher mit dem Testen zu beginnen, denn je früher ein Fehler gefunden wird, desto günstiger ist dessen Beseitigung. 

Im klassischen V-Modell versucht man dieser Tatsache dadurch Rechnung zu tragen, dass man die kleinste isolierbarste Einheit der Software, sobald verfügbar, auf Herz und Nieren testet: eine Unit bzw. ein einzelnes Source File. Nachdem das einzelne File bzw. die darin implementierten Funktionen alle Tests überstanden haben, fasst man mehrere Files zusammen und überprüft deren Zusammenspiel im Integrationstest. Im Systemtest wird schließlich die gesamte Software getestet. Betrachten wir also die "rechte Seite" des V-Modells genauer (siehe PDF).

Eine zentrale Rolle im Test kommt der Automation zu. Das manuelle Wiederholen immer gleicher Testabläufe ist einem Menschen nicht zuzumuten, weshalb Test-Automation nicht nur der Mitarbeiterzufriedenheit dient, sondern auch dazu beiträgt, dass Tests auch wirklich ausgeführt werden. Daher sollte bei der Bildung der Test-Landschaft darauf geachtet werden, dass alles, was automatisierbar ist, auch automatisiert wird. Denn nur so ist ein vernünftiger Regressionstest realisierbar.

Regressionstest

Am Ende eines V-Entwicklungsprozesses steht eine gut getestete und qualitativ hochwertige Software. Wenn damit die Möglichkeiten einer SW-Änderung an Ihrem Produkt enden, weil Sie es z.B. zum Mars schießen, spielt für Sie der Regressionstest keine große Rolle. Aber auch dann, wenn Sie keine Möglichkeiten von Softwareänderungen am fertigen Produkt haben, kann sich schon aus dem Einsatz eines anderen Entwicklungsmodells die Notwendigkeit eines Regressionstests ergeben. Z.B. erfordern agile Entwicklungsmethoden ein kontinuierlich erneutes Ausführen der bereits vorhandenen Testfälle. Weitere Gründe für SW-Änderungen und damit ein Wiederholen aller Tests können sein:

  • Fehlerbeseitigungen
  • Neue Feature (CI)
  • Geänderte Hardware
  • Geänderte Anforderungen
  • Redesign


Tatsächlich haben Untersuchungen z.B. von der FDA (Food and Drug Administration, USA) ergeben, dass ein Großteil (79%) von SW-Fehlern, die zu einem Produktrückruf geführt haben, nachträglich durch Codeänderungen ins fertige Produkt eingeführt wurden[1]. Codeänderungen, deren Auswirkungen auf die SW-Qualität durch einen entsprechenden Regressionstest hätten entdeckt werden können.

Testumgebungen

Betrachtet man die Anzahl der Testumgebungen, die in einem empfohlenen Entwicklungsprozess in einem Projekt entstehen, so kommt einiges zusammen:

  • Eine Unit-Testumgebung je Source File
  • Mehrere Integrationstestumgebungen mit jeweils mehreren Source Files
  • Eine bis mehrere Testumgebungen mit allen Source Files für den Systemtest


Hinzu kommt, dass es in der Regel mehr als eine Konfiguration gibt, in der alle Testumgebungen ausgeführt werden sollten. So ist es z.B. offensichtlich sinnvoll und von verschiedenen Standards auch gefordert, die Tests auf dem späteren Zielsystem bzw. einem entsprechenden Board auszuführen. Nun findet ein Unit-Test in der Regel aber sehr früh im Entwicklungsprozess statt. Ein Board zur Ausführung der Unit-Tests ist aber möglicherweise selbst Teil des zu entwickelnden Produkts und steht dementsprechend nocht nicht für eine Ausführung von SW-Tests zur Verfügung.

Aber auch bei vorhandener HW kann es sinnvoll sein, die echte HW zu meiden. Z.B. wird üblicherweise die Test-Applikation auf die HW "ge-flashed" und die Anzahl der von der HW unterstützten Flashzyklen ist dabei begrenzt. Um einen übermäßigen Verschleiß an HW zu vermeiden, kann man also auf Simulatoren oder Emulatoren umsteigen. Dies macht auch das Ausführen von Testfällen schneller, was der Ungeduld des Testers beim Erstellen der Testfälle entgegenkommt.

Beim Nichtvorhandensein von Simulatoren kann es auch sinnvoll sein, eine Testumgebung auf den Host aufzusetzen. Natürlich ist dies mit größerem Aufwand bei der Testumgebungserstellung verbunden: Cross-Compiler-spezifische Keywords müssen "weg-definiert" werden, um den Code mit einem Host-Compiler kompilieren zu können. Hardware-Zugriffe müssen "weg-gestubbt" bzw. durch das Einbinden anderer Header Files ausgetauscht werden. Nichtsdestotrotz macht sich dieser intitiale Aufwand später bezahlt durch verschiedene Vorteile: schnellere Testfallerstellung, Schonen der HW-Ressourcen und nicht zuletzt ein Überprüfen der Software in einem weiteren Testumfeld (anderer Compiler, anderes Betriebssystem). So wird Ihnen Windows z.B. einen "Segmentation Violation Error" beim Zugriff auf invalide Pointer liefern, während der gleiche Testfall auf Ihrem RTOS im schlimmsten Fall sauber durchläuft.

Last but not least wird SW häufig in mehr als einer Konfiguration an spätere Kunden übergeben. Z.B. kann es verschiedene Ausbaustufen Ihres Produkts geben, die auf unterschiedlichen Boards laufen. Oft werden auch Funktionalitäten in der SW per Compile-Defines an- bzw. ausgeschaltet. Oder zentrale Teile der Software laufen in komplett unterschiedlichen Produkten.

Was bedeutet das jetzt für die Anzahl der Testumgebungen? (siehe Abb. 2, PDF)

Anzahl der Testumgebungen  =
    1 Host Konfiguration
+ 1 Simulator Konfiguration
+ (Anzahl Boards * Anzahl Compile-Define-Kombinationen)

Die "Compile-Define-Kombinationen", in denen Ihr Produkt schließlich ausgeliefert wird, ist sinnvollerweise definiert, sodass die Anzahl bekannt ist. Ist dies nicht der Fall, da sich z.B. Kunden baukastenartig ihr Produkt zusammenstellen können, kann es sinnvoll sein, nach Bekanntwerden der Kundenanforderung sämliche Testfälle nochmals in der geforderten Konfiguration durchzuführen.

Obige Formel erhebt keinen Anspruch auf Vollständigkeit, und in Ihrem Umfeld mag ein Faktor oder ein Summand hinzukommen oder wegfallen. Es soll lediglich verdeutlicht werden, dass es "eigentlich" nicht ausreicht, Testfälle in nur einer Testumgebungskonfiguration durchzuführen. Prinzipiell sollten alle Testarten  (also Unit-, Integration-, und System-Tests) in allen möglichen Konfigurationen durchgeführt werden. Oder würden Sie in einem Flugzeug sitzen wollen, dessen SW nur auf dem Host getestet wurde? Oder die Bremsassistenz Ihres Fahrzeugs einem Stück SW überlassen, das in dieser Compile-Define-Kombination auf diesem Board noch nie getestet wurde?

Nicht selten wird behauptet, dass in Testen in allen Kombinationen schlicht unmöglich sei. Durch Test-Automation und entsprechenden Optimierungs-Algorithmen wird die Menge an entstehenden Testfällen aber beherrschbar, und notfalls muss die Varianz beim Kunden reduziert werden. Flexibilität darf nicht zu Lasten der SW-Qualität gehen.

Änderungsbasiertes Testen

Die zuletzt dargestellte Anzahl an Testfällen führt natürlich zu einem Dilemma. Wie sollen immer kürzere Produkt-Release-Zyklen realisiert werden, und wie soll ein Software-Entwickler "sauberen" Code liefern, wenn das Ausführen aller Testfälle zwei Monate dauert? Stand der Technik ist es zurzeit, dass ein pragmatischer Ansatz verfolgt wird. Bei Codeänderungen werden alle Unit-Tests des geänderten Files in einer Konfiguration ausgeführt, bevor die Änderung in die Code-Basis eingecheckt wird. Integrations-Tests werden sporadisch, z.B. einmal pro Woche, ausgeführt und Systemtests z.B. nur alle zwei Monate. Das hat zur Folge, dass Fehler, die im Systemtest auffallen, ihre Ursache in einer Codeänderung haben, die eventuell vor zwei Monaten eingecheckt wurde. Neben dem zusätzlichen Aufwand, der dadurch entsteht, dass zunächst der Verursacher des Fehlers eruiert werden muss, benötigt dieser dann mehr Zeit, den Fehler zu korrigieren, als wenn er direkt am Tage der Codeänderung auf das Problem aufmerksam gemacht worden wäre.

Ziel muss es also sein, dass jede Codeänderung möglichst zeitnah überprüft wird. Und zwar in allen Konfigurationen und in allen Test-Ebenen (Unit-, Integration-, System-Test). Um diesem Ziel näher zu kommen, kann die Test-Landschaft zunächst einmal dahingehend optimiert werden, dass das Ausführen von Tests parallelisiert wird. Automatisierbare Tests können dann durch die Bereitstellung einer entsprechenden Anzahl von Test-Servern in sehr viel kürzeren Zeitabschnitten durchlaufen werden. Manuelle Tests gilt es soweit wie möglich zu reduzieren. Es ist tatsächlich nicht vertretbar, gleiche Tests in 300 verschiedenen Konfigurationen manuell durchzuführen, wenn dies auch automatisiert möglich wäre.

Neben einer Parallelisierung der Testaktivitäten kann die Testausführungsdauer zusätzlich durch eine intelligente Auswahl der Testfälle drastisch reduziert werden. Zunächst einmal ist es offensichtlich, dass von einer Source-Code-Änderung nur Testumgebungen betroffen sind, in denen das geänderte File vorhanden ist. Durch eine intelligente Auswahl (siehe Abb. 3, PDF) kann die Menge an durchzuführenden Tests aber auch dadurch reduziert werden, dass nur die Testfälle innerhalb der betroffenen Testumgebungen erneut ausgeführt werden, die von der Source-Code-Änderung betroffen sind. Insbesondere im Systemtest, der dadurch, dass üblicherweise alle Files zusammen getestet werden und der somit von jeder Codeänderung betroffen ist, kann durch eine intelligente Testfall-Auswahl ein erheblicher Aufwand eingespart werden.

Configuration Management und Continuous Integration

Professionelle SW-Entwicklung arbeitet heute mit einem zentralen Configuration Management der Software. Zentral wird zum Beispiel auf einem Build Server eine Basisversion der Software gehalten. Entwickler können lokale Kopien der Basis erstellen, lokal Änderungen am Code durchführen und diese dann wieder in die Basis einchecken. Das zentrale Management der Software hat verschiedene Vorteile (siehe Abb. 4, PDF):

  • Entwickler ändern in der lokalen Kopie des Codes, nicht in der Basis direkt
  • Änderungsverfolgung: Wer hat wann was geändert?
  • Versions-Management der Basis-SW: Gib mir den SW-Stand vom 1.4.2016


Probleme können dann entstehen, wenn das Einchecken der lokalen Kopien in zu großen Abständen erfolgt. Dies hat oft zur Folge, dass auch der Test der Codeänderungen erst sehr spät erfolgt, denn üblicherweise ist ein Software-Entwickler nicht in der Lage, alle relevanten Testfälle ausführen zu können. Darüber hinaus wird durch das verzögerte "Mergen" mit der Basis die Wahrscheinlichkeit eines Merge-Konflikts oder sogar einer Inkompatibilität des einzucheckenden Codes größer. Eine optimierte Software-Entwicklung sollte daher ...

  • ... jeden am Entwicklungsprozess Beteiligten in die Lage versetzen, alle (relevanten) Tests auszuführen
  • ... Merge-Zyklen der lokalen Kopien mit der Basis möglichst kurz halten


Das Ziel muss es sein, die Basis-SW kontinuierlich in einem lauffähigen Zustand zu halten. Jede Codeänderung erfordert üblicherweise auch eine Anpassung der Testfall-Daten, sodass diese im Zuge der Codeänderung mit geändert und eingecheckt werden sollten.

Messen, Bewerten, Verbessern

Ein nicht zu unterschätzender Aspekt bei der Verbesserung eines Prozesses ist das Messen des Ist-Zustands. Leider wird dieses Messen allzuoft auch mit einem Kontrollieren der beteiligten Personen gleichgesetzt und daher häufig abgelehnt. Auch werden Metriken gerne als "Manager-Spielzeug ohne Mehrwert" abgetan. Aber tatsächlich können Metriken auf allen Ebenen dabei helfen, Prozesse zu verbessern oder Abläufe zu optimieren. Zielsetzung der Bereitstellung von Metriken sollte also immer sein, jedem Mitarbeiter transparent die Zahlen zugänglich und deren Nutzen plausibel zu machen.

Auch die Automobilindustrie misst der Bedeutung von Metriken eine immer größere Bedeutung zu. So hat der Arbeitskreis Softwaretest der Herstellerinitiative Software (HIS, bestehend aus den Automobilherstellern Audi, BMW Group, DaimlerChrysler, Porsche und Volkswagen) eine Empfehlung von relevanten Metriken (HIS-Metriken) inklusiver akzeptabler Obergrenzen der jeweiligen Werte herausgegeben[4].

Betrachten wir zunächst relevante Messdaten im SW-Entwicklungs- und Testprozess:

In Bezug auf den Quellcode:

  • Anzahl der Files
  • Anzahl der Funktionen
  • Anzahl der Codezeilen
  • Kommentar-Dichte
  • Compiler Warnings
  • Compiler Error
  • Zyklomatische Komplexität
  • Anzahl Funktionsaufrufe:
  • Wie oft wird eine Funktion aufgerufen?
  • Wie viele Funktionsaufrufe innerhalb einer Funktion?
  • Anzahl der Funktionsparameter
  • Sprachumfang (Anzahl Operatoren und Operanden)

Statische Code-Analyse:

  • Warnings
  • Errors

In Bezug auf dynamische Testfälle:

  • Auf allen Ebenen (Unit-, Integration-, System-Test)
  • Anzahl insgesamt
  • Anzahl durchgeführt
  • PASS/FAIL
  • Laufzeiten

Code Coverage:

  • Statement
  • Branch
  • Condition
  • MC/DC
  • function
  • function call
  • basis path

In Bezug auf Requirements:

  • Requirements/Testfall Coverage
  • Anzahl Testfall je Requirement

In Bezug auf Codeänderungen:

  • Anzahl der geänderten/hinzugefügten/gelöschten Codezeilen
  • Trends

 

Fragen, die diese Metriken beantworten sollen, sind zum Beispiel:

  • Wie gut ist die Software-Qualität?
  • Ist meine SW "ready-to-release"?
  • Wie groß ist das Risiko eines Fehlers im Code?
  • Wie viele Tests wurden durchgeführt und wie viele Tests müssen noch durchgeführt werden?
    Wie lange wird das dauern?
  • Wo muss mehr Testaufwand betrieben werden?
  • Change Impact Analyse: Welche Testfälle sind von einer Codeänderung betroffen?
    Wie lange dauert deren Ausführung?

Beispiele für Darstellungen von Metriken

Die Kunst bei der Darstellung von Metriken ist es, die Zahlen in einer wahrnehmbaren Art zu präsentieren, ohne dabei Problemstellen im statistischen Rauschen untergehen zu lassen. So ist z.B. eine durchschnittliche zyklomatische Komplexität von 3,5 je Funktion ein guter Wert. Insgesamt ist aber vielleicht der eine Ausreißer mit einem Wert von 158.

Um wirklich für jeden Entwicklungsprozess interessante Informationen zu liefern, ist es wichtig, die Metriken interaktiv zu präsentieren. D.h., der Benutzer muss in die Lage versetzt werden, die Daten angezeigt zu bekommen, die für ihn relevant sind. Außerdem sollte es möglich sein, in einzelne Bereiche der SW tiefer hineinzublicken bzw. die Sicht mehr zu globalisieren.

Abbildung 5 (siehe PDF) zeigt ein Beispiel für die Darstellung von Metriken mit sowohl Durchschnittswerten als auch Ausreißern.

Eine zusätzliche Dimension lässt sich in der Darstellung von Metriken durch die Verwendung von Farben erzielen. Der Mehrwert wird deutlich bei der Betrachtung von Abbildung 6 (siehe PDF), in der Code Coverage, also der Anteil des Quellcodes, der in dynamischen Softwaretests ausgeführt wurde, farblich dargestellt ist. Die Größe des Blicks gibt einen Hinweis auf die Codegröße (auf der linken Seite) bzw. die Komplexität des Codes (rechte Seite). In diesem Beispiel befindet sich ein großer roter Block oben links. Der Block repräsentiert die Datei lvm.c, die nicht nur groß (im Sinne von "viele Statements"), sondern auch komplex und noch dazu schlecht getestet ist. Ein Hinweis für Tester, Test-Manager oder Projekt-Manager, dass noch ein gutes Stück Arbeit vor ihnen liegt.

Die zyklomatische Komplexität der Software ist ein nicht zu unterschätzender Wert, der eine nähere Betrachtung lohnt. In der Luft- und Raumfahrt wird von den Zertifizierungsbehörden zum Beispiel eine Obergrenze von 10 festgelegt. Ebenso empfiehlt der HIS AK Softwaretest eine Obergrenze von 10[4]. Tatsächlich zeigen Erfahrungsberichte[3], dass die Anzahl von "Abweichungen" (unter einer Abweichung versteht man alles, was nach einem Review zu einer Änderung des Codes geführt hat, wie z.B. Typos, Bugs, fehlende Kommentare, Verstöße gegen Coding Conventions ...) im Code mit der zyklomatischen Komplexität steigt. Funktionen mit einer zyklomatischen Komplexität > 20 sollten generell vermieden werden, da diese sehr fehleranfällig und schlecht wartbar sind.

Abbildung 7 (siehe PDF) zeigt ein Beispiel einer Darstellung des Risikos eines Fehlers im Code, wie es sich aus der zyklomatischen Komplexität der implementierten Funktionen ergibt. Sie gibt Antworten auf die Fragen, wie groß der Anteil an sehr komplexen und damit fehlerträchtigen Funktionen ist und wie gut diese getestet sind.

Als letztes Beispiel einer Information, die sich aus der Kombination bestehender Metriken ableiten lässt, soll noch der Change Impact Report, wie in Abbildung 8 (siehe PDF) dargestellt, erwähnt werden. Dieser ergibt sich aus dem Bewerten von Codeänderungen, Code Coverage und Testfalldaten. Wenn man weiß, welche Testfälle von Codeänderungne betroffen sind, kann man den Aufwand abschätzen, den es bedeuten wird, eine Fehlerbeseitigung oder ein neues Release zu testen.

Konklusion

Durch die zunehmende Bedeutung von Software in allen Industriezweigen ergibt sich eine zunehmende Softwarekomplexität. Metriken können dabei helfen, diese Komplexität zu beherrschen und Testaufwände durch änderungsbasiertes Testen zu verringern. Viele der Kennzahlen, auf die ich in diesem Beitrag eingegangen bin, liegen Ihnen vielleicht schon vor oder sie sind durch geringe Aufwände zu erhalten. Zum Dank liefern die Metriken Antworten auf einige Fragen, die allen am Prozess Beteiligten helfen, effizienter zu arbeiten, die Anzahl der Software-Fehler im Produkt zu minimieren und die Software qualitativ hochwertig und wartbar zu halten.

Bei allen Arten von Messen und Bewerten muss aber auch immer darauf geachtet werden, dass das Erstellen von bunten Bildern nicht zum Selbstzweck ausartet. Außerdem sollten alle beteiligten Personen mit in den Bewertungsprozess einbezogen werden, um den Beigeschmack der Kontrolle bzw. der Mitarbeiterbeurteilung zu vermeiden.

Schließlich sollte bei aller Messerei und Bewerterei auch der gesunde Menschenverstand nicht ausgeschaltet werden. Feste Obergrenzen für einzelne Messwerte, wie z.B. die zyklomatische Komplexität einzuhalten, scheint zwar sinnvoll; der Prozess muss aber immer auch die Ausnahme von der Regel erlauben.

Richtig eingesetzt, können Metriken dann am Ende helfen, Produkt-Release-Zyklen zu verringern und gleichzeitig die Produktqualität zu optimieren, was schließlich im Interesse aller ist: Manager, Mitarbeiter und Kunden.

Abkürzungen

Abb

AK

CI

FDA

HIS

HW

MC/DC

RTOS

SW

vgl

z.B.

 

Abbildung

Arbeitskreis

Continuous Integration

Food and Drug Administration

Herstellerinitiative Software

Hardware

Modified Condition/Decision Coverage

Real Time Operating System

Software

vergleiche

zum Beispiel

Referenzen

[1] General Principles of Software Validation; Final Guidance for Industry and FDA Staff, FDA, 2002
[2] James Martin, An Information Systems Manifesto, Prentice-Hall, Inc., Englewood Cliffs, New Jersey
[3] softwaretesting.vectorcast.com/acton/formfd/10305/0018:d-009d
[4] HIS Source Code Metriken des HIS AK Softwaretest

 

Beitrag als PDF downloaden

 


Test, Qualität & Debug - unsere Trainings & Coachings

Wollen Sie sich auf den aktuellen Stand der Technik bringen?

Dann informieren Sie sich hier zu Schulungen/ Seminaren/ Trainings/ Workshops und individuellen Coachings von MircoConsult zum Thema Test, Qualität & Debug.

 

Training & Coaching zu den weiteren Themen unseren Portfolios finden Sie hier.


Test, Qualität & Debug -Fachwissen

Wertvolles Fachwissen zum Thema Test, Qualität & Debug steht hier für Sie zum kostenfreien Download bereit.

Zu den Fachinformationen

 
Fachwissen zu weiteren Themen unseren Portfolios finden Sie hier.