Partager via


Moniteur en mode utilisateur

Le moniteur du mode utilisateur permet aux tests d’obtenir plus de contexte sur l’exécution du « processus testé » afin d’obtenir davantage de contexte pour examiner les échecs de test ou pour permettre une meilleure vérification à partir des tests existants. L’implémentation actuelle du moniteur en mode utilisateur fournit une implémentation de base, avec davantage de personnalisation et de configuration dans les versions suivantes.

Introduction

Le moniteur de mode utilisateur (UMM) utilise des API Windows de bas niveau pour être averti de tous les événements de « débogueur » qui proviennent d’un processus donné : démarrage et arrêt du thread, chargement du module, incidents et exceptions gérées, pour n’en citer que quelques-uns. Lors de la réception d’un événement de débogueur, le code UMM peut effectuer l’une des différentes actions, notamment la journalisation des commentaires, la journalisation des erreurs (afin d’échouer à un test) ou même l’exécution d’un minidump du processus en cours de test.

Activation du moniteur en mode utilisateur

Pour activer l’UMM pour un cas de test donné, vous devez fournir deux éléments de configuration :

  1. Le test doit être marqué avec la valeur de métadonnées « ProcessUnderTest ». Cela permet à l’UMM d’identifier le processus testé.
  2. La ligne de commande Te.exe doit inclure « /userModeMonitor » pour activer la fonctionnalité UMM.

Les points suivants doivent être pris en compte lors de l’utilisation du code UMM :

  1. Si plusieurs instances du processus nommé sous test sont en cours d’exécution, le instance qui est découvert en premier est utilisé.
  2. L’utilisateur qui exécute l’automatisation du test doit disposer des autorisations suffisantes pour recevoir des événements de débogueur à partir du processus en cours de test.
  3. Le code UMM « s’attache » au processus en cours de test une fois que tous les montages d’installation ont été exécutés, et « détache » avant l’exécution des montages de nettoyage. Cela permet aux montages d’installation d’un test de démarrer le processus en cours de test et d’effectuer toute initialisation nécessaire pour se préparer au test.

Actions prises en charge du moniteur en mode utilisateur

Le moniteur de mode utilisateur a un ensemble d’actions qu’il peut effectuer lorsqu’un événement de débogueur donné se produit dans le processus surveillé. Dans l’implémentation actuelle, un événement donné appelle uniquement son action par défaut ; il n’existe actuellement aucune prise en charge de la configuration.

Action Description
LogComment Ajoute un commentaire au journal, avec des informations contextuelles de l’événement.
LogError Enregistre une erreur dans le journal, ce qui échoue au test actuel.
Minidump Écrit un minidump et l’enregistre dans le journal.
Ignorer Ne fait rien.

« Événements » du moniteur du mode utilisateur pris en charge

Le moniteur du mode utilisateur affiche des « événements » qui peuvent appliquer l’une des « actions » répertoriées ci-dessus. Le tableau suivant présente la liste actuelle des événements signalés, ainsi que l’action par défaut qui sera effectuée lors de la réception de l’événement.

événement Action par défaut (action par défaut de la deuxième chance)
Créer un thread Ignorer
Thread de sortie Ignorer
Créer un processus Ignorer
Processus de sortie LogError
Module de chargement LogComment
Décharger le module Ignorer
Erreur système Ignorer
Point d’arrêt initial LogError
Chargement initial du module Ignorer
Sortie de débogage LogComment
Violation d’accès LogError (LogError)
Échec d’assertion LogError (LogError)
Blocage de l’application LogError (LogError)
Exception d’instruction d’arrêt LogError
Arrêt de l’exception d’instruction continue Ignorer
Exception EH C++ LogError (LogError)
Exception CLR LogError (LogError)
Exception de notification CLR LogError (Ignorer)
Control-LogError exception LogError
Control-LogError exception continue Ignorer
Exception Control-C LogError
L’exception Control-C continue Ignorer
Données mal alignées LogError (LogError)
Exception de commande débogueur Ignorer
Violation de page de protection LogError (LogError)
Instruction non conforme LogError (LogError)
Erreur d’E/S dans la page LogError (LogError)
Entier divisé par zéro LogError (LogError)
Dépassement de capacité d’entier LogError (LogError)
Handle non valide LogError
Continue du handle non valide LogError
Séquence de verrous non valide LogError (LogError)
Appel système non valide LogError (LogError)
Port déconnecté LogError (LogError)
Blocage du service LogError (LogError)
Exception à étape unique LogError
L’exception à étape unique continue Ignorer
Dépassement de mémoire tampon au niveau de la pile LogError (LogError)
Dépassement de capacité de la pile LogError (LogError)
Arrêt du vérificateur LogError (LogError)
Exception Visual C++ Ignorer (Ignorer)
Débogueur de veille LogError (LogError)
Point d’arrêt WOW64 LogError (Ignorer)
Exception d’étape unique WOW64 LogError (Ignorer)
Autre exception LogError (LogError)

Exemple

Pour illustrer l’utilisation de la fonctionnalité UMM, examinons un exemple (légèrement artificiel) d’un test qui automatise « MSPaint » :

namespace UserModeMonitorExample
{
    using System;
    using System.Diagnostics;
    using System.Threading;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using WEX.Logging.Interop;
    using WEX.TestExecution;

    [TestClass]
    public class BasicExample
    {
        [TestInitialize]
        public void TestInitialize()
        {
            Process[] runningPaintInstances = Process.GetProcessesByName("mspaint.exe");

            Verify.IsTrue(runningPaintInstances.Length == 0, "There are no running instances of mspaint.exe");

            this.mspaintUnderTest = Process.Start("mspaint.exe");
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // Close the 'mspaint under test' - if it's already gone, this will throw, but that's no big deal.
            this.mspaintUnderTest.CloseMainWindow();
        }

        [TestMethod]
        [TestProperty("ProcessUnderTest", "mspaint.exe")]
        [TestProperty("Description", "Shows how a test can be failed if the UI is closed from underneath the test.")]
        public void SimpleInteraction()
        {
            Log.Comment("If the 'user mode monitor' is enabled and mspaint.exe is closed,");
            Log.Comment("then this test will be failed.");
            Log.Comment("Sleeping for 5 seconds");

            Thread.Sleep(TimeSpan.FromSeconds(5));
        }

        private Process mspaintUnderTest;
    }
}

Voici une rapide répartition de la structure du test :

  • Le test « SimpleInteraction » représente un test qui interagit avec une application basée sur l’interface utilisateur. Dans ce cas, il s’agit de « MSPaint.exe ». Notez que les métadonnées « ProcessUnderTest » ont été appliquées pour signaler que ce test test teste le processus « mspaint.exe ».
  • Le test a une fixation d’installation qui garantit qu’aucune instance préexistante n’est en cours d’exécution et lance une seule instance à tester.
  • Le test a également un appareil de nettoyage qui ferme le instance qui a été lancé dans le montage d’installation.

Le « test » est très simple, examinons les résultats possibles :

  1. Le test s’exécute sans problème. C’est le meilleur résultat possible.
  2. Sans UMM activé, un utilisateur ferme le instance MSPaint pendant l’exécution. Dans ce cas, le test est réussi, mais le nettoyage échoue avec une « InvalidOperationException ».
  3. Avec UMM activé, un utilisateur ferme le instance MSPaint pendant l’exécution. Dans ce cas, le code UMM journalisera une erreur indiquant que le processus s’est fermé en échouant au test. Le nettoyage échoue comme dans le cas (2).

Avec UMM activé, le comportement errant est immédiatement signalé et affecte directement le résultat du test. Il s’agit d’un modèle de test bien meilleur, car les erreurs sont signalées le plus tôt possible et un contexte supplémentaire est fourni pour faciliter le débogage ou la compréhension des échecs de test.