Έμμεση και ρητή αναμονή Selenium με Σύνταξη
⚡ Έξυπνη Σύνοψη
Selenium Οι εντολές αναμονής συγχρονίζουν τα σενάρια αυτοματοποίησης με τη δυναμική συμπεριφορά της σελίδας, αποτρέποντας τις αποτυχίες των δοκιμών που προκαλούνται από στοιχεία που φορτώνουν ασύγχρονα. Αυτή η αναφορά εξηγεί τις στρατηγικές έμμεσης, ρητής και ρευστής αναμονής με σύνταξη WebDriver, που λειτουργούν. Java δείγματα κώδικα και πρακτικές οδηγίες σχετικά με την επιλογή της κατάλληλης αναμονής για σταθερή και αξιόπιστη εκτέλεση δοκιμών.
In Selenium, Οι εντολές "Waits" παίζουν σημαντικό ρόλο στην εκτέλεση αξιόπιστων δοκιμών. Σε αυτό το σεμινάριο, θα μάθετε τις βασικές πτυχές και τις διαφορές μεταξύ των εντολών Implicit και Explicit Wait στο Selenium, μαζί με την πρακτική χρήση του Fluent Wait.
Γιατί χρειαζόμαστε αναμονή Selenium?
Οι περισσότερες σύγχρονες διαδικτυακές εφαρμογές αναπτύσσονται χρησιμοποιώντας Ajax JavaΓραφήΌταν μια σελίδα φορτώνεται από το πρόγραμμα περιήγησης, τα στοιχεία με τα οποία θέλουμε να αλληλεπιδράσουμε ενδέχεται να φορτώνονται σε διαφορετικά χρονικά διαστήματα.
Αυτό όχι μόνο δυσχεραίνει την αναγνώριση του στοιχείου, αλλά αν το στοιχείο δεν εντοπιστεί χρονικά, Selenium θα ρίξει ένα ElementNotVisibleException. Selenium Οι αναμονές επιλύουν αυτό το πρόβλημα συγχρονισμού δίνοντας στο WebDriver ένα καθορισμένο παράθυρο στο οποίο μπορεί να βρει ένα στοιχείο πριν αποτύχει.
Εξετάστε ένα σενάριο στο οποίο χρησιμοποιούνται τόσο έμμεσες όσο και ρητές αναμονές στην ίδια δοκιμή. Ας υποθέσουμε ότι η έμμεση αναμονή έχει οριστεί σε 20 δευτερόλεπτα και η ρητή αναμονή έχει οριστεί σε 10 δευτερόλεπτα.
Αν ψάχνουμε για ένα στοιχείο που διέπεται από συγκεκριμένα Αναμενόμενες Συνθήκες (Explicit Wait) και το στοιχείο δεν βρίσκεται εντός του ρητού παραθύρου των 10 δευτερολέπτων, το WebDriver επιστρέφει στο έμμεσο παράθυρο των 20 δευτερολέπτων πριν ρίξει ένα ElementNotVisibleException.
Selenium Το WebDriver περιμένει
- Σιωπηρή αναμονή
- Άμεση αναμονή
- Γρήγορη αναμονή
Σιωπηρή Αναμονή Selenium
The Σιωπηρή Αναμονή Selenium Δίνει εντολή στο WebDriver να περιμένει για ένα καθορισμένο χρονικό διάστημα πριν ενεργοποιήσει ένα NoSuchElementException. Η προεπιλεγμένη τιμή είναι 0. Μόλις ρυθμιστεί, το WebDriver πραγματοποιεί αναζήτηση στο DOM κατά τη διάρκεια αυτού του χρονικού διαστήματος πριν αποτύχει. Selenium Το WebDriver κληρονόμησε την έννοια των έμμεσων αναμονών από Watir.
Στο παρακάτω παράδειγμα, δηλώνουμε μια έμμεση αναμονή με διάρκεια 10 δευτερολέπτων. Εάν το στοιχείο δεν βρίσκεται μέσα σε αυτό το παράθυρο, δημιουργείται μια εξαίρεση.
Σύνταξη έμμεσης αναμονής (Selenium 4):
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
package guru.test99;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
public class AppTest {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
String eTitle = "Demo Guru99 Page";
String aTitle = "";
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.equals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
// close browser
driver.close();
}
}
Επεξήγηση του Code
Στο παραπάνω παράδειγμα, λάβετε υπόψη την ακόλουθη δήλωση:
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
Selenium Το 4 αντικατέστησε την παλαιότερη υπογραφή δύο ορισμάτων (ακέραιος αριθμός συν TimeUnit) με ένα μόνο όρισμα Duration. Η κλάση Duration υποστηρίζει δευτερόλεπτα, λεπτά, χιλιοστά του δευτερολέπτου και άλλες μονάδες χρόνου μέσω στατικών βοηθών όπως Duration.ofSeconds, Duration.ofMillis και Duration.ofMinutes.
Ρητή Αναμονή Selenium
The Ρητή Αναμονή Selenium Δίνει εντολή στο WebDriver να περιμένει συγκεκριμένες συνθήκες (Αναμενόμενες Συνθήκες) ή μια μέγιστη διάρκεια πριν ρίξει ένα ElementNotVisibleException. Είναι μια πιο έξυπνη αναμονή επειδή ισχύει μόνο για το καθορισμένο στοιχείο. Η ρητή αναμονή προτιμάται έναντι της έμμεσης αναμονής κάθε φορά που η δοκιμή χρειάζεται να χειριστεί δυναμικά φορτωμένο περιεχόμενο Ajax.
Μόλις δηλωθεί ρητή αναμονή, πρέπει να χρησιμοποιήσετε Αναμενόμενες Συνθήκεςή μπορείτε να διαμορφώσετε τη συχνότητα σταθμοσκόπησης χρησιμοποιώντας Γρήγορη αναμονή. Αποφύγετε τη χρήση Thread.sleep(), καθώς διακόπτει την εκτέλεση άνευ όρων και γενικά θεωρείται κακή πρακτική.
Στο παρακάτω παράδειγμα, δημιουργούμε μια αναφορά του WebDriverΠεριμένετε κλάση, δημιουργήστε την με το Πρόγραμμα οδήγησης Web αναφορά και διαμορφώστε ένα μέγιστο παράθυρο 20 δευτερολέπτων.
Σύνταξη ρητής αναμονής (Selenium 4):
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
package guru.test99;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
public class AppTest2 {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
String eTitle = "Demo Guru99 Page";
String aTitle = "";
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.contentEquals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
WebElement guru99seleniumlink;
guru99seleniumlink = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
guru99seleniumlink.click();
}
}
Επεξήγηση του Code
Σκεφτείτε τον ακόλουθο κώδικα:
WebElement guru99seleniumlink;
guru99seleniumlink = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
guru99seleniumlink.click();
Σε αυτό το παράδειγμα WebDriverWait, το σενάριο περιμένει έως και 20 δευτερόλεπτα, όπως ορίζεται από το WebDriverΠεριμένετε τάξη, μέχρι το Αναμενόμενες Συνθήκες ικανοποιούνται — όποιο από τα δύο συμβεί πρώτο.
Τα παραπάνω Java Ο κώδικας περιμένει έως και 20 δευτερόλεπτα για την συνθήκη ορατότηταΕντοπισμένουΣτοιχείου να είναι αλήθεια.
Οι ακόλουθες Αναμενόμενες Συνθήκες μπορούν να χρησιμοποιηθούν σε Selenium Ρητή αναμονή:
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvailableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- presentOfAllElementsLocatedBy()
- presentOfElementLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleΠεριέχει()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
Άνετο Wait in Selenium
The Άνετο Wait in Selenium ορίζει τη μέγιστη διάρκεια αναμονής του WebDriver για μια συνθήκη, μαζί με τη συχνότητα ανίχνευσης για την επαλήθευση αυτής της συνθήκης πριν από την εκτέλεση ενός ElementNotVisibleException. Το Fluent Wait ελέγχει για το στοιχείο σε τακτά χρονικά διαστήματα μέχρι να βρεθεί το αντικείμενο ή να λήξει το χρονικό όριο.
Συχνότητα: Ο κύκλος επανάληψης για την αξιολόγηση της κατάστασης σε τακτά χρονικά διαστήματα.
Σκεφτείτε ένα σενάριο όπου ένα στοιχείο φορτώνει σε απρόβλεπτα χρονικά διαστήματα. Το στοιχείο μπορεί να φορτώσει σε 10 δευτερόλεπτα, 20 δευτερόλεπτα ή περισσότερο. Εάν δηλώσουμε μια ρητή αναμονή 20 δευτερολέπτων, το σενάριο θα περιμένει για όλη τη διάρκεια πριν αποτύχει. Σε τέτοιες περιπτώσεις, το Fluent Wait είναι η ιδανική επιλογή επειδή πραγματοποιεί βολές στην καθορισμένη συχνότητα μέχρι να εντοπιστεί το στοιχείο ή να λήξει ο τελικός χρονοδιακόπτης.
Σύνταξη Fluent Wait (Selenium 4):
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
Η παλαιότερη υπογραφή που δεχόταν ακέραιες τιμές συν Μονάδα Χρόνου καταργήθηκε το Selenium 3.11 και αφαιρέθηκε στο Selenium 4. Το API που βασίζεται στη διάρκεια και εμφανίζεται παραπάνω είναι η τρέχουσα συνιστώμενη προσέγγιση.
package guru.test99;
import java.time.Duration;
import java.util.NoSuchElementException;
import java.util.function.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.testng.annotations.Test;
public class AppTest3 {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
String eTitle = "Demo Guru99 Page";
String aTitle = "";
driver = new ChromeDriver();
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.contentEquals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
WebElement clickseleniumlink = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
}
});
// click on the selenium link
clickseleniumlink.click();
// close browser
driver.close();
}
}
Επεξήγηση του Code
Σκεφτείτε τον ακόλουθο κώδικα:
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
Στο παραπάνω παράδειγμα, δηλώνουμε μια Fluent Wait με χρονικό όριο 30 δευτερολέπτων, συχνότητα polling 5 δευτερολέπτων και αγνοούμε NoSuchElementException.
Σκεφτείτε τον ακόλουθο κώδικα:
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
}
Αυτή η συνάρτηση προσδιορίζει το WebElement στη σελίδα (εδώ, το Selenium σύνδεσμος στην αρχική σελίδα). Με διάστημα polling 5 δευτερολέπτων και χρονικό όριο 30 δευτερολέπτων, η αναμονή ελέγχει για το στοιχείο κάθε 5 δευτερόλεπτα για μέγιστο διάστημα 30 δευτερολέπτων. Εάν το στοιχείο βρίσκεται μέσα σε αυτό το παράθυρο, το σενάριο συνεχίζεται. Διαφορετικά, ένα ElementNotVisibleException ρίχνεται.
Επίσης ελέγξτε: Selenium Εκμάθηση IDE για αρχάριους
Διαφορά μεταξύ σιωπηρής αναμονής έναντι ρητής αναμονής
Ο παρακάτω πίνακας επισημαίνει τις βασικές διαφορές μεταξύ της έμμεσης και της ρητής αναμονής. Selenium.
| Σιωπηρή αναμονή | Άμεση αναμονή |
|---|---|
| Ο έμμεσος χρόνος αναμονής εφαρμόζεται σε όλα τα στοιχεία του σεναρίου. | Ο ρητός χρόνος αναμονής εφαρμόζεται μόνο στα στοιχεία που στοχεύονται συγκεκριμένα. |
| Στην Implicit Wait, οι ExpectedConditions δεν καθορίζονται για το στοιχείο. | Στην Explicit Wait, πρέπει να οριστούν οι ExpectedConditions για το στοιχείο. |
| Συνιστάται όταν τα στοιχεία φορτώνονται εντός του διαμορφωμένου έμμεσου παραθύρου αναμονής. | Συνιστάται όταν τα στοιχεία χρειάζονται περισσότερο χρόνο για να φορτώσουν και κατά την επικύρωση καταστάσεων στοιχείων όπως visibilityOfElementLocated, elementToBeClickable ή elementToBeSelected. |
| Ορίζεται μία φορά και εφαρμόζεται για τον κύκλο ζωής της παρουσίας του WebDriver. | Ορισμός ανά στοιχείο ή ανά έλεγχο, παρέχοντας καλύτερο έλεγχο. |
Πώς να επιλέξετε τη σωστή στρατηγική αναμονής
Η επιλογή της σωστής εντολής αναμονής επηρεάζει άμεσα τη σταθερότητα του σεναρίου και τον χρόνο εκτέλεσης. Χρησιμοποιήστε αυτό το πλαίσιο λήψης αποφάσεων για να επιλέξετε την κατάλληλη επιλογή για κάθε σενάριο.
- Προσδιορίστε το μοτίβο φόρτωσης: Ελέγξτε εάν το στοιχείο εμφανίζεται σε καθορισμένη χρονική στιγμή, μετά την απόκριση Ajax ή σε απρόβλεπτα χρονικά διαστήματα. Τα σταθερά φορτία ταιριάζουν στην Implicit Wait, ενώ τα απρόβλεπτα φορτία απαιτούν Fluent Wait.
- Αποφύγετε την ανάμειξη έμμεσων και ρητών αναμονών: Ο συνδυασμός των δύο μπορεί να προκαλέσει απροσδόκητες καθυστερήσεις, επειδή η μεγαλύτερη αναμονή μπορεί να κυριαρχήσει. Selenium Η τεκμηρίωση συνιστά τη χρήση μόνο μίας στρατηγικής ανά συνεδρία WebDriver.
- Προεπιλογή σε ρητή. Περιμένετε για δυναμικό περιεχόμενο: Όταν οι σελίδες εξαρτώνται από Ajax, απόδοση υπό όρους ή κινούμενα σχέδια, η λειτουργία Explicit Wait με ExpectedConditions στοχεύει ακριβώς το στοιχείο που έχει σημασία.
- Χρησιμοποιήστε το Fluent Wait για μεταβλητό χρονισμό: Όταν ο χρόνος φόρτωσης στοιχείων ποικίλλει μεταξύ των εκτελέσεων, διαμορφώστε το Fluent Wait με ένα διάστημα polling. Η polling μειώνει τον συνολικό χρόνο αναμονής σε σύγκριση με ένα μόνο μεγάλο χρονικό όριο.
- Αντικατάσταση του Thread.sleep: Οι ενσωματωμένες αναμονές ύπνου επιβραδύνουν τις σουίτες δοκιμών και αποκρύπτουν προβλήματα πραγματικού χρονισμού. Αντικαταστήστε τες με αναμονές υπό όρους για να διατηρήσετε την εκτέλεση γρήγορη και ντετερμινιστική.
- Τιμές χρονικού ορίου συντονισμού: Ξεκινήστε με σύντομα χρονικά όρια (5–10 δευτερόλεπτα) και αυξήστε τα μόνο όταν οι βλάβες δείχνουν γνήσια αργή φόρτωση. Τα μεγάλα προεπιλεγμένα χρονικά όρια καλύπτουν τις παλινδρομήσεις στην απόδοση.
- Διατήρηση αναμονών σε βοηθητικά προγράμματα βοήθειας: Συγκεντρώστε τη λογική αναμονής σε μια βοηθητική κλάση, έτσι ώστε οι αλλαγές στην πολιτική χρονικού ορίου να εφαρμόζονται σε ολόκληρη τη σουίτα δοκιμών.
Ακολουθώντας αυτό το πλαίσιο, οι μηχανικοί αυτοματισμού μπορούν να δημιουργήσουν ανθεκτικά σενάρια που προσαρμόζονται στον πραγματικό χρονισμό της εφαρμογής χωρίς να γίνονται αργά ή εύθραυστα.
Συνηθισμένα λάθη που πρέπει να αποφεύγετε Selenium Περιμένετε
Ακόμα και έμπειροι δοκιμαστές πέφτουν σε μια μικρή σειρά επαναλαμβανόμενων παγίδων όταν εργάζονται με Selenium περιμένει. Η αποφυγή αυτών των προβλημάτων διατηρεί τα σενάρια γρήγορα, ντετερμινιστικά και εύκολα στη συντήρηση σε όλες τις ομάδες και τα περιβάλλοντα.
Το πρώτο συνηθισμένο λάθος είναι η υπερβολική χρήση του Thread.sleep. Μια παύση με ενσωματωμένο κώδικα αναγκάζει το σενάριο να περιμένει για όλη τη διάρκεια ανεξάρτητα από την πραγματική διαθεσιμότητα των στοιχείων, γεγονός που αυξάνει τον συνολικό χρόνο εκτέλεσης. Αντικαταστήστε τέτοιες παύσεις με Explicit ή Fluent Wait, ώστε το σενάριο να συνεχίσει τη στιγμή που πληρούται η συνθήκη.
Το δεύτερο λάθος είναι η ανάμειξη έμμεσων και ρητών αναμονών στην ίδια δοκιμή. Οι δύο μηχανισμοί μπορούν να συνδυάζονται, δημιουργώντας απρόβλεπτα χρονικά όρια που είναι δύσκολο να εντοπιστούν. Επιλέξτε μία στρατηγική ανά συνεδρία WebDriver και εφαρμόστε την με συνέπεια.
Ένα τρίτο λάθος είναι ο καθορισμός πολύ υψηλών χρονικών ορίων «για κάθε ενδεχόμενο». Τα μεγάλα προεπιλεγμένα παράθυρα κρύβουν πραγματικά προβλήματα απόδοσης και επιβραδύνουν την ανατροφοδότηση σε συνεχείς αγωγούς ολοκλήρωσης. Ξεκινήστε με σύντομα χρονικά όρια και παρατείνετε τα μόνο όταν τα αρχεία καταγραφής σφαλμάτων αποδεικνύουν ότι υπάρχει πραγματικό πρόβλημα χρονισμού.
Επίσης ελέγξτε: Selenium Οδηγός για αρχάριους: Μάθετε WebDriver σε 7 ημέρες

