Einführung in Pester – Part 1

Inhaltsverzeichnis

Post Featured Image

Code-Review und Software-Unit-Tests sind nicht die beliebtesten Aufgaben bei der Code-Entwicklung, und auch PowerShell-DevOps bleiben davon nicht verschont. Dennoch ist es beim Schreiben einer Funktion oder eines Scripts zur Ausführung einer bestimmten Aufgabe wichtig zu wissen, ob das Script das tut, was es tun soll.

Mit dem Pester-Framework zum Testen und Mocking für PowerShell wird diese Aufgabe weniger zeitaufwändig und lästig. Pester bietet eine Sprache zum Schreiben von Unit- und Integrationstests für Ihre PowerShell-Scripte, Cmdlets, Funktionen und Module. Und wie wir es von PowerShell gewohnt sind, können diese Tests leicht automatisiert werden.

In diesem Artikel erfahren Sie, wie Sie in Pester einsteigen können, sowie die Grundlagen der Verwendung von Pester zum Testen Ihrer Scripte.
 

 

Pester installieren

Zu Beginn müssen Sie prüfen, ob Pester auf Ihrem Computer verfügbar ist und wenn ja, in welcher Version.

Get-Module -ListAvailable Pester

Als Ausgabe dieses Befehls wird Ihnen die Version von Pester angegeben, die auf Ihrem Gerät installiert ist. Die folgende Ausgabe zeigt, dass Pester in der Version 5.0.4 installiert ist.
Directory: C:\\Program Files\\WindowsPowerShell\\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 5.0.4 Pester {Invoke-Pester, Describe, Context, It...}

Wenn die Ausgabe eine Version von Pester anzeigt, die niedriger als 5 ist, sollten Sie sie aktualisieren:
Update-Module -Name Pester

Installieren Sie Pester mit dem folgenden Befehl:
Install-Module Pester -Force

Jetzt können Sie das Modul importieren:
Import-Module Pester

Wenn Sie jetzt den Befehl zum Prüfen auf das importierte Modul ausführen, sollten Sie Pester anzeigen können (wie in Abbildung 1 zu sehen ist):
Get-Module
Screenshot: Powershell console displaying details on the Pester PowerShell module

Abb. 1: Pester ist jetzt in der Modulausgabe sichtbar

 

Pester Tests erstellen

Erstellen wir Ihren ersten Pester-Test. Für unser Beispiel zerlegen wir ihn in mehrere Teile. Nehmen wir an, dass Sie ein Script testen müssen, das zur Ausführung bestimmter Aufgaben in Office 365 erstellt wurde. Dazu müssen Sie PowerShell mit Ihrem Office 365-Tenant verbinden. Falls Sie das dafür benötigte Modul noch nicht installiert haben, sollten Sie das EXOV2 PowerShell-Modul herunterladen.

Verwenden Sie diese Befehle, um eine Verbindung mit dem Office 365-Tenant herzustellen:

$Credentials = Get-Credential
Connect-ExchangeOnline -Credential $Credentials

Angenommen Sie haben eine csv-Datei mit der Liste der Anwender, an denen Sie Ihre Aufgaben ausführen müssen. Das erste Ziel wäre, sicherzustellen, dass der angegebene Pfad auch tatsächlich existiert.

Lassen Sie uns einen Test erstellen, um das zu überprüfen.

Describe "Test-CSV" {
It "CSV exists" {
"" | Should -Exist
}
}

IWenn die Datei am genannten Ort existiert, dann sollte die Ausgabe wie in Abbildung 2 gezeigt aussehen:

Screenshot: PowerShell output depicting that the path test was successful

Abb. 2: Erfolgreicher Pfad-Test

Hier passiert eine ganze Reihe von Dingen. Zunächst einmal haben wir den Befehl Invoke-Pester verwendet, um den Pester-Test zu starten. Auf diese Weise rufen wir den Test auf.

Der nächste Teil besteht darin, die Testdatei an der angegebenen Stelle zu identifizieren. Pester-Tests haben dieses Format „Dateiname.tests.ps1″.

Tipp: ScriptRunner erkennt Pester-Tests automatisch an ihrem Dateiformat. Die entsprechenden Testscripte werden automatisch in der Subbibliothek „Pester Tests“ der ScriptRunner Admin App abgelegt.

Screenshot: ScriptRunner Admin App

ScriptRunner sortiert Pester-Scripte automatisch in der Subbibliothek „Pester Tests“.

Sobald die Datei gefunden wird, wird die Anzahl der angegebenen Bedingungen geprüft und der Test durchgeführt. Das Testergebnis wird dann unten angezeigt.
In diesem Fall hatte ich die Datei an der genannten Stelle erstellt; mein Test war also erfolgreich.
Wenn die Datei jedoch nicht an diesem Ort auffindbar ist, sieht die Ausgabe wie in Abbildung 3 dargestellt aus:

PowerShell output depicting that the path test was unsuccessful

Abbildung 3: Erfolgloser Pfad-Test.

Die anderen Aspekte dieses Tests sind die Blöcke „Describe“ und „It“. Im nächsten Abschnitt erfahren Sie mehr darüber.

 

Pester-Blöcke

Die Funktionen, die in Pester verwendet werden, sind leicht verständlich, wie aus dem zuvor besprochenen Beispiel hervorgeht. Die Blöcke, die in Pester verwendet werden, sind:

  • Describe
  • It
  • Context
  • BeforeAll
  • AfterAll
  • BeforeEach
  • AfterEach

 

Describe-Block

Der Describe-Block ist ein Script-Block in PowerShell. In diesem Block werden Sie so gut wie Ihren gesamten Testcode eingeben. Die Blöcke It, Context und alle andere können innerhalb dieses Blocks eingefügt werden.

Describe dient zum Gruppieren von Tests. Sie können mehrere Describe-Blöcke zu Ihrem Test hinzufügen.

Hier ist ein Beispiel-Script, auf dem wir im Laufe dieses Artikels aufbauen werden (ich habe es auch in seiner endgültigen Form später in diesem Beitrag eingefügt).

function Get-UsageLocation ($User){
return (Get-Mailbox $User).UsageLocation
}
Describe "Retrieve Mailbox Information" -Tag 'MailboxInfo' {
It "Check if India" -Tag "India" {
Get-UsageLocation "yogi@testdomain1988.onmicrosoft.com" | Should -Be "India"
}
It "Usage location should not be UK" -Tag "NotUK" {
Get-UsageLocation "derek@testdomain1988.onmicrosoft.com" | Should -Not -Be "United Kingdom"
}
}

Mit diesem Describe-Block testen Sie zwei Möglichkeiten. Da die Mailbox „derek@testdomain1988.onmicrosoft.com“ als Verwendungsort „UK“ hat, wird der Test im zweiten It-Block fehlschlagen.

It-Block

Im It-Block geben Sie Ihre Bedingungen an, unter denen der Test durchgeführt werden soll. Wie aus dem obigen Beispiel zu sehen ist, haben wir im ersten It-Block die Bedingung gestellt, dass der Nutzungsort der Mailbox „Indien“ sein muss.

Der zweite It-Block enthielt die Bedingung, dass der Nutzungsort nicht „UK“ sein darf.

Das Ergebnis des Tests kann eines der folgenden sein:

  • Passed – Alle Bedingungen in diesem Test bestanden.
  • Failed – Das Ergebnis entsprach nicht den von uns gestellten Bedingungen.
  • Skipped – Der Test wurde übersprungen.
  • Pending –Der Test konnte nicht durchgeführt werden, da er noch nicht beendet oder leer ist.
  • Inconclusive – Das Ergebnis des Tests ist weder „bestanden“ noch „durchgefallen“.

In unserem Beispiel wurde der erste It-Block-Test bestanden, der zweite nicht (Abb. 4).

Screenshot: PowerShell output depicting that the first it block test succeeded while the second failed

Fig. 4: It block test output


Context-Block

Der Describe-Block gruppiert alle Tests innerhalb dieses Blocks. Wenn ein Test jedoch unter anderen Bedingungen oder Umständen ausgeführt werden soll, können Sie den Context-Block verwenden. Dieser Block ist dem Describe-Block ähnlich; es gibt jedoch einige wesentliche Unterschiede.

Der Context-Block existiert innerhalb des Describe-Blocks. Es können sogar mehrere Context-Blöcke in einem Describe-Block vorhanden sein: Wie der Name schon sagt, können Sie sie dazu verwenden, Ihre Tests in verschiedene Kontexte zu unterteilen.

Im vorliegenden Beispiel werden Sie feststellen, dass ich 2 Context-Blöcke hinzugefügt habe, um zwischen den Tests für Verwendungsort und Adressbuch zu unterscheiden. Hier ist der Code:

Context "Check Usage Location" {
It "Check if India" -Tag "India" {
Get-UsageLocation "yogi@testdomain1988.onmicrosoft.com" | Should -Be "India"
}
It "Usage location should not be UK" -Tag "NotUK" {
Get-UsageLocation "derek@testdomain1988.onmicrosoft.com" | Should -Not -Be "United Kingdom"
}
}
#end of usagelocation context
Context "Is it hidden from the address book" -Tag HiddenFromGAL {
It "Check hidden from GAL attribute" {
Get-HiddenFromGal "vignesh@testdomain1988.onmicrosoft.com" | Should -Be "False"
}
} #end of Hidden from GAL context block

BeforeAll-Block

Möglicherweise möchten Sie zu Beginn einige bestimmte Tasks oder Codes ausführen. In unserem Beispiel gibt es zur Zeit 2 Funktionen, auf die später im Script Bezug genommen werden muss. Eine Möglichkeit besteht darin, den BeforeAll-Block zu verwenden, um die 2 Funktionen im Speicher zu behalten.
Dieser Block wird vor jedem der It-Blöcke ausgeführt.
Sie können nun die Funktionen innerhalb des BeforeAll-Blocks hinzufügen, wie hier gezeigt:

BeforeAll {
#Connecting to Exchange Online PowerShell Module
. #Functions
function Get-UsageLocation ($User){
return (Get-Mailbox $User).UsageLocation
}
function Get-HiddenFromGal ($Account){
return (Get-Mailbox $Account).HiddenFromAddressListsEnabled
}
}

Die Durchführung des Tests zeigt nun deutlich, dass er wie erwartet funktioniert (siehe Abbildung 5).

Screenshot: PowerShell output depicting the output of BeforeAll block

Abb. 5: Ausgabe des BeforeAll-Tests


AfterAll-Block

In manchen Situationen kann es sinnvoll sein, am Ende eines Tests oder Blocks eine Reihe von Tasks durchzuführen. Zu diesem Zweck eignet sich der AfterAll-Block, der nach der Ausführung aller It-Blöcke ausgeführt wird.

Durch Hinzufügen des folgenden Codeblocks am Ende des letzten It-Blocks wird sichergestellt, dass die Verbindung der Exchange Online PowerShell-Session nach Ausführung der Tests getrennt wird:

AfterAll{
Disconnect-ExchangeOnline -Confirm:$false
}

BeforeEach/AfterEach Block

Die BeforeEach– und AfterEach-Blöcke sind nützlich, wenn Sie möchten, dass ein bestimmter Codeblock vor und nach jedem It-Block ausgeführt wird. Sie können sie verwenden, um einen Eintrag in eine Protokolldatei vorzunehmen oder sogar etwas im PowerShell-Ergebnis anzuzeigen.

In dem Beispiel, auf dem wir in dieser Session aufgebaut haben, habe ich die BeforeEach– und AfterEach-Blöcke verwendet, um einen Text im Ergebnis anzuzeigen:

BeforeEach {
Write-Host "BeforeEach Block" -BackgroundColor DarkMagenta
}
AfterEach {
Write-Host "AfterEach Block" -BackgroundColor Black
}

 

Fazit

Wie Sie gesehen haben, sind die Grundlagen von Pester leicht zu erlernen, und Sie können schnell erste einfache Unit-Tests schreiben.
Für komplexere Tests ist es erforderlich, Verweise auf andere Cmdlets und Funktionen zu berücksichtigen. Hier kommt Mocking ins Spiel. Bleiben Sie dran, um im zweiten Teil dieses Artikels mehr über Mocking, Assertions und Tags zu erfahren.

Zusammenhängende Posts

16 min read

ScriptRunner Portal Edition R4

4 min read

So nutzen Sie Azure Templates zur Automatisierung

Über den Autor: