17. Okt 2022
Lesedauer 11 Min.
Der Universaltester
Testen mit PowerShell und Pester
Mit der Version 5 bietet Pester nun neben einem neuen Discovery-Konzept auch Verbesserungen beim Mocking.

Das automatisierte Testen ist in der agilen Softwareentwicklung unerlässlich, um eine kontinuierliche Produktivität gewährleisten zu können. Pester ist ein Test-Runner für die PowerShell und hat sich im Lauf der Jahre zum Quasi-Standard für das Testen von und mit PowerShell-Code entwickelt.Häufig wird Pester im Zusammenhang mit dem Prinzip des Behavior Driven Development (BDD) erwähnt, was den Eindruck vermittelt, dass eine Verwendung die Umsetzung dieser Methodik voraussetzt. Damit würde man aber die Vielseitigkeit der möglichen Anwendungsbereiche einschränken.Pester eignet sich sowohl für das Testen von Legacy-Anwendungen, die bisher möglicherweise ohne automatisierte Tests auskamen, als auch zum Testen von bereitgestellter Infrastruktur. Denkbar sind auch automatisierte Tests im Rahmen von regelmäßigen Audits und nicht zuletzt in klassischen .NET-Anwendungen. Pester-Tests sind für alle Level des Software-Testing wie Unit-Tests, Integrationstests, System- und Akzeptanz-Tests einsetzbar.
Geschichtliches
Pester ist als Open-Source-Projekt bei GitHub gehostet [1]. Ursprünglich wurde das Projekt von Scott Muc 2011 ins Leben gerufen, der sich jedoch nach den ersten Erfolgen aus persönlichen Gründen aus dem Projekt zurückgezogen hat.Die Ownership ging an Jakub Jareš über, der nahezu seit Beginn an intensiv an dem Projekt mitgearbeitet hat [2]. Jakub Jareš betreut das Projekt neben seiner Tätigkeit bei Microsoft als Entwickler für vstest und MSTest. Die sehr gute Dokumentation findet man unter [3].Installation
Die Bereitstellung erfolgt als PowerShell-Modul, das über die PowerShell Gallery [4] installiert werden kann. Auf Windows 10 und Windows Server 2016 ist Pester 3.40 vorinstalliert. Diese Version ist aber veraltet und sollte nicht mehr verwendet werden, beziehungsweise die in diesem Artikel vorgestellte Syntax funktioniert darin nicht. Selten ist es notwendig, die vorinstallierte Version zu entfernen. Die neue Version wird parallel installiert. Eine Anleitung findet man in der Pester-Dokumentation. Um Pester zu aktualisieren oder die neueste Version auf anderen Plattformen zu installieren, gibt man auf einer PowerShell-Konsole den folgenden Befehl ein:<span class="hljs-keyword">Install</span>-<span class="hljs-keyword">Module</span> Pester
Gegebenenfalls sind weitere Parameter wie -Force nötig, um Warnungen zu unterdrücken, und/oder -SkipPublisherCheck. Alternativ kann man das Package auch über GitHub herunterladen und per Copy/Paste-Deployment als PowerShell-Modul direkt verwenden. PowerShell als Open-Source-Projekt ist ebenfalls mit Pester getestet [5].Sollten Sie die Fehlermeldung .ps1 is not digitally signed. The script will not execute on the system erhalten, so hilft für diese PowerShell-Session der Fix unter [6] weiter.Pester zusammen mit PowerShell Core (das seit Version 7.x nur noch PowerShell heißt) ist plattformunabhängig. Daher können Tests sowohl auf Windows als auch unter iOS, Linux, Docker und so weiter ausgeführt werden.
Erste Schritte
Pester bietet ein Test-Framework, das konzeptionell an die Arbeitsweise von bekannten Test-Frameworks für Visual Studio angelehnt ist – wie zum Beispiel xUnit oder NUnit. Am besten geht man so vor, dass man sich die Schritte überlegt, die nötig sind, wenn man manuell testen würde, und diese aufschreibt. Dann überlegen Sie sich, welche Fehler möglich sind beziehungsweise was das erwartete Verhalten ist. Damit haben Sie schon ein Test-Set, welches Sie automatisieren können.Es gibt verschiedene Möglichkeiten, Module und Layer einer Software anzusprechen. Angefangen bei der Datenbank, die über die PowerShell und entsprechende Module abgefragt und manipuliert werden kann, über klassische Web APIs zum Beispiel per Invoke-WebRequest, oder indem man die eigene Software insoweit testbar macht, dass Funktionalitäten als Commandlets bereitgestellt werden.Letztendlich kann man alles ansteuern, was mit der PowerShell selbst oder den diversen verfügbaren Modulen angesprochen werden kann. Nicht zuletzt ist auch bereitgestellte Infrastruktur über Module und Commandlets testbar. Wenn Sie sich in der PowerShell befinden und einen beliebigen Befehl eingeben und ein Ergebnis erhalten, dann können Sie dies in Pester testen. Nicht zuletzt schafft man sich durch automatisierte Tests ein Sicherheitsnetz, indem Feedback-Schleifen beschleunigt werden.Grundlagen und Arbeitsweise
Pester arbeitet mit einer domänenspezifischen Testsprache (DSL) zum Isolieren, Ausführen, Auswerten und Ermitteln der Ergebnisse. Für einen ersten vollständigen Test benötigt man drei Funktionen: Describe, It und Should. Ein minimaler Test sieht wie folgt aus:<span class="hljs-keyword">Describe</span> <span class="hljs-string">"Replace-Hashtag"</span> {
It <span class="hljs-string">"replaces _ with -"</span> {
<span class="hljs-string">"a_b"</span>.<span class="hljs-keyword">Replace</span>(<span class="hljs-string">"_"</span>, <span class="hljs-string">"-"</span>) | Should -Be <span class="hljs-string">"a-b"</span>
}
}
Should wirft eine Exception, wenn das erwartete Ergebnis nicht mit dem aktuellen Ergebnis übereinstimmt. Meistens wird Should zusammen mit -Be verwendet, was eine Prüfung auf Gleichheit bedeutet, die jedoch nicht case sensitive ist. Sind die Objekte nicht in diesem Sinne gleich, wird eine Exception geworfen. Im Beispiel bedeutet das, dass das aktuelle Ergebnis auf der linken Seite dem erwarteten Ergebnis auf der rechten entspricht und der Test positiv ist. Der Test wäre auch dann noch positiv, wenn die Groß-/Kleinschreibung nicht übereinstimmen würde. Um den Test case sensitive auszuführen, müsste -BeExactly verwendet werden. Neben -Be und -BeExactly gibt es viele weitere dokumentierte Assertions.Intern wird eine Funktion mit dem erwarteten und dem aktuell ermittelten Ergebnis als Eingabeparameter aufgerufen. Wenn der gewünschte Vergleich – hier equal – nicht zutrifft, wirft die Funktion eine Exception. Vereinfacht sieht der Code wie folgt aus:
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Should</span>-<span class="hljs-title">Be</span> <span class="hljs-params">($Expected, $Actual)</span> </span>{
<span class="hljs-keyword">if</span> ($Expected -ne $Actual) {
<span class="hljs-keyword">throw</span> [<span class="hljs-keyword">Exception</span>] `
<span class="hljs-string">"Expected '$Expected' but got '$Actual'."</span>
}
}
Umschlossen wird Should mit einem It-Block. Im Rahmen des AAA-Pattern (Arrange – Act – Assert) ist der It-Block das Assert, also der eigentliche Test. Die Beschreibung des It-Blocks sollte die Erwartung an den Test deutlich machen. Intern wird eine Funktion aufgerufen, die den Beschreibungstext für den Test und den ScriptBlock entgegennimmt. Dann wird der ScriptBlock ausgeführt.Läuft dieser ohne Fehler durch, gibt Pester eine positive Meldung aus. Wird eine Exception geworfen, meldet Pester das mit einer negativen Meldung. Vereinfacht sieht der Code wie folgt aus:
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">It</span> <span class="hljs-params">($Name, [ScriptBlock] $Test)</span> </span>{
<span class="hljs-keyword">try</span> {
$null = & $Test
Write-Host -Foreground Green [+] $Name
}
<span class="hljs-keyword">catch</span> {
Write-Host -Foreground Red [-] $Name
}
}
Der It-Block muss wiederum mindestens von einem Describe-Block umschlossen sein. Alternativ kann hier auch Context verwendet werden, jedoch ist Describe üblicher. Describe und Context sind reine Strukturierungselemente. Intern wird der Beschreibungstext für Describe (oder Context) und der ScriptBlock entgegengenommen. Dann gibt Pester den Beschreibungstext aus und führt den ScriptBlock aus. Vereinfacht sieht der Code wie folgt aus:
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Describe</span> <span class="hljs-params">($Name, [ScriptBlock] $Code)</span> </span>{
Write-Host $Name
$null = & $Code
}
Before* und After* sind Blöcke, um allgemeine Arbeiten vor und nach Tests auszuführen. Sie sind also klassische Setups und Teardowns, um zum Beispiel das SUT (subject under test) bereitzustellen. Dabei können BeforeAll und AfterAll auf mehreren Ebenen ausgeführt werden.Der Unterschied zu BeforeEach und AfterEach ist, dass diese vor und nach jedem It-Block, also vor und nach jedem Test, ausgeführt werden. Weiterhin gibt es ein BeforeDiscovery. Typischerweise werden in den Before*-Blöcken die zu testenden Funktionen importiert oder das SUT bereitgestellt, sowie Mocks definiert und Testdaten generiert. Bei Bedarf räumen die After*-Blöcke wieder auf.Pester führt After* auch aus, wenn Tests fehlschlagen. Lokale Variablen, die in Before* und After* definiert werden, werden an alle Child-Blöcke übergeben und nach der Ausführung wieder zurückgesetzt.
Discovery und Run
Pester-Tests laufen grundsätzlich in zwei Phasen ab: Discovery und Run. In der Discovery-Phase durchsucht Pester die Test-Files nach den vorher beschriebenen Blöcken wie Describe, Context, It und so weiter. Um bereits Skript-Blöcke während der Discovery-Phase ausführen zu können, zum Beispiel um variable Werte für Beschreibungstexte oder Daten für datengetriebene Tests bereitzustellen, kann man das in dem sogenannten BeforeDiscovery-Block tun. Wichtig ist, dass Test-Code nur in It, BeforeAll, BeforeEach, AfterAll und AfterEach ausgeführt wird. Falsch eingefügter Code wird während der Discovery-Phase nicht berücksichtigt und kommt beim Run nicht zur Ausführung.Am Ende der Discovery-Phase stehen alle Tests, Setups und Teardowns mit den jeweiligen Skript-Blöcken in einer internen Datenstruktur. Bei der Run-Phase übergibt Pester diese Datenstruktur dem Runner. Dabei wird jeder Test in einem neuen Scope ausgeführt. Hat der Runner alle Tests abgearbeitet, gibt er das Ergebnis aus.Kompatibilität der Version 4 zu Version 5
Das Zwei-Phasen-Konzept mit Discovery und Run ist neu in Version 5. In Version 4 gab es noch einen reinen Top-Down-Ansatz. Es konnte also an allen Stellen weiterer PowerShell-Code ergänzt werden. Das hat die Nachvollziehbarkeit der Ausführung jedoch nicht unbedingt erleichtert.Durch die Verbesserung der datengetriebenen Tests in Version 5 sind die meisten Workarounds obsolet geworden. Die weit verbreitete Methode, generische Tests in einer For-Each-Schleife auszuführen, wurde in Version 5 durch einen -ForEach-Parameter im Describe- oder Context-Block abgelöst.Mocking
Ein weiteres Schlüsselwort ist Mock. Mit Mock können Abhängigkeiten von PowerShell-Befehlen oder sogar nativen Anwendungen mit eigenen Funktionalitäten ersetzt werden. Pester bietet eine Reihe von Mocking-Funktionen, die es einfach machen, Abhängigkeiten vorzutäuschen und auch das Verhalten zu überprüfen. Mit den von Pester bereitgestellten Mocking-Funktionen kann man:- das Verhalten von PowerShell-Befehlen mocken,
- überprüfen, ob bestimmte PowerShell-Befehle aufgerufen wurden (oder auch nicht),
- überprüfen, wie oft ein PowerShell-Befehl mit einem bestimmten Parameter-Set aufgerufen wurde.
Listing 1: Beispiel für Mocking von Write-Host
BeforeDiscovery {<br/> <span class="hljs-variable">$prefix</span> = <span class="hljs-string">"&gt;&gt;&gt;"</span><br/>}<br/><br/>Describe <span class="hljs-string">"Mocking Write-Host"</span> {<br/> BeforeAll{<br/> Mock <span class="hljs-built_in">Write-Host</span> { <span class="hljs-keyword">throw</span> <span class="hljs-string">"Use Mock!"</span> }<br/> }<br/> It <span class="hljs-string">"$(<span class="hljs-variable">$prefix</span>)Throws exception"</span> {<br/> { <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"Something happens"</span> } | Should -Throw<br/> }<br/> Context <span class="hljs-string">"Overriding Mock and test"</span> {<br/> BeforeAll {<br/> Mock <span class="hljs-built_in">Write-Host</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">"mocked Write-Host"</span> } <br/> -Verifiable <br/> -ParameterFilter { <span class="hljs-variable">$Object</span> <span class="hljs-nomarkup">-eq</span> <span class="hljs-string">"XXX"</span> }<br/> }<br/> It <span class="hljs-string">"$(<span class="hljs-variable">$prefix</span>)All mocks are invoked"</span> {<br/> <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"XXX"</span><br/> Should -InvokeVerifiable<br/> }<br/> It <span class="hljs-string">"$(<span class="hljs-variable">$prefix</span>)Returns 'mocked Write-Host'"</span> {<br/> <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"XXX"</span> | <br/> Should -Be <span class="hljs-string">"mocked Write-Host"</span><br/> }<br/> It <span class="hljs-string">"$(<span class="hljs-variable">$prefix</span>)Write-Host invoked with parameter"</span> {<br/> <span class="hljs-built_in">Write-Host</span> <span class="hljs-string">"XXX"</span><br/> Should -Invoke <br/> -CommandName <span class="hljs-built_in">Write-Host</span> <br/> -Times <span class="hljs-number">1</span> <br/> -ParameterFilter { <span class="hljs-variable">$Object</span> <span class="hljs-nomarkup">-eq</span> <span class="hljs-string">"XXX"</span> }<br/> }<br/> }<br/>}
Im BeforeAll von Context “Overriding Mock and test“wird zunächst der Mock überschrieben und anschließend getestet. It “$($prefix)All mocks are invoked“ testet, ob nach einem Aufruf von Write-Host auch alle definierten Mocks aufgerufen wurden (hier nur einer). In It “$($prefix)Returns ‘Invoke mocked Write-Host‘“ wird getestet, ob Write-Host wirklich den Rückgabewert “mocked Write-Host“ liefert (in Wirklichkeit hat Write-Host bekanntlich keinen Rückgabewert). Schließlich prüft It “$($prefix)Write-Host invoked with parameter“, ob das Kommando Write-Host mit dem Parameter XXX genau einmal aufgerufen wurde.Obwohl dies in den vorangegangenen Tests schon zweimal der Fall war, zählt hier nur der Aufruf im aktuellen It-Block, da Pester für jeden Block einen neuen Scope erzeugt. Schließlich ist BeforeDiscovery zu erwähnen, in welchem der Prefix für die It-Blöcke in eine Variable geschrieben wird. Da die Beschreibungstexte während der Discovery-Phase erzeugt werden, muss die Variable hier gesetzt werden. Der Output für die erfolgreichen Tests ist in Bild 1 dargestellt. Bild 2 zeigt die Ausgabe mit einem fehlgeschlagenen Test (Write-Host wurde im It nicht aufgerufen).

Konsolenausgabe für mocked Write-Host:Alle Tests wurden erfolgreich durchgeführt(Bild 1)
Autor

Konsolenausgabe für mocked Write-Host:Ein Test ist fehlgeschlagen(Bild 2)
Autor
Ausführung von Pester-Tests
Pester führt Discovery und Run auf Dateien aus, die der Namenskonvention *.Tests.ps1 entsprechen. Entweder man weist Visual Studio Code mit [F5] an, eine einzelne Datei zu starten, oder man macht das über den Befehl Invoke-Pester auf der Konsole. Invoke-Pester ohne weitere Parametereingabe führt alle Dateien im aktuellen Verzeichnis sowie den Unterverzeichnissen aus, die der Konvention entsprechen. Invoke-Pester bietet jedoch auch eine Vielzahl an Parametereinstellungen, wovon die wichtigsten in Listing 2 beispielhaft genannt und im Folgenden beschrieben werden.Listing 2: Beispiel für Parametrisierung von Invoke-Pester
<span class="hljs-variable">$configuration</span> = New-PesterConfiguration<br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.Run</span><span class="hljs-selector-class">.Path</span> = <span class="hljs-variable">$PSScriptRoot</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.Filter</span><span class="hljs-selector-class">.Tag</span> = <span class="hljs-string">"UnitTest"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.Filter</span><span class="hljs-selector-class">.ExcludeTag</span> = <span class="hljs-string">"AcceptanceTest"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.CodeCoverage</span><span class="hljs-selector-class">.Enabled</span> = <span class="hljs-variable">$true</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.CodeCoverage</span><span class="hljs-selector-class">.OutputFormat</span> = <span class="hljs-string">"JaCoCo"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.CodeCoverage</span><span class="hljs-selector-class">.OutputPath</span> = <span class="hljs-string">"$PSScriptRoot\results\pester-coverage.xml"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.Output</span><span class="hljs-selector-class">.Verbosity</span> = <span class="hljs-string">"Detailed"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.Output</span><span class="hljs-selector-class">.StackTraceVerbosity</span> = <span class="hljs-string">"Full"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.TestResult</span><span class="hljs-selector-class">.Enabled</span> = <span class="hljs-variable">$true</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.TestResult</span><span class="hljs-selector-class">.OutputFormat</span> = <span class="hljs-string">"NUnitXml"</span><br/><span class="hljs-variable">$configuration</span><span class="hljs-selector-class">.TestResult</span><span class="hljs-selector-class">.OutputPath</span> = <span class="hljs-string">"$PSScriptRoot\results\test-pester.xml"</span><br/><br/>Invoke-Pester -Configuration <span class="hljs-variable">$configuration</span>
Run.Path gibt an, für welches Verzeichnis Tests gesucht werden sollen. Für Describe, Context und It können Sie Tags angeben, die über Filter.Tag und Filter.ExcludeTag ein- oder ausgeschlossen werden können. Es können zwei Arten von Result-Dateien geschrieben werden: einmal für die Code Coverage, und dann für die Testergebnisse. Diese Ausgaben lassen sich aktivieren oder deaktivieren, und man kann OutputPath und OutputFormat setzen. Schließlich lässt sich noch die Verbosity für die Ausgaben setzen.Wenn der Output in eine Datei geschrieben wird, stehen als Ausgabeformate NunitXml und JUnit Xml zur Verfügung.Diese Formate können über Standardverfahren automatisiert ausgewertet werden. Ein Beispiel hierfür ist die Ausführung von Pester-Tests durch eine Azure-DevOps-Pipeline. Es gibt mehrere Möglichkeiten, Pester in die Azure-DevOps-Pipeline zu integrieren. Zum einen kann man eine Extension aus dem Azure-DevOps-Marketplace installieren, oder man verwendet ein eigenes PowerShell-Skript. Letzteres bietet mehr Flexibilität und bessere Kontrolle (Bild 3).

Beispiel einer Azure-DevOps-Pipelinemit Testausführung über eigenes PowerShell-Skript(Bild 3)
Autor
Anwendungsbereiche
Betrachtet man die unterschiedlichen Bereiche des Testens, dann kann Pester überall verwendet werden, wo man über die PowerShell Funktionen ansprechen kann.Unit-Tests sind White-Box-Tests. Mit Pester eignen sie sich nur für Code, der in der PowerShell entwickelt wurde. Das reicht von einzelnen PowerShell-Funktionen bis hin zu ganzen PowerShell-Skript-Modulen und Commandlets. Unit-Tests für C#-Code werden weiterhin mit den bewährten Tools wie xUnit und NUnit gebaut und ausgeführt. Haben Sie allerdings aus C#-Code eine Komponente erzeugt und wollen Sie diese im Black-Box-Verfahren testen, können Sie das mit Pester erledigen.Mit der PowerShell lassen sich zunächst einzelne Komponenten konfigurieren oder aber auch eine vollständige Infrastruktur bereitstellen. Dann werden Komponententests auf der bereitgestellten Umgebung ausgeführt, und man erhält so eine Absicherung der technologischen Anforderungen.Neben dem Testen der Technologie benötigt ein agiles Team auch Tests, die fachlich getrieben sind. In einem agilen Prozess kommen die Anforderungen meist von einer Fachabteilung, die dann in einer User Story aus Sicht des Anwenders beschrieben sind. Diese Anforderungen beschreiben auch oft einen Workflow, der einen Anfangszustand hat und wo mit jedem Workflow-Schritt der Zustand verändert wird. Mit Pester können diese Workflows zunächst einmal textuell beschrieben werden.Im Dialog zwischen den Anforderern, den Testern und den Entwicklern werden zugehörige Tests geschrieben, die gewünschtes und unerwünschtes Verhalten der Software testen. Anschließend wird die zugehörige Funktionalität entwickelt. Man spricht hier auch von Behavior Driven Development (BDD). Damit kann man eine gute Abdeckung mit funktionalen Tests erreichen beziehungsweise kann gegebenenfalls sogar User-Acceptance-Tests mit Pester automatisieren, wenn der Kunde entsprechend einbezogen werden kann.Ein weiterer wichtiger Anwendungsbereich von Pester sind Audits. Denkbar sind hier zum Beispiel der Einsatz für eine regelmäßige Überprüfung, ob das Systemlaufwerk noch ausreichend Speicherplatz hat, ob Firewall-Regeln korrekt eingestellt sind, oder auch als umfangreiches Reporting für Prüfer sowie als Nachweis der Einhaltung von Compliance-Anforderungen an Infrastruktur in der Cloud oder On-Premise.Im Infrastrukturbereich ist die PowerShell sehr weit verbreitet. Sie kann sowohl interaktiv auf der Konsole als auch zum Skripten verwendet werden. Als Skriptsprache wird die PowerShell häufig zur Automatisierung der Verwaltung von Systemen genutzt. Sie kommt auch zum Erstellen, Testen und Bereitstellen von Lösungen zum Einsatz, häufig in CI/CD-Umgebungen. PowerShell basiert auf der .NET Common Language Runtime (CLR). Alle Ein- und Ausgaben sind .NET-Objekte. Dieser Umstand erlaubt einen Zugriff auf .NET-Klassen beziehungsweise .NET-Assemblies. Beispiel:Add-Type -AssemblyName System<span class="hljs-selector-class">.ServiceProcess</span>
[System<span class="hljs-selector-class">.ServiceProcess</span><span class="hljs-selector-class">.ServiceController</span>[]]<span class="hljs-variable">$sc</span> =
[System<span class="hljs-selector-class">.ServiceProcess</span><span class="hljs-selector-class">.ServiceController</span>]::GetDevices(
<span class="hljs-string">'localhost'</span>)
Es gibt für nahezu alle Anwendungsbereiche PowerShell-Module, die vorhandene Frameworks und Anwendungen wrappen – ob nun für den Zugriff auf eine Microsoft-SQL-Datenbank oder PostgreSQL. Es gibt Wrapper für Selenium oder für den Zugriff auf REST-APIs. Zunächst sollte man in der PowerShell Gallery [4] nach einem geeigneten Modul für ein aktuelles Problem suchen. Da die Bereitstellung von Modulen einfach ist, sollte man sich auch nicht scheuen, in Open-Source-Projekten nach Lösungen zu suchen. Möchte man eigene Software direkt testbar entwickeln, bietet sich die Programmierung eines eigenen Wrappers in Form eines PowerShell-Moduls an. Man spricht hier auch von einem PowerShell Binary Module. Die Vorgehensweise ist in der Microsoft-Dokumentation [7] beschrieben beziehungsweise in Bild 4 rudimentär dargestellt.

Beispiel für die Entwicklungvon Binary Commandlets in Visual Studio(Bild 4)
Autor
Fazit
Automatisiertes Testen mit PowerShell und Pester verkürzt Feedbackzyklen und schafft Sicherheit bei der Anpassung von Funktionalitäten und Änderungen an Konfigurationen. Durch die Möglichkeit, Beschreibungstexte in Anwendersprache zu schreiben, und die dadurch leichtere Lesbarkeit für Kunden und Fachabteilungen wird Transparenz für alle Projektbeteiligten geschaffen. Damit wird die Zusammenarbeit gefördert und Nachvollziehbarkeit verbessert.Fussnoten
- Pester auf GitHub, http://www.dotnetpro.de/SL2211Pester1
- Die Story hinter Pester, http://www.dotnetpro.de/SL2211Pester2
- Pester-Homepage, https://pester.dev
- PowerShell Gallery, http://www.powershellgallery.com
- PowerShell, http://www.dotnetpro.de/SL2211Pester3
- Fix for PowerShell Script Not Digitally Signed, http://www.dotnetpro.de/SL2211Pester4
- PowerShell Binary Module, http://www.dotnetpro.de/SL2211Pester5