Nicht schon wieder! Noch ein kaputter Selektor...

Einige Frontend-Codeänderungen wurden vorgenommen und die Regression ist fehlgeschlagen! Plötzlich können Tests ihre Elemente nicht finden. Erst dann wird klar, dass nicht der Code kaputt gegangen ist, sondern die Test-Selektoren selbst nicht mehr funktionieren.
Klingt vertraut?
Es ist mir und vielen anderen, die ich gesehen habe, sicherlich passiert. Wenn es dir noch nicht passiert ist, kannst du dich glücklich schätzen, oder vielleicht hast du schon einen Weg gefunden, deine Selektoren widerstandsfähig zu machen 😉.
Dies ist ein Problem, mit dem wir bei FloQast zu oft konfrontiert waren, aber wir haben einige Schritte unternommen, um es zu bekämpfen, und ich möchte einen Ansatz teilen, den wir gewählt haben und was ich gefunden habe.
Niveaus von Sprödigkeit — Wie Selektoren dazu neigen, zu brechen, und Beispiele dafür, was sie kaputt macht
CSS-Selektoren werden in allen Beispielen verwendet, sofern nicht anders angegeben. Dieselben Prinzipien/Ansätze können auch auf XPath angewendet werden.
Lassen Sie uns zunächst einen Blick auf gängige Selektoren werfen und herausfinden, wie sie uns im Stich lassen können. Wenn Sie bereits mit diesem Teil vertraut sind oder diesen Teil überspringen möchten, scrollen Sie bitte zu Datenattribute unten!
Ein Beispiel für einen Worst Case
div > div > div > div:nth-child(2) > div > ul > li:nth-child(5) > div > div + div > div > button
Dieser gibt mir nur Albträume Nein! Vorsicht! Schlag nicht drauf!


Okay, genau den habe ich nicht gesehen, aber ähnliche! Und sie alle haben mir im Grunde genommen das Gefühl gegeben, genau so zu sein.
Warum? Es ist definitiv spezifisch. Aber es ist mit einer strengen Reihenfolge generischer Teile gebaut.
Es ist so, als würde man sagen, suche eine Karte einer Stadt und finde eine bestimmte Art von Geschäft in einem Gebäude in einem Einkaufsblock, der direkt nach einem anderen Einkaufsblock in seiner Straße ist, die 5. Straße in der zweiten Region... nun, du verstehst schon, worum es geht.
Schauen wir uns einige dieser und anderer spröder Selektorteile an und sehen wir uns Beispiele an, wie sie kaputt gehen können.
Leicht zerbrechlich
In unserer Analogie war es spezifisch und bringt Sie möglicherweise zum gewünschten Geschäft, das dieser Kombination eindeutig entspricht (oder zufällig das erste ist, das dazu passt). Das Gleiche gilt für diesen Selektor.
Hier sind einige Arten von Sprödfindungsstücken, angefangen mit den sprödesten:
- Untergeordnete Operatoren, Indizes und andere präzise relationale Teile -
* > * + * *:nth-kind (n)
- Tag-Namen -
div ul li div button a
- Einige Attribute -
[deaktiviert]
[geprüft]
[Typ = Text]
- Text - (mit XPath, da nur Text verwendet werden kann)
//* [enthält (text (), „Juni“)]
Ich habe gesehen, wie sie alle kaputt gegangen sind, und das nicht ungewöhnlich. Hier sind einige Möglichkeiten, wie sie kaputt gehen können:
- Ein Element wird hinzugefügt oder entfernt, wodurch relationale Teile (oder Text!) zerstört werden
- Ein Tag-Name wurde geändert - das ist einfach für einen Entwickler! Zum Beispiel kann eine td, li oder sogar eine Schaltfläche in eine Div-Schaltfläche geändert und so gestaltet werden, dass sie genauso funktioniert/aussieht.
- Ein Attribut wurde geändert oder existiert nicht mehr
- Text wird aktualisiert, Leerzeichen verursachen Probleme (wie bei hinzugefügten Elementen) oder wenn Sie internationalisieren und in einer der Sprachen testen möchten
Diese sind zwar sehr spröde, aber einige weniger spröde, häufig verwendete Selektoren sind immer noch verfügbar.
Widerstandsfähiger — Klassen
Von der weniger spröden Variante gängiger Selektoren, Klassen (.monatspicker
) sind wahrscheinlich die häufigsten. Jedes kann sich auf beliebig viele Elemente beziehen, dynamisch sein und wirklich die meisten Fälle bewältigen. Obwohl sie nicht so widerstandsfähig sind wie IDs, sind sie dennoch relativ widerstandsfähig und flexibler und benutzerfreundlicher. Wenn Sie keine robusteren Optionen haben, sind Klassen im Allgemeinen gut zu verwenden, und es können beliebig viele hinzugefügt werden, ohne dass sich dies auf irgendetwas auswirkt, wenn sie unterschiedliche Namen haben.
Bei diesen gibt es nur ein Hauptproblem: Ihr Hauptzweck ist das Styling und der App-Code!
- Wenn das Unternehmen zu so etwas wechselt gestylte Komponenten, die Klassen können unlesbar verändert oder zumindest erweitert werden (z. B. mit Namen vorindiziert)
- Entwickler können sie je nach Bedarf jederzeit hinzufügen, entfernen und umbenennen
- Entwickler werden wahrscheinlich nicht wissen, welche tatsächlich zum Testen oder für andere Zwecke verwendet werden
- Es sei denn, Sie erstellen und markieren sie speziell zum Testen, was diese zu einer besseren Option macht, aber dennoch einige Risiken und andere Probleme mit sich bringen kann
Der robusteste aller allgemein verfügbaren Ansätze - id
Eine ID (#export -Button
) ist die robusteste und einfachste Option der gängigen Selektoren. Warum? Aus einem Hauptgrund: Sie zielen auf ein einzigartiges Element auf der Seite ab (oder zumindest sollte). Wenn Sie also auf dieses bestimmte Element abzielen möchten, können Sie einfach die ID verwenden, und es wird nichts anderes ausgewählt. Da sie so zielgerichtet sind und nicht so oft wie Klassen für Styling-Zwecke verwendet werden, ist es auch weniger wahrscheinlich, dass sie geändert oder entfernt werden, und es ist normalerweise klar, was sie sind.
Es gibt jedoch einige Nachteile:
- Es gibt normalerweise nicht so viele von ihnen, und daher helfen sie bei den meisten Selektoren nicht
- Nicht hilfreich für nicht eindeutige Elemente
- Nicht gut/zum Speichern dynamischer Werte gedacht
Gibt es eine Möglichkeit, extrem belastbare Selektoren zu haben, die für jeden potenziellen Bedarf flexibel sind und so viele hinzufügen können, wie wir möchten?
Datenattribute sind die Rettung!

Einer der Hauptansätze, die wir bei FloqAst gewählt haben, um unsere Selektoren widerstandsfähiger und flexibler zu machen, besteht darin, die folgenden Vorteile zu nutzen Daten-
Attribute.
Was sind Datenattribute?
Datenattribute sind jedes HTML-Attribut, das mit beginnt Daten-
. Sie werden von allem, was mit HTML zu tun hat, völlig ignoriert und haben daher kein Risiko die Seite oder Funktionalität durch irgendetwas anderes zu beeinflussen. Und du kannst so viele erstellen, wie du willst!
Wie haben wir sie benutzt?
Wir haben sie zwar für verschiedene Zwecke verwendet, z. B. zum Speichern eines Komponentennamens auf dem äußersten Element oder für die Rolle eines Elements innerhalb der Komponente, aber wir haben uns auch getroffen und uns darauf geeinigt, einen QE-spezifischen „Namespace“ vorzusehen! Wir haben die Kontrolle über und es steht uns frei, so viele Attribute zu haben, wie wir wollen, damit beginnen Daten-q-
.
Dies ermöglicht uns alle möglichen zuverlässigen und dennoch flexiblen Selektoren. Möchten Sie eine Standard-CSS-ID nachahmen, um ein einzigartiges Element auszuwählen? data-qe-id="Export-Button“
! Möchten Sie einen Menüpunkt auswählen, ohne Text verwenden zu müssen? [Datenkomponentenname="Monatsauswahl "] [Daten-QE-Option="März"]
! Wie wäre es mit einer bestimmten Zeile einer Tabelle? [data-qe-account-row="1000 Bargeld "]
! Sie können sogar Daten speichern und abrufen, nicht nur zur Auswahl!
Warum sind diese so hilfreich?
- Es ist viel weniger wahrscheinlich, dass sie sich ändern. Diejenigen, die einem bestimmten Zweck wie data-qe-* gewidmet sind, sind praktisch unzerbrechlich, da niemand einen Grund haben sollte, sie für einen anderen Zweck anzufassen!
- Wenn sie gut benannt sind, können sie sehr deutlich machen, was sie sind, und die Lesbarkeit Ihres Codes verbessern
- Beides Name und Wert kann mit diesen spezifiziert werden!
- Sie können ohne Risiko für die App oder den Benutzer hinzugefügt werden.
- Bezieht sich auf einen obigen Punkt, aber da IDs und Klassen in erster Linie für das Styling und den App-Code gedacht sind und von Entwicklern leicht geändert werden können, ohne zu wissen, dass bestimmte Klassen für einen anderen Zweck bestimmt sind, entwirrt es die beiden Verwendungszwecke und behebt alle damit verbundenen Probleme
- Sie können Namen und/oder Daten enthalten, die als IDs, Klassen usw. keinen Sinn ergeben, und können auch die Notwendigkeit einer Textauswahl überflüssig machen
Also, obwohl nicht so kurz wie id (#export -Button
) oder class (.monatspicker
) und auf Zeichenkettenwerte beschränkt, sind sie dennoch kurz und können für noch mehr Klarheit und Flexibilität sorgen.
Wir haben vor über einem Jahr angefangen, diese zu verwenden. Seit wir sie eingeführt haben, haben sie sich als immer wertvoller und notwendiger erwiesen, zum Beispiel als Klassen anfingen, zu verschwinden (oder besser gesagt, verstümmelt zu werden), weil sie verwendet wurden gestylte Komponenten. Da das Muster bereits vorhanden war, waren wir auf diese Änderungen vorbereitet.
Zusammenfassung
Selektoren sind einer der häufigsten Gründe, warum automatisierte UI-Tests fehlschlagen. Scheinbar unbedeutende Codeänderungen können bei ahnungslosen Tests, deren Selektoren zu spröde sind, verheerende Folgen haben. Es macht einen großen Unterschied, die sprödesten Operatoren zu vermeiden, wie z. B. die Verwendung von relationalen Operatoren, aber wir können auch praktisch unzerstörbare Selektoren mithilfe von Datenattributen erstellen.
Wir sind zwar nicht die einzigen, die einen ähnlichen Ansatz verwenden (data-testid wird immer beliebter), aber ich habe unseren data-qe-Namespace-Ansatz sehr geschätzt, der sich nicht auf IDs beschränkt und unseren Attributen und Selektoren unglaubliche Flexibilität und Klarheit verleiht. Und ich muss mich nicht mehr so sehr vor dem unvermeidlichen Untergang spröder Selektoren fürchten 😊.
Wir haben auch andere Strategien implementiert, um unsere Tests zu verbessern und die Wartung zu vereinfachen, wie z. B. nicht nur Seitenobjekte, sondern auch Seitenkomponentenobjekte, die gezielte Selektoren innerhalb bestimmter enthaltender Elemente enthalten. Das ist jedoch insgesamt ein größeres Thema als der Umfang dieses Beitrags. Zum Zeitpunkt des Schreibens haben wir zwar noch keinen Beitrag dazu, aber schauen Sie sich einige unserer anderen Artikel an, z. B. einen kürzlich erschienenen über Konsolidierung der Behauptung!