ทำ UI Test ด้วย Selenium: ลดปวดหัวงานเช็คเว็บแบบแมนนวล

โอ้ยยย... เหนื่อยจริงไหมกับการมานั่งคลิกๆ ตรวจสอบหน้าเว็บเองทุกรอบที่แก้โค้ด? คือมันก็ดีแหละถ้าเว็บเล็กๆ แต่พอโปรเจกต์ใหญ่ขึ้นมาหน่อย หรือแก้เยอะๆ นี่... บอกเลยว่าไม่ไหว! เราก็เลยต้องพึ่งตัวช่วยอย่าง Selenium ไงล่ะ มันช่วยให้เราเขียนโค้ดสั่งให้บราวเซอร์ทำงานเองเลยนะ เจ๋งป้ะล่ะ!

เตรียมตัวก่อนลุย

ก่อนอื่นเลยต้องมี Python ก่อนนะ อันนี้เบสิคมาก ใครไม่มีไปโหลดมาซะ! แล้วก็ pip install selenium ไปเลย

pip install selenium

ทีนี้ปัญหามันอยู่ตรง WebDriver นี่แหละ! คือ Selenium มันต้องมี 'คนขับ' ให้มันไง เป็นตัวเชื่อมกับบราวเซอร์ของเรา Chrome, Firefox, Edge อะไรก็ได้หมดแหละ แต่ต้องไปโหลดมานะเว้ยยย... โหลดตามเวอร์ชั่นบราวเซอร์ที่เราใช้เป๊ะๆ ด้วย ไม่งั้นมี Error จ้าาาาาาาาาา SessionNotCreatedException มาแน่ๆ

ตัวอย่าง Error ที่เคยเจอประจำ:

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version XX
Current browser version is YY with binary path C:\Program Files\Google\Chrome\Application\chrome.exe

ไอ้เนี่ยแหละคืออาการ WebDriver ไม่ตรงเวอร์ชั่นโคตรคลาสสิค! วิธีแก้ก็ง่ายๆ เลย แค่ไปโหลด ChromeDriver (ถ้าใช้ Chrome) ที่ตรงกับ Chrome เวอร์ชั่นปัจจุบันของเราเป๊ะๆ แล้วก็เอาไฟล์ chromedriver.exe ไปวางไว้ใน Path ที่เข้าถึงได้ (เช่น โฟลเดอร์ที่รันโค้ด หรือใน System PATH เลยก็ได้)

เริ่มเขียนโค้ด Test แรก

มาลองเขียนโค้ดง่ายๆ ให้มันไปเปิด Google แล้วลองค้นหาคำว่า "Selenium" กันดู:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time # ไว้ดูผลเฉยๆ ไม่ควรใช้ในงานจริงจังนะ

# ระบุ path ไปยัง chromedriver ของเรา
# ถ้าอยู่ใน PATH ของระบบอยู่แล้ว ไม่ต้องระบุก็ได้
driver_path = 'C:/path/to/your/chromedriver.exe' # แก้ด้วย path ของคุณ

# เริ่มต้น WebDriver (ในที่นี้ใช้ Chrome)
# ถ้า chromedriver อยู่ใน PATH แล้ว ใช้ webdriver.Chrome() เฉยๆ ก็ได้
driver = webdriver.Chrome(executable_path=driver_path)

try:
    # เปิดเว็บ Google
    driver.get("https://www.google.com")
    print("เปิด Google สำเร็จ!")

    # หาช่องค้นหา ด้วย attribute name="q"
    search_box = driver.find_element(By.NAME, "q")
    search_box.send_keys("Selenium")
    search_box.send_keys(Keys.RETURN) # กด Enter

    print("ค้นหา Selenium สำเร็จ!")

    # รอแป๊บนึง (อันนี้ไม่แนะนำให้ใช้ในงานจริงจังนะ) 
    # ควรใช้ Explicit Waits แทน
    time.sleep(5) 

    # เช็คว่าผลลัพธ์การค้นหามาจริงไหม ลองหา text ที่คาดว่าจะเจอ
    assert "Selenium" in driver.title # เช็คจาก title ของหน้าเว็บ
    print("เจอคำว่า Selenium ใน Title ของหน้าเว็บผลลัพธ์")

except Exception as e:
    print(f"เกิดข้อผิดพลาด: {e}")
    # อาจจะ capture screenshot ตอน error ไว้ดูด้วยก็ดีนะ
    # driver.save_screenshot("error_screenshot.png")

finally:
    # ปิด browser ทุกครั้งเมื่อทำงานเสร็จ
    driver.quit()
    print("ปิดบราวเซอร์แล้ว")

โค้ดข้างบนมันจะเปิด Chrome ขึ้นมาเองเลยนะ แล้วก็จัดการกรอกข้อมูล กด Enter ให้เราเสร็จสรรพ เจ๋งดีใช่ไหมล่ะ

ปัญหาโลกแตก: Element หาไม่เจอ!

บ่อยโคตรๆ ใช่ปะ? ไอ้ NoSuchElementException เนี่ย! มันคือหา Element ที่เราอยากจะ Interact ด้วยไม่เจอไง สาเหตุหลักๆ ก็คือ Element นั้นอาจจะยังโหลดไม่เสร็จ หรือ Selector ที่เราใช้มันผิดพลาดเองแหละ

ตัวอย่าง Error:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[name='q']"}

วิธีแก้นอกจากเช็ค selector ดีๆ (จะใช้ Chrome DevTools ช่วยดู id, name, class, xpath, css selector ก็ได้นะ) แล้วคือ WebDriverWait นี่แหละ ช่วยชีวิตได้เยอะมากๆ มันคือการบอก Selenium ว่า "รอหน่อยนะ! รอจนกว่า Element นี้จะปรากฏขึ้นมา" ไม่ใช่รอแบบ time.sleep() มั่วๆ ที่บางที Element ก็มาไม่ทัน บางทีก็รอนานเกินไป.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# ...โค้ดเดิม...

try:
    driver.get("https://www.google.com")
    print("เปิด Google สำเร็จ!")

    # ใช้ WebDriverWait รอจนกว่า Element ที่ชื่อ "q" จะปรากฏ
    search_box = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.NAME, "q"))
    )

    search_box.send_keys("Selenium")
    search_box.send_keys(Keys.RETURN)

    print("ค้นหา Selenium สำเร็จ!")

    # ...ที่เหลือเหมือนเดิม...

except Exception as e:
    print(f"เกิดข้อผิดพลาด: {e}")
finally:
    driver.quit()

WebDriverWait(driver, 10) คือรอสูงสุด 10 วินาที ถ้าเกิน 10 วิแล้วยังไม่เจอ Element ที่เราหา มันก็จะ Error ออกมา ส่วน EC.presence_of_element_located คือรอจนกว่า Element นั้นจะอยู่ใน DOM (Document Object Model) ส่วน EC.visibility_of_element_located ก็มีนะ อันนั้นคือรอจนกว่าจะมองเห็นด้วยตาจริงๆ (อาจจะซ่อนไว้แต่ยังอยู่ใน DOM ก็ไม่ผ่าน)

สรุปแบบไม่เข้าข้าง!

คือมันก็ไม่ได้เพอร์เฟคไปซะทุกอย่างนะ บางที Element ก็เลื่อน, บางที Browser อัพเดทแล้ว WebDriver ดันไม่รองรับ ต้องมานั่งตามอัพเดทอีก แต่มันก็ช่วยให้เรามั่นใจได้เยอะขึ้นว่าหน้าเว็บของเรามันยังทำงานได้ตามที่ควรจะเป็นหลังจากการแก้ไขอะไรบางอย่าง. รวมๆ แล้วมันช่วยประหยัดเวลาชีวิตไปได้เยอะมาก ยิ่งถ้าเอาไปต่อยอดกับ CI/CD อย่างเช่น GitHub Actions ให้มันรัน Test อัตโนมัติทุกครั้งที่เรา Push โค้ดขึ้นไป นี่คือจะฟินกว่าเดิมอีกเยอะเลยนะ เชื่อดิ! ลองดูแล้วจะติดใจ.

Read more

ป้อม ภาวุธ: จากผู้บุกเบิกอีคอมเมิร์ซ สู่บทบาท สส. และผู้ตรวจสอบ AI ภาครัฐ

ป้อม ภาวุธ: จากผู้บุกเบิกอีคอมเมิร์ซ สู่บทบาท สส. และผู้ตรวจสอบ AI ภาครัฐ

เจาะลึกประวัติ "ป้อม" ภาวุธ พงษ์วิทยภานุ สส.พรรคประชาชน ผู้บุกเบิกอีคอมเมิร์ซไทย บทบาทผู้ตรวจสอบโครงการ AI ภาครัฐ และประเด็น Forex ที่กำลังถูกจับตา

By ทีมงาน devdog
ไฮไลท์บอลโลก 2026: มหากาพย์ 48 ทีม เปิดฉากความตื่นเต้นที่คุณไม่ควรพลาด!

ไฮไลท์บอลโลก 2026: มหากาพย์ 48 ทีม เปิดฉากความตื่นเต้นที่คุณไม่ควรพลาด!

เกาะติดไฮไลท์บอลโลก 2026 ตั้งแต่นัดเปิดสนาม! สรุปผลการแข่งขันสุดเซอร์ไพรส์, ช่องทางดูบอลสดในไทยทั้งฟรีและพรีเมียม, โปรแกรมสำคัญ และทุกสิ่งที่ควรรู้.

By ทีมงาน devdog
ตารางคะแนนบอลโลก: ทุกแต้มมีความหมาย และปาฏิหาริย์ที่สั่นสะเทือนบัลลังก์

ตารางคะแนนบอลโลก: ทุกแต้มมีความหมาย และปาฏิหาริย์ที่สั่นสะเทือนบัลลังก์

เจาะลึกความสำคัญของตารางคะแนนบอลโลก พร้อมเรื่องราวสุดประทับใจของโวซินญา ผู้รักษาประตูเคปเวิร์ดที่สร้างปาฏิหาริย์หยุดสเปนในฟุตบอลโลก 2026.

By ทีมงาน devdog