Selenium การรอคอย – การรอคอยโดยนัย ชัดเจน และคล่องแคล่ว


In Selenium“การรอ” มีบทบาทสำคัญในการดำเนินการทดสอบ ในบทช่วยสอนนี้ คุณจะได้เรียนรู้แง่มุมต่างๆ และความแตกต่างระหว่างการรอโดยนัยและโดยชัดแจ้ง Selenium.

ทำไมเราต้องรอเข้า Selenium?

เว็บแอปพลิเคชั่นส่วนใหญ่ได้รับการพัฒนาโดยใช้ อาแจ็กซ์ และ Javascript- เมื่อเบราว์เซอร์โหลดเพจ องค์ประกอบที่เราต้องการโต้ตอบด้วยอาจโหลดในช่วงเวลาที่ต่างกัน

ไม่เพียงแต่จะทำให้ระบุองค์ประกอบได้ยาก แต่ยังหากไม่พบองค์ประกอบนั้นก็จะส่ง “องค์ประกอบ NotVisibleException” ข้อยกเว้น โดยใช้ Selenium รอก่อน เราแก้ไขปัญหานี้ได้

ลองพิจารณาสถานการณ์ที่เราต้องใช้การรอทั้งโดยนัยและชัดเจนในการทดสอบของเรา สมมติว่าเวลารอโดยนัยถูกตั้งค่าเป็น 20 วินาที และเวลารอโดยชัดเจนถูกตั้งค่าเป็น 10 วินาที

สมมติว่าเรากำลังพยายามค้นหาองค์ประกอบที่มีบางส่วน “เงื่อนไขที่คาดหวัง “(Explicit Wait) หากองค์ประกอบไม่ได้อยู่ในกรอบเวลาที่กำหนดโดย Explicit wait(10 วินาที) องค์ประกอบจะใช้กรอบเวลาที่กำหนดโดย implicit wait(20 วินาที) ก่อนที่จะโยน “องค์ประกอบ NotVisibleException"

Selenium เว็บไดรเวอร์รออยู่

  1. รอโดยปริยาย
  2. รออย่างชัดแจ้ง

ในบทช่วยสอนนี้ คุณจะได้เรียนรู้เกี่ยวกับการรอประเภทต่างๆ Selenium:

รอเข้าโดยปริยาย Selenium

เทศกาล รอเข้าโดยปริยาย Selenium ใช้เพื่อบอกไดรเวอร์เว็บให้รอเป็นเวลาหนึ่งก่อนที่จะส่งข้อยกเว้น “No Such Element Exception” การตั้งค่าเริ่มต้นคือ 0 เมื่อเราตั้งเวลาแล้ว ไดรเวอร์เว็บจะรอองค์ประกอบนั้นเป็นเวลานั้นก่อนที่จะส่งข้อยกเว้น

Selenium Web Driver ได้ยืมแนวคิดเรื่องการรอโดยนัยมาจาก Watir.

ในตัวอย่างด้านล่าง เราได้ประกาศการรอโดยนัยโดยมีกรอบเวลา 10 วินาที หมายความว่าหากองค์ประกอบไม่ปรากฏบนหน้าเว็บภายในกรอบเวลานั้น องค์ประกอบนั้นจะเกิดข้อยกเว้น

เพื่อประกาศการรอโดยนัย Selenium เว็บไดร์เวอร์:

ไวยากรณ์รอโดยนัย:

driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
package guru.test99;
import java.util.concurrent.TimeUnit;
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 
	{
	System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
	driver = new ChromeDriver(); 
	driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS) ;
	String eTitle = "Demo Guru99 Page";
	String aTitle = "" ;
	// launch Chrome and redirect it to the Base URL
	driver.get("http://demo.guru99.com/test/guru99home/" );
	//Maximizes 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();
}
}

คำอธิบายของรหัส

ในตัวอย่างข้างต้น

พิจารณารหัสต่อไปนี้:

driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS) ;

การรอโดยปริยายจะยอมรับพารามิเตอร์ 2 ตัว โดยพารามิเตอร์ตัวแรกจะยอมรับเวลาเป็นค่าจำนวนเต็ม และพารามิเตอร์ตัวที่สองจะยอมรับการวัดเวลาเป็นวินาที นาที มิลลิวินาที ไมโครวินาที นาโนวินาที วัน ชั่วโมง เป็นต้น

รออย่างชัดแจ้ง Selenium

เทศกาล รออย่างชัดแจ้ง Selenium ใช้เพื่อแจ้งให้ Web Driver รอจนกว่าจะมีเงื่อนไขบางอย่าง (เงื่อนไขที่คาดหวัง) หรือเกินเวลาสูงสุดก่อนที่จะส่งข้อยกเว้น “ElementNotVisibleException” เป็นการรอแบบชาญฉลาด แต่สามารถใช้ได้กับองค์ประกอบที่ระบุเท่านั้น มีตัวเลือกที่ดีกว่าการรอโดยปริยาย เนื่องจากรอองค์ประกอบ Ajax ที่โหลดแบบไดนามิก

เมื่อเราประกาศการรออย่างชัดเจนแล้ว เราต้องใช้ “เงื่อนไขที่คาดหวัง” หรือเราสามารถกำหนดค่าความถี่ที่เราต้องการตรวจสอบสภาพโดยใช้ รอได้อย่างคล่องแคล่ว- ทุกวันนี้ในขณะที่เรากำลังใช้งานอยู่ Thread.นอน() โดยทั่วไปไม่แนะนำให้ใช้

ในตัวอย่างด้านล่าง เรากำลังสร้างการรออ้างอิงสำหรับ “เว็บไดร์เวอร์รอสักครู่” คลาสและการสร้างอินสแตนซ์โดยใช้ “ไดรเวอร์เว็บ” อ้างอิง และเราจะให้กรอบเวลาสูงสุด 20 วินาที

ไวยากรณ์การรอที่ชัดเจน:

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,TimeOut);
package guru.test99;

import java.util.concurrent.TimeUnit;
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 
	{
	System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
	driver = new ChromeDriver(); 
	WebDriverWait wait=new WebDriverWait(driver, 20);
	String eTitle = "Demo Guru99 Page";
	String aTitle = "" ;
	// launch Chrome and redirect it to the Base URL
	driver.get("http://demo.guru99.com/test/guru99home/" );
	//Maximizes 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();
	}
	
}

คำอธิบายของรหัส

พิจารณารหัสต่อไปนี้:

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();

ในตัวอย่างการรอของ WebDriver นี้ ให้รอตามระยะเวลาที่กำหนดไว้ในส่วน “เว็บไดร์เวอร์รอสักครู่” ชั้นเรียนหรือ “เงื่อนไขที่คาดหวัง” ให้เกิดขึ้นแล้วแต่กรณีใดจะเกิดขึ้นก่อน

ดังกล่าวข้างต้น Java รหัสระบุว่าเรากำลังรอองค์ประกอบสำหรับกรอบเวลา 20 วินาทีตามที่กำหนดไว้ใน “เว็บไดร์เวอร์รอสักครู่” คลาสบนหน้าเว็บจนกระทั่ง “เงื่อนไขที่คาดหวัง” เป็นไปตามเงื่อนไขคือ “การมองเห็นขององค์ประกอบที่ตั้ง"

ต่อไปนี้คือเงื่อนไขที่คาดว่าจะสามารถใช้ได้ Selenium รออย่างชัดแจ้ง

  1. alertIsPresent ()
  2. elementSelectionStateToBe()
  3. องค์ประกอบToBeClickable()
  4. องค์ประกอบToBeSelected()
  5. frameToBeAvaliableAndSwitchToIt()
  6. การมองไม่เห็นขององค์ประกอบที่ตั้ง ()
  7. การมองไม่เห็นขององค์ประกอบด้วยข้อความ ()
  8. การแสดงตนขององค์ประกอบทั้งหมดตั้งอยู่โดย ()
  9. การแสดงตนขององค์ประกอบตั้งอยู่()
  10. textToBePresentInElement()
  11. textToBePresentInElementlocation()
  12. textToBePresentInElementValue()
  13. ชื่อเรื่องคือ()
  14. ชื่อเรื่องมี()
  15. การมองเห็นของ()
  16. การมองเห็นขององค์ประกอบทั้งหมด ()
  17. การมองเห็นขององค์ประกอบทั้งหมดตั้งอยู่โดย ()
  18. การมองเห็นขององค์ประกอบตั้งอยู่()

รอเข้าได้เลย Selenium

เทศกาล รอเข้าได้เลย Selenium ใช้เพื่อกำหนดเวลาสูงสุดที่เว็บไดรเวอร์จะต้องรอเงื่อนไข รวมถึงความถี่ที่เราต้องการตรวจสอบเงื่อนไขก่อนที่จะส่งข้อยกเว้น “ElementNotVisibleException” โดยจะตรวจสอบองค์ประกอบเว็บเป็นระยะ ๆ จนกว่าจะพบวัตถุหรือหมดเวลา

ความถี่: ตั้งค่ารอบการทำซ้ำโดยมีกรอบเวลาเพื่อตรวจสอบ/ตรวจสอบสภาพในช่วงเวลาปกติ

ลองพิจารณาสถานการณ์ที่องค์ประกอบถูกโหลดในช่วงเวลาที่แตกต่างกัน องค์ประกอบอาจโหลดภายใน 10 วินาที 20 วินาที หรือมากกว่านั้น หากเราประกาศการรออย่างชัดเจนเป็นเวลา 20 วินาที องค์ประกอบจะรอจนถึงเวลาที่กำหนดก่อนที่จะโยนข้อยกเว้น ในสถานการณ์ดังกล่าว การรอแบบฟลูเอนต์เป็นการรอที่เหมาะสมที่สุดที่จะใช้ เนื่องจากจะพยายามค้นหาองค์ประกอบในความถี่ที่แตกต่างกันจนกว่าจะพบหรือจนกว่าตัวจับเวลาสุดท้ายจะหมดลง

ไวยากรณ์การรออย่างคล่องแคล่ว:

Wait wait = new FluentWait(WebDriver reference)
.withTimeout(timeout, SECONDS)
.pollingEvery(timeout, SECONDS)
.ignoring(Exception.class);

รหัสข้างต้นเลิกใช้แล้วใน Selenium เวอร์ชัน 3.11 ขึ้นไป คุณต้องใช้

Wait wait = new FluentWait(WebDriver reference)
.withTimeout(Duration.ofSeconds(SECONDS))
.pollingEvery(Duration.ofSeconds(SECONDS))
.ignoring(Exception.class);

package guru.test99;

import org.testng.annotations.Test;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;
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.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;

public class AppTest3 {
	protected WebDriver driver;
	@Test
	public void guru99tutorials() throws InterruptedException 
	{
	System.setProperty ("webdriver.chrome.driver",".\\chromedriver.exe" );
	String eTitle = "Demo Guru99 Page";
	String aTitle = "" ;
	driver = new ChromeDriver();
	// launch Chrome and redirect it to the Base URL
	driver.get("http://demo.guru99.com/test/guru99home/" );
	//Maximizes 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<WebDriver>(driver)							
			.withTimeout(30, TimeUnit.SECONDS) 			
			.pollingEvery(5, TimeUnit.SECONDS) 			
			.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() ;
	}
}

คำอธิบายของรหัส

พิจารณารหัสต่อไปนี้:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)							
	.withTimeout(30, TimeUnit.SECONDS) 			
	.pollingEvery(5, TimeUnit.SECONDS) 			
	.ignoring(NoSuchElementException.class);				

ในตัวอย่างข้างต้น เรากำลังประกาศการรออย่างคล่องแคล่วโดยหมดเวลา 30 วินาที และความถี่ถูกกำหนดเป็น 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"));

เราได้สร้างฟังก์ชันใหม่เพื่อระบุองค์ประกอบเว็บบนเพจ (เช่น: Web Element ที่นี่ไม่มีอะไรนอกจาก Selenium ลิงค์บนหน้าเว็บ)

ความถี่ถูกตั้งไว้ที่ 5 วินาทีและเวลาสูงสุดถูกตั้งไว้ที่ 30 วินาที ซึ่งหมายความว่าระบบจะตรวจสอบองค์ประกอบบนเว็บเพจทุก ๆ 5 วินาทีเป็นเวลาสูงสุด 30 วินาที หากองค์ประกอบนั้นอยู่ภายในกรอบเวลาที่กำหนด ระบบจะดำเนินการ มิฉะนั้นระบบจะส่ง “องค์ประกอบ NotVisibleException"

ตรวจสอบด้วย: - Selenium บทช่วยสอน IDE สำหรับผู้เริ่มต้น

ความแตกต่างระหว่างการรอโดยนัยกับการรออย่างชัดเจน

ต่อไปนี้เป็นความแตกต่างหลักระหว่างการรอโดยปริยายและการรอโดยชัดแจ้งใน Selenium:

รอโดยปริยาย รออย่างชัดแจ้ง
เวลารอโดยนัยจะถูกนำไปใช้กับองค์ประกอบทั้งหมดในสคริปต์ เวลารอที่ชัดเจนจะใช้กับองค์ประกอบที่เราตั้งใจไว้เท่านั้น
ใน Implicit Wait เราต้องการ ไม่ ระบุ "ExpectedConditions" บนองค์ประกอบที่จะวาง ใน Explicit Wait เราจำเป็นต้องระบุ "ExpectedConditions" บนองค์ประกอบที่จะวาง
ขอแนะนำให้ใช้เมื่อองค์ประกอบอยู่ในกรอบเวลาที่ระบุ Selenium รอโดยปริยาย ขอแนะนำให้ใช้เมื่อองค์ประกอบใช้เวลาโหลดนานและสำหรับการตรวจสอบคุณสมบัติขององค์ประกอบเช่น (visibilityOfElementlocation, elementToBeClickable,elementToBeSelected)

สรุป

การรอโดยนัย ชัดเจน และคล่องแคล่วเป็นการรอที่แตกต่างกันที่ใช้ Selenium- การใช้งานการรอเหล่านี้ขึ้นอยู่กับองค์ประกอบที่โหลดในช่วงเวลาที่ต่างกันโดยสิ้นเชิง ไม่แนะนำให้ใช้ Thread.Sleep() เสมอไป การทดสอบ แอปพลิเคชันของเราหรือการสร้างกรอบงานของเรา

ตรวจสอบด้วย: - Selenium บทช่วยสอนสำหรับผู้เริ่มต้น: เรียนรู้ WebDriver ใน 7 วัน

อ่านเพิ่มเติม readmore