Megosztás a következőn keresztül:


Az AutomationID tulajdonság használata

Feljegyzés

Ez a dokumentáció .NET-keretrendszer fejlesztőknek készült, akik a névtérben System.Windows.Automation meghatározott felügyelt UI-automatizálás osztályokat szeretnék használni. A UI-automatizálás kapcsolatos legfrissebb információkért lásd: Windows Automation API: UI-automatizálás.

Ez a témakör olyan forgatókönyveket és mintakódot tartalmaz, amelyek bemutatják, hogyan és mikor használható egy AutomationIdProperty elem megkeresésére a UI-automatizálás fa.

AutomationIdPropertyegyedileg azonosít egy UI-automatizálás elemet a testvéreitől. A vezérlőazonosításhoz kapcsolódó tulajdonságazonosítókkal kapcsolatos további információkért lásd UI-automatizálás Tulajdonságok áttekintése című témakört.

Feljegyzés

AutomationIdProperty nem garantálja az egyedi identitást a fa egészében; általában a tárolóra és a hatókörre vonatkozó információkra van szükség, hogy hasznosak legyenek. Előfordulhat például, hogy egy alkalmazás több felső szintű menüelemet tartalmazó menüvezérlőt tartalmaz, amely viszont több gyermekmenüelemből áll. Ezeket a másodlagos menüelemeket egy általános séma, például az "Elem1", a "2. elem" stb. azonosíthatja, amely lehetővé teszi a gyermekek ismétlődő azonosítóit a felső szintű menüelemek között.

Forgatókönyvek

Három elsődleges UI-automatizálás ügyfélalkalmazás-forgatókönyvet azonosítottunk, amelyekhez pontos és konzisztens eredményekre van szükség AutomationIdProperty az elemek keresésekor.

Feljegyzés

AutomationIdPropertya vezérlő nézet összes UI-automatizálás eleme támogatja, kivéve a felső szintű alkalmazásablakokat, UI-automatizálás Windows megjelenítési alaprendszer (WPF) vezérlőkből származó elemeket, amelyek nem rendelkeznek azonosítóval vagy x:Uid azonosítóval, és UI-automatizálás olyan Win32-vezérlőkből származó elemek, amelyek nem rendelkeznek vezérlőazonosítóval.

Egyedi és felderíthető AutomationID használatával keresse meg a UI-automatizálás fa egy adott elemét

  • Használjon olyan eszközt, mint a UI Spy, hogy jelentse a AutomationIdProperty felhasználói felület érdekes elemét. Ezt az értéket ezután átmásolhatja és beillesztheti egy ügyfélalkalmazásba, például egy tesztszkriptbe a későbbi automatizált teszteléshez. Ez a megközelítés csökkenti és leegyszerűsíti az elemek futásidőben történő azonosításához és megkereséséhez szükséges kódot.

Figyelemfelhívás

Általában meg kell próbálnia csak a közvetlen gyermekeket megszerezni a RootElement. Az utódok keresése több száz vagy akár több ezer elemen is átfolyhat, ami valószínűleg egy verem túlcsordulását eredményezheti. Ha egy adott elemet alacsonyabb szinten próbál beszerezni, a keresést az alkalmazásablakból vagy egy alacsonyabb szintű tárolóból kell elindítania.

///--------------------------------------------------------------------
/// <summary>
/// Finds all elements in the UI Automation tree that have a specified
/// AutomationID.
/// </summary>
/// <param name="targetApp">
/// The root element from which to start searching.
/// </param>
/// <param name="automationID">
/// The AutomationID value of interest.
/// </param>
/// <returns>
/// The collection of UI Automation elements that have the specified
/// AutomationID value.
/// </returns>
///--------------------------------------------------------------------
private AutomationElementCollection FindElementFromAutomationID(AutomationElement targetApp,
    string automationID)
{
    return targetApp.FindAll(
        TreeScope.Descendants,
        new PropertyCondition(AutomationElement.AutomationIdProperty, automationID));
}
'''--------------------------------------------------------------------
''' <summary>
''' Finds all elements in the UI Automation tree that have a specified
''' AutomationID.
''' </summary>
''' <param name="targetApp">
''' The root element from which to start searching.
''' </param>
''' <param name="automationID">
''' The AutomationID value of interest.
''' </param>
''' <returns>
''' The collection of automation elements that have the specified
''' AutomationID value.
''' </returns>
'''--------------------------------------------------------------------
Private Function FindElementFromAutomationID( _
ByVal targetApp As AutomationElement, _
ByVal automationID As String) As AutomationElementCollection
    Return targetApp.FindAll( _
    TreeScope.Descendants, _
    New PropertyCondition( _
    AutomationElement.AutomationIdProperty, automationID))
End Function 'FindElementFromAutomationID

Állandó elérési út használata egy korábban azonosított AutomationElementhez való visszatéréshez

  • Az ügyfélalkalmazások az egyszerű tesztszkriptektől a robusztus rekord- és lejátszási segédprogramokig hozzáférést igényelhetnek a jelenleg nem példányosított elemekhez, például egy fájlmegnyitási párbeszédpanelhez vagy egy menüelemhez, és ezért nem léteznek a UI-automatizálás fában. Ezek az elemek csak egy adott felhasználói felületi műveletsor reprodukálásával vagy "visszajátszásával" hozhatók létre, UI-automatizálás tulajdonságok, például AutomationID, vezérlőminták és eseményfigyelők használatával.
///--------------------------------------------------------------------
/// <summary>
/// Creates a UI Automation thread.
/// </summary>
/// <param name="sender">Object that raised the event.</param>
/// <param name="e">Event arguments.</param>
/// <remarks>
/// UI Automation must be called on a separate thread if the client
/// application itself could become a target for event handling.
/// For example, focus tracking is a desktop event that could involve
/// the client application.
/// </remarks>
///--------------------------------------------------------------------
private void CreateUIAThread(object sender, EventArgs e)
{
    // Start another thread to do the UI Automation work.
    ThreadStart threadDelegate = new ThreadStart(CreateUIAWorker);
    Thread workerThread = new Thread(threadDelegate);
    workerThread.Start();
}

///--------------------------------------------------------------------
/// <summary>
/// Delegated method for ThreadStart. Creates a UI Automation worker
/// class that does all UI Automation related work.
/// </summary>
///--------------------------------------------------------------------
public void CreateUIAWorker()
{
   uiautoWorker = new FindByAutomationID(targetApp);
}
private FindByAutomationID uiautoWorker;

'''--------------------------------------------------------------------
''' <summary>
''' Creates a UI Automation thread.
''' </summary>
''' <param name="sender">Object that raised the event.</param>
''' <param name="e">Event arguments.</param>
''' <remarks>
''' UI Automation must be called on a separate thread if the client
''' application itself could become a target for event handling.
''' For example, focus tracking is a desktop event that could involve
''' the client application.
''' </remarks>
'''--------------------------------------------------------------------
Private Sub CreateUIAThread(ByVal sender As Object, ByVal e As EventArgs)

    ' Start another thread to do the UI Automation work.
    Dim threadDelegate As New ThreadStart(AddressOf CreateUIAWorker)
    Dim workerThread As New Thread(threadDelegate)
    workerThread.Start()

End Sub


'''--------------------------------------------------------------------
''' <summary>
''' Delegated method for ThreadStart. Creates a UI Automation worker
''' class that does all UI Automation related work.
''' </summary>
'''--------------------------------------------------------------------
Public Sub CreateUIAWorker()

    uiautoWorker = New UIAWorker(targetApp)

End Sub

Private uiautoWorker As UIAWorker

///--------------------------------------------------------------------
/// <summary>
/// Function to playback through a series of recorded events calling
/// a WriteToScript function for each event of interest.
/// </summary>
/// <remarks>
/// A major drawback to using AutomationID for recording user
/// interactions in a volatile UI is the probability of catastrophic
/// change in the UI. For example, the //Processes// dialog where items
/// in the listbox container can change with no input from the user.
/// This mandates that a record and playback application must be
/// reliant on the tester owning the UI being tested. In other words,
/// there has to be a contract between the provider and client that
/// excludes uncontrolled, external applications. The added benefit
/// is the guarantee that each control in the UI should have an
/// AutomationID assigned to it.
///
/// This function relies on a UI Automation worker class to create
/// the System.Collections.Generic.Queue object that stores the
/// information for the recorded user interactions. This
/// allows post-processing of the recorded items prior to actually
/// writing them to a script. If this is not necessary the interaction
/// could be written to the script immediately.
/// </remarks>
///--------------------------------------------------------------------
private void Playback(AutomationElement targetApp)
{
    AutomationElement element;
    foreach(ElementStore storedItem in uiautoWorker.elementQueue)
    {
        PropertyCondition propertyCondition =
            new PropertyCondition(
            AutomationElement.AutomationIdProperty, storedItem.AutomationID);
        // Confirm the existence of a control.
        // Depending on the controls and complexity of interaction
        // this step may not be necessary or may require additional
        // functionality. For example, to confirm the existence of a
        // child menu item that had been invoked the parent menu item
        // would have to be expanded.
        element = targetApp.FindFirst(TreeScope.Descendants, propertyCondition);
        if(element == null)
        {
            // Control not available, unable to continue.
            // TODO: Handle error condition.
            return;
        }
        WriteToScript(storedItem.AutomationID, storedItem.EventID);
    }
}

///--------------------------------------------------------------------
/// <summary>
/// Generates script code and outputs the code to a text control in
/// the client.
/// </summary>
/// <param name="automationID">
/// The AutomationID of the current control.
/// </param>
/// <param name="eventID">
/// The event recorded on that control.
/// </param>
///--------------------------------------------------------------------
private void WriteToScript(string automationID, string eventID)
{
    // Script code would be generated and written to an output file
    // as plain text at this point, but for the
    // purposes of this example we just write to the console.
    Console.WriteLine(automationID + " - " + eventID);
}
'''--------------------------------------------------------------------
''' <summary>
''' Function to playback through a series of recorded events calling
''' a WriteToScript function for each event of interest.
''' </summary>
''' <remarks>
''' A major drawback to using AutomationID for recording user
''' interactions in a volatile UI is the probability of catastrophic
''' change in the UI. For example, the 'Processes' dialog where items
''' in the listbox container can change with no input from the user.
''' This mandates that a record and playback application must be
''' reliant on the tester owning the UI being tested. In other words,
''' there has to be a contract between the provider and client that
''' excludes uncontrolled, external applications. The added benefit
''' is the guarantee that each control in the UI should have an
''' AutomationID assigned to it.
'''
''' This function relies on a UI Automation worker class to create
''' the System.Collections.Generic.Queue object that stores the
''' information for the recorded user interactions. This
''' allows post-processing of the recorded items prior to actually
''' writing them to a script. If this is not necessary the interaction
''' could be written to the script immediately.
''' </remarks>
'''--------------------------------------------------------------------
Private Sub Playback(ByVal targetApp As AutomationElement)

    Dim element As AutomationElement
    Dim storedItem As ElementStore
    For Each storedItem In uiautoWorker.elementQueue
        Dim propertyCondition As New PropertyCondition( _
        AutomationElement.AutomationIdProperty, storedItem.AutomationID)
        ' Confirm the existence of a control.
        ' Depending on the controls and complexity of interaction
        ' this step may not be necessary or may require additional
        ' functionality. For example, to confirm the existence of a
        ' child menu item that had been invoked the parent menu item
        ' would have to be expanded.
        element = targetApp.FindFirst( _
        TreeScope.Descendants, propertyCondition)
        If element Is Nothing Then
            ' Control not available, unable to continue.
            ' TODO: Handle error condition.
            Return
        End If
        WriteToScript(storedItem.AutomationID, storedItem.EventID)
    Next storedItem

End Sub


'''--------------------------------------------------------------------
''' <summary>
''' Generates script code and outputs the code to a text control in
''' the client.
''' </summary>
''' <param name="automationID">
''' The AutomationID of the current control.
''' </param>
''' <param name="eventID">
''' The event recorded on that control.
''' </param>
'''--------------------------------------------------------------------
Private Sub WriteToScript( _
ByVal automationID As String, ByVal eventID As String)

    ' Script code would be generated and written to an output file
    ' as plain text at this point, but for the
    ' purposes of this example we just write to the console.
    Console.WriteLine(automationID + " - " + eventID)

End Sub

Relatív elérési út használata egy korábban azonosított AutomationElementhez való visszatéréshez

  • Bizonyos körülmények között, mivel az AutomationID csak a testvérek között garantáltan egyedi, a UI-automatizálás fa több eleme azonos AutomationID tulajdonságértékekkel rendelkezhet. Ezekben az esetekben az elemek egyedileg azonosíthatók a szülő és szükség esetén a nagyszülő alapján. Egy fejlesztő például több menüelemből álló menüsávot biztosíthat, amelyben több gyermekmenüelem található, amelyekben a gyermekeket szekvenciális AutomationID azonosítóval azonosítják, például "Item1", "Item2" stb. Ezután minden egyes menüpontot egyedileg azonosíthat az AutomationID, valamint a szülőjének és szükség esetén a nagyszülőjének AutomationID azonosítójával.

Lásd még