Mester XPath i Selenium: Finn elementer effektivt!

Testingeniører spiller en sentral rolle i programvareutviklingsprosessen, der de sikrer at et team produserer applikasjoner som er fri for feil og fungerer som forventet. Disse spesialistene utsetter applikasjonene for en rekke tester før de lanseres eller erklæres klare for bruk.

Det er avgjørende at testere er kompetente i å finne og samhandle med elementer på nettsider. Selenium er et ledende verktøy for testautomatisering, populært blant moderne utviklingsteam. Dette verktøyet består av fire hovedkomponenter: Selenium Grid, Selenium WebDriver, Selenium IDE og Selenium RC.

I dag fokuserer vi spesielt på Selenium WebDriver, som inkluderer XPath. Denne artikkelen gir en innføring i XPath, utforsker den grunnleggende syntaksen og illustrerer bruken av XPath med Selenium.

Hva er XPath

XPath (XML Path Language) er et spørrespråk designet for å velge og navigere i attributter og elementer i XML-dokumenter. XPath definerer et stiuttrykk som gjør det mulig å adressere spesifikke deler av et XML-dokument og hente informasjon derfra.

Syntaksen minner om en filsystemsti. Den inneholder også funksjoner og symboler som forenkler valg av elementer basert på attributter og hierarki. XPath kan brukes med teknologier som XML, HTML og XSLT for å trekke ut og manipulere data.

Hvorfor bruke XPath?

  • Fleksibel: I motsetning til CSS-selektorer som begrenser seg til å finne elementer med tagnavn, ID eller klasse, gir XPath mulighet til å finne elementer ved hjelp av ulike attributter.
  • Gjenbrukbar: XPath-uttrykk kan lagres i variabler og gjenbrukes i koden.
  • Presis nodevalg: XPath tilbyr en standardisert metode for å målrette mot spesifikke elementer i et nettdokument.

Grunnleggende syntaks for XPath

XPath lar deg lokalisere ethvert element på en nettside ved hjelp av DOM. Før vi går inn på syntaksen, er det viktig å forstå følgende XPath-uttrykk:

Uttrykk Beskrivelse
nodename/tagname Velger alle noder med navn «nodename» eller «tagname»
/ Velger fra rotnoden
// Velger noder i det gjeldende dokumentet som samsvarer med valget, uavhengig av hvor de er
@ Velger attributter
.. Velger forelderen til gjeldende node
. Velger gjeldende node

Standard syntaks for XPath er:

XPath=//tagname[@attribute="value"]

Som vist, begynner syntaksen med en dobbel skråstrek (//), som starter fra den gjeldende noden, definert av tag-/nodenavnet.

Absolutt XPath vs. relativ XPath

Det finnes to tilnærminger når man jobber med XPath: Absolutt XPath og relativ XPath.

Absolutt XPath

En absolutt XPath gir en direkte sti fra rot til ønsket element. Stien begynner med rotnoden og ender med målnoden.

Tenk deg et HTML-dokument med følgende struktur:

<!DOCTYPE html>
<html>
<head>
    <title>tipsbilk.net</title>
</head>
<body>
    <div>
        <h1>Velkommen til tipsbilk.net</h1>
    </div>
</body>
</html>

For å finne elementet med teksten «Velkommen til tipsbilk.net», følger vi denne stien:

/html/body/div/h1

I dokumentet over har vi:

  • HTML som rotnoden: /html
  • Body som en overordnet node: /html/body
  • Div som et barn av body-noden: /html/body/div
  • H1 som en underordnet div-noden: /html/body/div/h1

For å nå det innerste elementet, må man følge hele stien.

Når bør du bruke absolutt XPath?

Absolutt XPath følger en spesifikk sti. Den er derfor ideell når det finnes flere elementer med lignende attributter på en side, og man ønsker å være sikker på at de eksakte elementene i dokumentet blir målrettet.

Men absolutt XPath er veldig følsom for endringer i HTML-dokumentets struktur. En enkel endring kan bryte en absolutt XPath.

Relativ XPath

Relativ XPath starter fra en hvilken som helst node og ender med målnoden. Stien påvirkes ikke av endringer i dokumentet, noe som gjør den foretrukket i de fleste situasjoner. Med relativ XPath er det mulig å finne elementer fra alle deler av dokumentet. Et relativt XPath-uttrykk begynner med doble skråstreker «//».

Hvis vi ser på det samme HTML-dokumentet, kan vi finne H1 som sier «Velkommen til tipsbilk.net» ved hjelp av:

<!DOCTYPE html>
<html>
<head>
    <title>tipsbilk.net</title>
</head>
<body>
    <div>
        <h1>Velkommen til tipsbilk.net</h1>
    </div>
</body>
</html>

Vår relative XPath for h1 vil være:

//body/div/h1

Når bør du bruke relativ XPath?

Relativ XPath bør brukes når man ønsker en balanse mellom fleksibilitet og spesifisitet. Stien er motstandsdyktig mot endringer i HTML-dokumentet, gitt at forholdet mellom elementene forblir konstant.

Finn elementer ved hjelp av XPath i Selenium

Selenium er et åpen kildekode-rammeverk som lar brukere automatisere nettlesere. Rammeverket inneholder en samling av biblioteker og verktøy som hjelper testere med å samhandle med elementer på nettsider på en automatisert og systematisk måte.

La oss si vi har et nettdokument som inneholder en liste over sanger:

<!DOCTYPE html>
<html>
<head>
    <title>Sangbibliotek</title>
</head>
<body>
    <h1>Sangbibliotek</h1>
    <ul class="song-list">
        <li class="song" title="Sangtittel 1">Sang 1 - Artist 1</li>
        <li class="song" title="Sangtittel 2">Sang 2 - Artist 2</li>
        <li class="song" title="Sangtittel 3">Sang 3 - Artist 1</li>
        <li class="song" title="Sangtittel 4">Sang 4 - Artist 3</li>
    </ul>
</body>
</html>
  • Rotnoden vår er <html>.
  • Vi har <body> som vår overordnede node.
  • Vi har <h1> som et barn av <body>.
  • Vi har <ul> som et barn av <body>.
  • Vi har <li> som et barn av <ul>.

Vi kan bruke forskjellige XPath-lokalisere i HTML-dokumentet over. Vi kan for eksempel finne elementer etter ID, navn, klassenavn, inneholder, tekster, slutter-med og starter-med, blant mange andre lokaliseringstyper. Selenium kan brukes med ulike programmeringsspråk. Vi vil bruke Python som eksempel.

Finn etter indeks

Hvis vi ønsker å finne sang nummer 3, kan vi bruke følgende kode:

third_song = driver.find_element_by_xpath("//li[@class="song"][3]")
print("Third Song:", third_song.text)

Vi har brukt relativ XPath og starter med «li»-noden. Når Selenium finner den tredje sangen i listen, skrives teksten ut.

Finn etter attributt

Vi kan lage en XPath som ser etter alle sangene fra «Artist 1» og skriver ut titlene deres. Koden kan være som følger:

songs_by_artist1 = driver.find_elements_by_xpath("//li[contains(@class, 'song') and contains(text(), 'Artist 1')]")
print("Songs by Artist 1:")
for song in songs_by_artist1:
    print(song.text)

Finn etter tekst

Denne lokalisatoren hjelper deg med å finne elementer med en bestemt tekst. Vi kan lete etter en sang med teksten «Sang 4» og skrive ut teksten. Dette kan vi gjøre med følgende kode:

song_with_text = driver.find_element_by_xpath("//li[contains(text(), 'Sang 4')]")
print("Song with Text:", song_with_text.text)

XPath-akser

Metodene vi har sett på til nå fungerer utmerket med enkle nettsider. Men det finnes tilfeller der XPath-søkelementmetoder som etter tekst, ID, klassenavn og navn ikke fungerer.

XPath-akser brukes for dynamisk innhold der vanlige lokalisere ikke er tilstrekkelige. Her finner man elementer basert på deres relasjon til andre elementer. Dette er noen av de vanligste XPath-aksene:

Stamfar

Ancestor Axis-metoden er ideell for å håndtere XML-dokumenter med svært nestede elementer. Man kan velge alle stamfarelementer, som besteforeldre og foreldre, til gjeldende node fra den nærmeste til den fjerneste.

La oss si at vi har følgende kode:

<bookstore>
  <book>
    <title>The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <genre>Fiction</genre>
  </book>
  <book>
    <title>The Biggest Dilemma</title>
    <author>George Orwell</author>
    <genre>Dystopian</genre>
  </book>
</bookstore>

Hvis vi ønsker å velge alle forfedrene til elementet «tittel» for boken «The Biggest Dilemma», kan vi bruke denne Ancestor Axis-metoden:

//title[text() = '1984']/ancestor::*

Følgende

Following Axis-metoden lokaliserer alle noder etter gjeldende nodes sluttag. Denne metoden ignorerer hierarkiet og plasseringen til målnodene. Hvis du har et XML-dokument eller en nettside med flere seksjoner, kan du identifisere et element som vises etter en bestemt seksjon uten å navigere i hele trestrukturen.

Forelder

Parent Axis-metoden i XPath velger forelderen til gjeldende node. Du kan bruke følgende sti for å finne den overordnede noden:

//tag[@attribute="value"]/parent::tagName

Denne metoden fungerer når de underordnede elementene til gjeldende node har unike attributter som er lette å finne, og du ønsker å bekrefte med den overordnede noden.

Barn

Child Axis-metoden i XPath velger alle barna til gjeldende node. Det er fortsatt en av de mest brukte XPath Axis-metodene, ettersom den hjelper med å velge underordnede noder til et spesifikt element.

Se på denne kodebiten:

<section id='text'>
    <p>Avsnitt en</p>
    <p>Avsnitt to</p>
    <p>Avsnitt tre</p>
    <p>Avsnitt fire</p>
</section>

Vi kan finne alle «p»-elementene i koden ved hjelp av denne aksen:

//section[@id='text']/child::p

Vanlige spørsmål

Hvorfor bruke XPath i stedet for CSS-velgere?

CSS-velgere kan kun finne elementer basert på ID, tagnavn og klasse. Med XPath kan du derimot finne elementer basert på plassering, tekstinnhold og andre attributter i HTML-strukturen. Du kan også lagre XPath-uttrykk i variabler og gjenbruke dem i applikasjonen din.

Hvilke språk støtter XPath i Selenium?

XPath kan brukes med alle språk som støtter Selenium. Du kan skrive skript i JavaScript, Java, Python, Ruby, C# og PHP.

Hva er alternativene til XPath?

Du kan bruke CSS-velgere, bildegjenkjenning eller Seleniums innebygde lokalisere som et alternativ til XPath. CSS-velgere er de mest vanlige, og du kan finne elementer basert på tagnavn, ID eller klasse. Bildegjenkjenning lar deg finne elementer basert på bildene deres. Seleniums innebygde lokalisere er designet for å være enkle å bruke.

Konklusjon

Du vet nå hva XPath i Selenium er, forskjellen på absolutt og relativ XPath, og hvordan du lokaliserer elementer ved hjelp av ulike XPath-lokalisere. Valget av lokalisator avhenger av innholdets art og de spesifikke målene du har.

Ta gjerne en titt på artikkelen vår om Selenium-intervjuspørsmål hvis du vil forberede deg til ditt neste intervju.