Übung: Ausführen der UI-Tests lokal und in der Pipeline

Abgeschlossen

Bevor Andy und Amita Ihre Tests in der Pipeline ausführen, möchten sie überprüfen, ob die neuen UI-Tests die gewünschten Aktionen ausführen. In diesem Abschnitt führen Sie zunächst lokal und dann in der Pipeline die Benutzeroberflächentests von Selenium aus.

Wie das Schreiben jedes anderen Codes ist das Schreiben von automatisierten Tests ist ein iterativer Prozess. Für Ihre eigenen Apps müssen Sie wahrscheinlich mehrerer Strategien ausprobieren, die Referenzdokumentation und den Beispielcode zu Rate ziehen sowie Buildfehler beheben.

Optional: Installieren des Selenium-Treibers für Microsoft Edge

Führen Sie die Schritte in diesem Abschnitt durch, wenn Sie sehen möchten, wie die Tests lokal in Microsoft Edge ausgeführt werden.

Das NuGet-Paket für Chrome und Firefox installiert die Treibersoftware neben dem kompilierten Testcode im Verzeichnis bin. Für Microsoft Edge müssen Sie den Treiber manuell installieren. Gehen Sie folgendermaßen vor:

  1. Installieren Sie Microsoft Edge.

  2. Öffnen Sie Microsoft Edge, und navigieren Sie zu edge://settings/help. Beachten Sie die Versionsnummer. Hier sehen Sie ein Beispiel:

    A screenshot of the Microsoft Edge setting page, showing the version number.

  3. Navigieren Sie zur Downloadseite für den Microsoft Edge-Treiber, und laden Sie den Treiber für die entsprechende Edge-Versionsnummer herunter. Hier sehen Sie ein Beispiel:

    A screenshot of the Downloads section of the Microsoft Edge Driver page showing the matching driver version.

  4. Extrahieren Sie die ZIP-Datei in das Verzeichnis bin/Release/net6.0 unter dem Verzeichnis Tailspin.SpaceGame.Web.UITests Ihres Projekts. Erstellen Sie diese Verzeichnisse, wenn diese nicht vorhanden sind.

Unter macOS müssen Sie u. U. die Systemrichtlinie aktualisieren, damit msedgedriver ausgeführt werden kann. Führen Sie dazu in Visual Studio Code den folgenden spctl-Befehl im Terminal aus:

spctl --add Tailspin.SpaceGame.Web.UITests/bin/Release/net6.0/msedgedriver

Exportieren von Umgebungsvariablen

Später in diesem Modul führen Sie Selenium-Tests unter Windows Server 2019 aus. In der Dokumentation finden Sie eine Liste der vorinstallierten Software.

Im Abschnitt Selenium Web Drivers werden die verfügbaren Selenium-Treiberversionen für Chrome, Firefox und Microsoft Edge aufgelistet. Hier sehen Sie ein Beispiel:

A screenshot showing the documentation for the installed Selenium drivers on the build agent.

Für jeden Treiber wird die entsprechende Umgebungsvariable für den Speicherort des betreffenden Treibers angezeigt. ChromeWebDriver entspricht beispielsweise dem Speicherort des Chrome-Treibers.

Der Code für Komponententests ist bereits so eingerichtet, dass diese Umgebungsvariablen gelesen werden. Diese Variablen teilen Selenium mit, wo die ausführbaren Treiberdateien zu finden sind. Um die Komponententests lokal auszuführen, müssen Sie die gleichen Umgebungsvariablen exportieren.

Rufen Sie in Visual Studio Code das Terminal auf. Führen Sie anschließend die aufgeführten Befehle aus. Ersetzen Sie den angezeigten Pfad durch den vollständigen Pfad zu Ihrem Projekt mslearn-tailspin-spacegame-web-deploy.

Wichtig

Stellen Sie sicher, dass Sie diese Befehle ausführen und die Umgebungsvariablen im selben Terminalfenster festlegen, das Sie zum Ausführen der Tests verwenden.

driverDir="C:\Users\user\mslearn-tailspin-spacegame-web-deploy\Tailspin.SpaceGame.Web.UITests\bin\Release\net6.0"
export ChromeWebDriver=$driverDir
export EdgeWebDriver=$driverDir
export GeckoWebDriver=$driverDir

Lokales Ausführen der UI-Tests

Die Setup-Methode in HomePageTest.cs navigiert zur Space Game-Homepage, nachdem die Membervariable driver festgelegt wurde.

Obwohl Sie die Website-URL fest codieren können, wird die URL hier aus einer Umgebungsvariablen namens SITE_URL gelesen. Auf diese Weise können Sie die Tests mehrmals für verschiedene URLs ausführen.

// Navigate to the site.
// The site name is stored in the SITE_URL environment variable to make 
// the tests more flexible.
string url = Environment.GetEnvironmentVariable("SITE_URL");
driver.Navigate().GoToUrl(url + "/");

Da die Space Game-Website noch nicht in der App Service Umgebung bereitgestellt wurde, verwenden Sie die von Microsoft gehostete Website, um die Tests lokal auszuführen.

So führen Sie die Tests lokal aus:

  1. Navigieren Sie in Visual Studio Code zum integrierten Terminal, und öffnen Sie ein neues Terminalfenster.

  2. Führen Sie im neuen Terminal die folgenden Befehle aus.

    dotnet build --configuration Release
    dotnet run --configuration Release --no-build --project Tailspin.SpaceGame.Web
    
  3. Notieren Sie sich den Link für die lokale Website, in diesem Beispiel http://localhost:5000.

  4. Wechseln Sie zurück zum Terminalfenster, in dem Sie im vorherigen Schritt die Umgebungsvariablen festgelegt haben, und stellen Sie sicher, dass Sie sich im Stammverzeichnis Ihres Projekts befinden. Hier sehen Sie ein Beispiel:

    cd ~/mslearn-tailspin-spacegame-web-deploy
    
  5. Exportieren Sie die Umgebungsvariable SITE_URL. Verwenden Sie den lokal ausgeführten Link, den Sie im vorherigen Schritt erhalten haben.

    export SITE_URL="http://localhost:5000"
    

    Diese Variable verweist auf die von Microsoft gehostete Space Game-Website.

  6. Führen Sie die UI-Tests aus.

    dotnet test --configuration Release Tailspin.SpaceGame.Web.UITests
    

    Dieser Code führt die Tests aus, die sich im Projekt Tailspin.SpaceGame.Web.UITests befinden.

    Bei der Ausführung der Tests werden die Browser angezeigt. Selenium steuert den jeweiligen Browser und folgt den von Ihnen definierten Testschritten.

    Hinweis

    Machen Sie sich keine Sorge, wenn nicht alle drei Browser angezeigt werden. Die Tests werden beispielsweise nicht in Chrome ausgeführt, wenn Chrome nicht oder eine inkompatible Version installiert ist. Wenn Sie nur einen Browser sehen, können Sie sicher sein, dass die Tests funktionieren. In der Praxis können Sie in Ihrer lokalen Entwicklungsumgebung ggf. alle Browser einrichten, die Sie testen möchten. Mit diesem Setup können Sie überprüfen, ob sich die Tests in jeder Konfiguration erwartungsgemäß verhalten, bevor Sie die Tests in der Pipeline ausführen.

  7. Verfolgen Sie die Ausgabe der einzelnen Tests im Terminal. Beachten Sie auch die Testlaufzusammenfassung am Ende.

    Dieses Beispiel zeigt, dass von neun Tests alle neun erfolgreich waren und keine Tests übersprungen wurden:

    Passed!  - Failed:     0, Passed:     9, Skipped:     0, Total:     9, Duration: 5 s 
    

Hinzufügen der SITE_URL-Variable zu Azure Pipelines

Zuvor haben Sie die SITE_URL-Umgebungsvariable lokal festgelegt, damit die Tests die jeweilige URL der Browser kennen. Sie können diese Variable zu Azure Pipelines hinzufügen. Die Vorgehensweise ähnelt dem Hinzufügen von Variablen für Ihre App Service-Instanzen. Wenn der Agent ausgeführt wird, wird diese Variable automatisch als Umgebungsvariable in den Agent exportiert.

Lassen Sie uns jetzt die Pipelinevariable hinzufügen, bevor Sie die Pipelinekonfiguration aktualisieren. Gehen Sie folgendermaßen vor:

  1. Navigieren Sie in Azure DevOps zum Projekt Space Game - web - Functional tests.

  2. Wählen Sie unter Pipelines die Option Libraryaus.

  3. Wählen Sie die Variablengruppe Release aus.

  4. Wählen Sie unter Variables die Option + Add aus.

  5. Geben Sie als Name der Variablen SITE_URL ein. Geben Sie als Wert die entsprechende URL der App Service-Instanz Ihrer Testumgebung ein, z. B. http://tailspin-space-game-web-test-10529.azurewebsites.net.

  6. Klicken Sie im oberen Bereich der Seite auf Speichern, um die Variable in der Pipeline zu speichern.

    Ihre Variablengruppe sollte ungefähr wie folgt aussehen:

    A screenshot of Azure Pipelines, showing the variable group. The group contains four variables.

Ändern der Pipelinekonfiguration

In diesem Abschnitt ändern Sie die Pipelinekonfiguration so, dass die Selenium-UI-Tests in der Testphase ausgeführt werden.

  1. Öffnen Sie in Visual Studio Code die Datei azure-pipelines.yml. Ändern Sie die Datei dann wie folgt:

    Tipp

    Diese Datei enthält einige Änderungen. Daher wird empfohlen, die gesamte Datei durch die hier gezeigte zu ersetzen.

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      dotnetSdkVersion: '6.x'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '6.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '$(System.DefaultWorkingDirectory)/**/Tailspin.SpaceGame.Web.csproj' 
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Test'
      displayName: 'Deploy to the test environment'
      dependsOn: Dev
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: test
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameTest)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
      - job: RunUITests
        dependsOn: Deploy
        displayName: 'Run UI tests'
        pool:
          vmImage: 'windows-2019'
        variables:
        - group: 'Release'
        steps: 
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--configuration $(buildConfiguration)'
            projects: '$(System.DefaultWorkingDirectory)/**/*UITests.csproj'
        - task: DotNetCoreCLI@2
          displayName: 'Run unit tests - $(buildConfiguration)'
          inputs:
            command: 'test'
            arguments: '--no-build --configuration $(buildConfiguration)'
            publishTestResults: true
            projects: '$(System.DefaultWorkingDirectory)/**/*UITests.csproj'
    
    - stage: 'Staging'
      displayName: 'Deploy to the staging environment'
      dependsOn: Test
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: staging
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameStaging)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    

    Die Datei enthält die folgenden drei Änderungen:

    • Die Variable dotnetSdkVersion wird an den Anfang der Datei verschoben, sodass mehrere Phasen darauf zugreifen können. Hier ist diese Version von .NET Core für die Build- und die Testphase erforderlich.

    • In der Buildphase wird lediglich das Space Game-Websitepaket als Buildartefakt veröffentlicht. Zuvor wurden Artefakte wie folgt veröffentlicht:

      - task: DotNetCoreCLI@2
        displayName: 'Publish the project - $(buildConfiguration)'
        inputs:
          command: 'publish'
          projects: '**/*.csproj'
          publishWebProjects: false
          arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
          zipAfterPublish: true
      

      Diese Aufgabe generiert zwei Buildartefakte: das Space Game-Websitepaket und die kompilierten UI-Tests. Sie erstellen die Benutzeroberflächentests während der Erstellungsphase, um sicherzustellen, dass sie während der Testphase kompiliert werden. Sie müssen den kompilierten Testcode jedoch nicht veröffentlichen. Dieser wird erneut in der Testphase erstellt, wenn die Tests ausgeführt werden.

    • Die Testphase umfasst einen zweiten Job, der die Tests erstellt und ausführt. Dieser Job weist Ähnlichkeit mit dem auf, den Sie im Modul zum Ausführen von Qualitätstests in der Buildpipeline mit Azure Pipelines verwendet haben. In diesem Modul haben Sie NUnit-Tests ausgeführt, mit denen die Filterfunktionalität der Bestenliste überprüft wurde.

      Bedenken Sie, dass es sich bei einem Bereitstellungsjob um einen speziellen Jobtyp handelt, der in ihren Bereitstellungsphasen eine wichtige Rolle spielt. Der zweite Job ist ein normaler Job, der die Selenium-Tests auf einem Windows Server 2019-Agent ausführt. Obwohl wir einen Linux-Agent zum Erstellen der Anwendung verwenden, verwenden wir hier einen Windows-Agent, um die UI-Tests auszuführen. Wir verwenden einen Windows-Agent, weil Amita die manuellen Tests wie die meisten Kunden unter Windows ausführt.

      Der RunUITests-Job hängt vom Deploy-Job ab, damit die Jobs in der richtigen Reihenfolge ausgeführt werden. Sie stellen die Website in App Service bereit, bevor Sie die UI-Tests ausführen. Wenn Sie diese Abhängigkeit nicht angeben, können Jobs innerhalb der Phase in beliebiger Reihenfolge oder parallel ausgeführt werden.

  2. Fügen Sie azure-pipelines.yml im integrierten Terminal zum Index hinzu, committen Sie die Änderungen, und pushen Sie den Branch an GitHub.

    git add azure-pipelines.yml
    git commit -m "Run Selenium UI tests"
    git push origin selenium
    

Beobachten der Testausführung in Azure Pipelines

Hier beobachten Sie, wie die Pipeline ausgeführt wird. Die Pipeline führt die Selenium-UI-Tests in der Testphase aus.

  1. Wechseln Sie in Azure Pipelines zum Build, und verfolgen Sie die Ausführung.

    Bei der Erstellung sehen Sie, dass die automatisierten Tests nach der Bereitstellung der Website ausgeführt werden.

    A screenshot of Azure Pipelines, showing the running stages.

  2. Wechseln Sie nach dem Build zur Zusammenfassungsseite.

    A screenshot of Azure Pipelines, showing the completed stages.

    Sie sehen, dass die Bereitstellung und die Benutzeroberflächentests erfolgreich abgeschlossen wurden.

  3. Beachten Sie die Zusammenfassung im oberen Bereich der Seite.

    Sie sehen, dass das Buildartefakt für die Website von Space Game wie üblich veröffentlicht wurde. Beachten Sie auch den Abschnitt Tests and coverage, in dem angezeigt wird, dass die Selenium-Tests erfolgreich durchgeführt wurden.

    A screenshot of Azure Pipelines, showing the test summary.

  4. Wählen Sie die Testzusammenfassung aus, um den vollständigen Bericht anzuzeigen.

    Der Bericht zeigt, dass alle neun Tests bestanden wurden. Diese Tests umfassen drei Tests für jeweils drei Browser.

    A screenshot of Azure Pipelines, showing the full test report.

    Wenn ein Test fehlschlägt, werden detaillierte Ergebnisse zum Fehler angezeigt. Von dort aus können Sie die Fehlerquelle untersuchen, lokal beheben und dann die erforderlichen Änderungen pushen, damit die Tests in der Pipeline erfolgreich durchgeführt werden.

Amita: Diese Automatisierung macht Spaß! Ich habe jetzt UI-Tests, die ich in der Pipeline ausführen kann. Die Tests sparen uns langfristig viel Zeit. Ich habe außerdem ein Muster zum Hinzufügen von weiteren Tests. Das Beste daran ist, dass die UI-Tests das Vertrauen in unserer Codequalität stärken.

Andy: Stimmt. Tests, die wiederholt manuell ausgeführt werden, sind gute Kandidaten für eine Automatisierung. Viel Glück dabei. Du weißt, wo du mich findest, wenn du nicht weiterkommst oder einen brauchst, der den Code überprüft.