Programming
Panduan Lengkap Selenium untuk Otomatisasi Browser Pemula
Daftar isi
- Kenapa Selenium Penting Buat Tim Developer
- Memahami Komponen Suite Selenium
- Selenium WebDriver
- Selenium IDE
- Selenium Grid
- Selenium Manager
- Perbandingan Komponen Selenium: Mana yang Pilih
- Yang Kamu Butuhin Sebelum Mulai (Prerequisites)
- 1. Python 3.10 atau Yang Lebih Baru
- 2. Browser yang Terinstall
- 3. pip (Python Package Installer)
- 4. Code Editor atau IDE
- Step 1: Install Library Selenium di Python
- Tips: Pakai Virtual Environment
- Step 2: Tulis Script Selenium Pertama Kamu
- Step 3: Interaksi dengan Elemen Web
- Cara Mencari Elemen
- Aksi pada Elemen
- Step 4: Menangani Wait dan Timing
- Expected Conditions yang Sering Dipakai
- Step 5: Membuat Test Suite dengan unittest Framework
- Step 6: Pakai pytest untuk Testing yang Lebih Ekspresif
- Step 7: Mengkonfigurasi Browser Options
- Step 8: Mengambil Screenshot untuk Debugging
- Step 9: Menangani Multiple Browser (Cross-Browser Testing)
- Step 10: Form Interaction yang Realistis - Login Test
- Step 11: Menghadapi Alert, Popup, dan Frame
- JavaScript Alerts
- Beralih ke iframe
- Step 12: Integrasi dengan CI/CD Pipeline
- Error dan Troubleshooting: Masalah yang Sering Muncul
- 1. NoSuchElementException
- 2. TimeoutException
- 3. WebDriverException: Chrome Failed to Start
- 4. StaleElementReferenceException
- 5. SessionNotCreatedException
- Studi Kasus: Implementasi Selenium di Tim E-commerce
- Background
- Challenge
- Approach
- Implementation
- Results
- Key Learnings
- Best Practices yang Wajib Kamu Tahu
- 1. Gunakan Page Object Model (POM)
- 2. Hindari Implicit Wait yang Terlalu Tinggi
- 3. Bersihkan Data Test Sebelum dan Sesudah
- 4. Jangan Test Hal yang Sama Dua Kali
- 5. Beri Nama Test yang Deskriptif
- Kesalahan yang Sering Dilakukan dan Cara Menghindarinya
- 1. Pakai time.sleep() Sebagai Wait
- 2. Lupa Tutup Browser
- 3. XPath yang Terlalu Rapuh
- 4. Test Depends on Test Lain
- 5. Tidak Test di Environment yang Sama dengan Production
- Selenium Grid: Scaling Test ke Level Berikutnya
- Konsep Dasar Grid
- Setup Grid dengan Docker
- Pakai Remote WebDriver
- Alternatif Selenium: Kapan Mempertimbangkan yang Lain
- Strategi Membangun Test Suite yang Maintainable
- Mulai Kecil, Tumbuh Organik
- Prioritaskan Berdasarkan Business Impact
- Test harus Bisa Di-trust
- Invest di Infrastructure
- Kesalahan Setup yang Umum di Environment Tim
- 1. Versi Selenium yang Berbeda di Mesin Berbeda
- 2. Hardcode URL di Setiap Test File
- 3. Test Data yang Tidak Konsisten
- Performance Tuning untuk Selenium Test
- 1. Headless Mode
- 2. Paralel Execution dengan pytest-xdist
- 3. Matikan Fitur yang Tidak Perlu
- 4. Reuse Browser Session untuk Test yang Berurutan
- Selenium untuk Web Scraping: Bukan Hanya Testing
- Penutup Teknis: Checklist Sebelum Test Kamu Go-Live
- Kesimpulan
Pernahkah Teman-Teman bayangin harus ngetik ulang ratusan kali buat ngecek apakah form login di web kamu masih berfungsi atau nggak? Nah, di sinilah Selenium masuk ke panggung. Selenium adalah suite tools open-source yang dipakai buat otomatisasi browser — dari ngetes aplikasi web, scrap data, sampai ngotomatisasi tugas administrasi berbasis web yang membosankan.
Selenium bukan cuma satu tool, tapi sekumpulan alat yang bikin kamu bisa ngendalin browser kayak Chrome, Firefox, Safari, dan Edge pakai kode. Mulai dari nulis script test otomatis, merekam interaksi pengguna, sampai jalanin test secara paralel di banyak mesin sekaligus — semua bisa dilakukan dengan Selenium.
Singkatnya: Selenium mengotomatisasi browser. Itu intinya. Apa yang kamu lakukan dengan kekuatan itu, terserah kamu.
Paket Selenium terdiri dari beberapa komponen utama: WebDriver buat ngerendah-level kontrol browser, Selenium IDE buat rekam dan mainkan ulang interaksi, serta Selenium Grid buat distribusi dan skala test lintas banyak environment. Buat kamu yang baru kenal dunia otomatisasi test, panduan ini bakal ngebawa kamu dari nol sampai bisa nulis dan jalanin script Selenium pertama kamu.
Kenapa Selenium Penting Buat Tim Developer
Sebelum MUGHU bahas cara pakainya, ada baiknya kita pahami dulu kenapa tool ini jadi standar de facto di industri pengujian web.
Dulu, MUGHU perngalamin banget capeknya ngetest manual tiap kali ada deploy baru. Bayangin, tiap release harus buka browser, isi form, klik tombol, tunggu loading, cek hasil — di tiga browser berbeda. Kalau satu siklus release butuh 30 menit buat regression test manual, dan kamu release tiap minggu, itu berarti dua jam per bulan habis cuma buat ngulang hal yang sama. Selenium ngubah semua itu jadi script yang jalan dalam hitungan detik.
Otomatisasi test dengan Selenium ngasih beberapa keuntungan strategis buat tim:
-
Hemat waktu signifikan — Test regression yang manual butuh jam bisa jadi menit
-
Konsistensi tinggi — Script jalan sama persis setiap kali, nggak ada "lupa ngetes satu kasus"
-
Cross-browser testing — Satu script bisa jalan di Chrome, Firefox, Safari, dan Edge
-
CI/CD friendly — Gampang diintegrasikan ke pipeline pipeline kayak Jenkins, GitHub Actions, atau GitLab CI
-
Skala lintas platform — Windows, macOS, Linux semua didukung
Dari sisi ROI (Return on Investment), investasi waktu buat setup Selenium test biasanya balik modal dalam Hitungan minggu — terutama kalau kamu punya banyak regression test yang berjalan manual. Tim yang udah adopt Selenium umumnya ngelihat peningkatan test coverage sekaligus pengurangan waktu release cycle secara signifikan.
Memahami Komponen Suite Selenium
Salah satu hal yang sering bikin bingung adalah "Selenium" itu sebetulnya payung buat beberapa tool. Tiap tool punya perannya masing-masing, dan penting buat pilih yang tepat sesuai kebutuhan kamu.
Selenium WebDriver
![]()
Ini jantung dari Selenium. WebDriver adalah kumpulan binding bahasa pemprograman yang bikin kamu bisa ngendalin browser secara langsung — kayak user asli ngeklik dan ngetik, tapi pakai kode. WebDriver mengimplementasi spesifikasi W3C WebDriver, jadi kode yang kamu tulis bisa jalan interchangeably antar browser.
Kalau kamu mau bikin regression test suite yang robust dan scalable, WebDriver jawabannya. Ini bukan cuma buat testing — tugas administrasi berbasis web kayak ngisi form berulang juga bisa diotomatisasi.
Selenium IDE
![]()
Selenium IDE adalah ekstensi browser (Chrome, Firefox, Edge) yang ngasih kamu kemampuan rekam dan mainkan ulang interaksi. Jadi kamu cukup buka browser, lakuin aksi yang mau dites, dan IDE bakal nerekam semuanya jadi script.
Ini cocok banget buat reproducibility bug cepat atau exploratory testing. Tapi untuk test suite yang kompleks, IDE punya keterbatasan dan biasanya nggak direkomendasiin sebagai solusi utama.
Selenium Grid
![]()
Bayangin kamu punya 200 test case dan harus jalan di 4 browser berbeda. Kalau jalan satu-satu di satu mesin, bisa jam-an. Selenium Grid bikin kamu bisa distribusikan test ke banyak mesin sekaligus, jadi semuanya jalan secara paralel.
Grid mengelola multiple environment dari titik pusat, jadi gampang buat ngejalankan test against banyak kombinasi browser dan OS. Buat tim yang udah skala, Grid itu game-changer.
Selenium Manager
![]()
Mulai versi 4.x, Selenium nambahin Selenium Manager — tool command-line yang ditulis pakai Rust dan otomatis ngurusin driver installation. Kamu nggak perlu lagi download chromedriver atau geckodriver manual. Tinggal instantiate, and it just works.
Perbandingan Komponen Selenium: Mana yang Pilih
Teman-Teman mungkin nanya, "Kalau gitu aku pakai yang mana?" Jawabannya tergantung use case. Biar gampang, ini perbandingan side-by-side:
Baca juga OpenCode Free: Agen AI Coding Gratis dan Open Source
Komponen | Bahasa yg Didukung | Tingkat Kesulitan | Best For | Skalabilitas |
|---|---|---|---|---|
Selenium WebDriver | Java, Python, C#, Ruby, JavaScript, Kotlin | Menengah | Regression test suite, otomatisasi kompleks | Tinggi (dengan Grid) |
Selenium IDE | Tidak perlu kode (record & playback) | Rendah | Quick bug repro, exploratory testing | Rendah |
Selenium Grid | Semua bahasa WebDriver | Menengah-Tinggi | Paralel test lintas mesin/browsers | Sangat Tinggi |
Selenium Manager | Built-in (Rust) | Otomatis | Manajemen driver/browser otomatis | N/A |
Rekomendasi by use case:
-
Butuh test suite jangka panjang yang maintainable → WebDriver + Grid
-
Mau cepat rekam bug dan buat script tanpa nulis kode → Selenium IDE
-
Punya ratusan test dan mau percepat eksekusi → WebDriver + Selenium Grid
-
Baru pertama kali nyobain Selenium → Mulai dengan WebDriver, pakai Selenium Manager yang sudah built-in
Yang Kamu Butuhin Sebelum Mulai (Prerequisites)
Okay, sekarang kita masuk ke bagian teknis. Sebelum mulai ngoding, pastikan environment kamu siap. Berikut yang harus ada di mesin kamu:
1. Python 3.10 atau Yang Lebih Baru
Selenium versi terbaru (4.x) butuh Python 3.10 ke atas. Cek versi Python kamu dengan perintah:
python --version
Output yang diharapkan:
Python 3.10.0
Kalau versinya lebih lama, update dulu. Install Python dari python.org atau pakai package manager sesuai OS kamu.
Kenapa Python 3.10? Karena Selenium 4.x packcage di PyPI sudah set minimum version ke 3.10, dan beberapa fitur terbaru seperti union type hints dan pattern matching butuh versi ini.
2. Browser yang Terinstall
Kamu butuh setidaknya satu browser yang didukung:
-
Google Chrome
-
Mozilla Firefox
-
Microsoft Edge
-
Safari (khusus macOS)
Pastikan browser versi terbaru. Selenium Manager bakal otomatis download driver yang cocok dengan versi browser kamu.
3. pip (Python Package Installer)
pip biasanya udah include sama instalasi Python. Cek dengan:
pip --version
Kalau belum ada, install dengan:
python -m ensurepip --upgrade
4. Code Editor atau IDE
Pilih yang paling nyaman buat kamu — VS Code, PyCharm, Sublime Text, atau bahkan vim. Yang penting support syntax highlighting buat Python.
Alasan kenapa hal-hal di atas penting: Selenium WebDriver butuh Python runtime buat jalanin script, browser buat target otomatisasi, pip buat install library Selenium, dan editor buat nulis kode dengan nyaman. Kalau salah satu nggak ada, prosesnya bakal terhenti di tengah jalan.
Step 1: Install Library Selenium di Python
Sekarang saatnya install. Buka terminal atau command prompt, jalankan perintah berikut:
pip install -U selenium
Flag -U artinya "upgrade" — kalau kamu sudah pernah install sebelumnya, ini bakal update ke versi terbaru.
Output yang diharapkan:
Collecting selenium
Downloading selenium-4.45.0-py3-none-any.whl (9.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.5/9.5 MB 25.3 MB/s eta 0:00:00
Installing collected packages: ... selenium-4.45.0
Successfully installed selenium-4.45.0
Kenapa step ini penting? Tanpa library ini terinstall, kamu nggak bisa import selenium di kode Python kamu. Library ini isinya binding resmi buat Selenium WebDriver dalam bahasa Python — semua API yang kamu butuhin buat ngendalin browser ada di sini.
Pada versi terbaru (4.45.0 saat tulisan ini dibuat), Selenium Manager sudah built-in. Artinya kamu nggak perlu repot download chromedriver atau geckodriver manual — semuanya diurus otomatis.
Tips: Pakai Virtual Environment
MUGHU selalu recommend pakai virtual environment biar dependency project nggak campur aduk sama sistem global. Caranya:
# Buat virtual environment
python -m venv selenium-env
# Aktivasinya
# Windows:
selenium-env\Scripts\activate
# macOS/Linux:
source selenium-env/bin/activate
# Baru install Selenium di dalam venv
pip install -U selenium
Dengan begini, kalau nanti kamu butuh versi berbeda di project lain, nggak bakal bentrok.
Step 2: Tulis Script Selenium Pertama Kamu
Saatnya momen yang ditunggu-tunggu — bikin script pertama. Kita akan lakuin tiga hal sederhana:
Baca juga ClinePass: Langganan Model Open Weight untuk Coding
-
Buka browser Chrome
-
Load sebuah halaman web
-
Tutup browser
Buka code editor kamu, buat file baru bernama first_test.py, lalu ketik kode berikut:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://selenium.dev")
print("Judul halaman:", driver.title)
driver.quit()
Simpan file, lalu jalankan:
python first_test.py
Output yang diharapkan:
Judul halaman: Selenium
Plus, kamu bakal ngeliat jendela Chrome terbuka sebentar, load halaman selenium.dev, lalu nutup sendiri. Itu otomatisasi browser paling basic yang bisa kamu lakuin dengan Selenium.
Mari kita bedah apa yang terjadi di tiap baris:
-
from selenium import webdriver— Mengimpor modul WebDriver dari library Selenium -
driver = webdriver.Chrome()— Membuat instance Chrome browser. Di balik layar, Selenium Manager otomatis download chromedriver yang cocok kalau belum ada -
driver.get("https://selenium.dev")— Perintah browser untuk navigate ke URL tersebut -
print("Judul halaman:", driver.title)— Mengambil judul halaman dan menampilkannya -
driver.quit()— Menutup browser dan mengakhiri session. Penting:quit()lebih lengkap dariclose()karena juga membersihkan resource WebDriver
Kenapa urutan ini penting? Karena setiap script Selenium selalu punya lifecycle yang sama: inisialisasi → interaksi → cleanup. Kalau kamu skip quit(), browser tetap kebuka dan process driver tetap jalan di background — ngerjain resource mesin kamu.
Step 3: Interaksi dengan Elemen Web
Membuka browser dan nutup emang keren, tapi itu baru permulaan. Kekuatan Selenium sebetulnya ada di kemampuannya berinteraksi dengan elemen-elemen di halaman web.
Kita coba skenario lebih lengkap: buka halaman dokumentasi Selenium, cari sebuah link, klik link tersebut, lalu verifikasi hasilnya.
Buat file baru bernama interact_test.py:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# Buka halaman dokumentasi
driver.get("https://selenium.dev/documentation")
# Verifikasi judul halaman
assert "Selenium" in driver.title
print("✓ Halaman dokumentasi terbuka dengan benar")
# Cari link berdasarkan ID
elem = driver.find_element(By.ID, "m-documentationwebdriver")
# Klik link tersebut
elem.click()
# Verifikasi sudah di halaman WebDriver
assert "WebDriver" in driver.title
print("✓ Berhasil navigasi ke halaman WebDriver")
print("Judul akhir:", driver.title)
driver.quit()
Jalankan:
python interact_test.py
Output yang diharapkan:
✓ Halaman dokumentasi terbuka dengan benar
✓ Berhasil navigasi ke halaman WebDriver
Judul akhir: WebDriver | Selenium
Mari kita bah konsep-konsep baru di sini:
Cara Mencari Elemen
find_element adalah metapode paling fundamental. Parameter pertamanya adalah strategi locator, dan parameter kedua adalah nilai yang dicari. Berikut locator strategies yang tersedia:
Strategi | Contoh | Kapan Pakai |
|---|---|---|
|
| Kalau elemen punya atribut |
|
| Buat form input yang punya atribut |
|
| Kalau elemen nggak punya ID atau name unik |
|
| Selektor CSS, fleksibel dan powerful |
|
| Kalau class name cukup spesifik |
|
| Mencari berdasarkan tag HTML |
|
| Mencari link berdasarkan text persisnya |
|
| Mencari link berdasarkan teks parsial |
Kenapa pilihan locator penting? Karena struktur DOM sering berubah. Kalau kamu pakai ID yang stabil, test kamu lebih resilient. Sebaliknya, kalau terlalu bergantung pada XPath yang kompleks, test mudah broke tiap kali UI berubah.
Aksi pada Elemen
Setelah elemen ditemukan, kamu bisa lakuin berbagai aksi:
# Klik tombol atau link
element.click()
# Ketik teks ke input field
element.send_keys("[email protected]")
# Hapus teks dari input field
element.clear()
# Ambil teks dari elemen
text = element.text
# Ambil atribut
href = element.get_attribute("href")
Step 4: Menangani Wait dan Timing
Ini salah satu topik yang bikin banyak orang kesel. Browser butuh waktu buat load halaman, dan kalau script kamu langsung nyari elemen sebelum halaman selesai loading, kamu bakal kenyang error NoSuchElementException.
Dulu MUGHU sering banget kena masalah ini. Terutama kalau ngetest web app yang banyak AJAX call-nya. Script jalan terlalu cepat, elemen belum muncul, boom — error. Solusi naifnya adalah time.sleep(5) — tunggu 5 detik. Tapi itu bad practice karena:
-
Terlalu lama → test jadi lambat
-
Terlalu pendek → test tetap flaky
-
Tidak adaptif → kadang butuh 1 detik, kadang 3 detik
Solusi yang benar adalah pakai WebDriverWait:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://selenium.dev/documentation")
# Tunggu maksimal 10 detik sampai elemen muncul
wait = WebDriverWait(driver, 10)
element = wait.until(
EC.presence_of_element_located((By.ID, "m-documentationwebdriver"))
)
element.click()
print("Element ditemukan dan diklik!")
driver.quit()
Kenapa ini lebih baik? Karena WebDriverWait bakal ngecek setiap 500ms apakah elemen sudah muncul. Begitu muncul, langsung lanjut — nggak nunggu kaku 10 detik penuh. Tapi kalau sampai 10 detik elemen belum muncul, baru raise TimeoutException.
Expected Conditions yang Sering Dipakai
Condition | Kegunaan |
|---|---|
| Elemen ada di DOM (belum tentu visible) |
| Elemen terlihat di layar |
| Elemen siap diklik |
| Judul halaman mengandung teks tertentu |
| URL mengandung string tertentu |
| Teks tertentu muncul di dalam elemen |
Pemilihan condition yang tepat bikin test kamu stabil tanpa nambah waktu eksekusi yang nggak perlu.
Baca juga Kiro Dev: IDE Agentic AWS untuk Spec-Driven Development
Step 5: Membuat Test Suite dengan unittest Framework
Okay, sekarang kita level up. Nulis script satu-satu enak, tapi di dunia nyata kamu butuh test suite yang terstruktur. Python udah punya built-in framework bernama unittest yang cocok banget dipadukan dengan Selenium.
Buat file test_suite.py:
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class SeleniumWebTest(unittest.TestCase):
def setUp(self):
"""Dijalankan sebelum setiap test method."""
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(10) # Implicit wait 10 detik
self.addCleanup(self.driver.quit)
def test_halaman_utama_selenium(self):
"""Test: Halaman utama selenium.dev bisa diakses."""
self.driver.get("https://selenium.dev")
self.assertIn("Selenium", self.driver.title)
print(f"✓ Test 1 - Judul halaman: {self.driver.title}")
def test_navigasi_dokumentasi(self):
"""Test: Bisa navigasi ke halaman dokumentasi."""
self.driver.get("https://selenium.dev/documentation")
self.assertIn("Selenium", self.driver.title)
print(f"✓ Test 2 - Dokumentasi terbuka")
def test_cari_elemen_link(self):
"""Test: Elemen link WebDriver di halaman dokumentasi bisa ditemukan."""
self.driver.get("https://selenium.dev/documentation")
wait = WebDriverWait(self.driver, 10)
elem = wait.until(
EC.presence_of_element_located((By.ID, "m-documentationwebdriver"))
)
self.assertTrue(elem.is_displayed())
print(f"✓ Test 3 - Elemen ditemukan dan visible")
if __name__ == "__main__":
unittest.main(verbosity=2)
Jalankan:
python test_suite.py
Output yang diharapkan:
test_cari_elemen_link (__main__.SeleniumWebTest) ...
✓ Test 3 - Elemen ditemukan dan visible
ok
test_halaman_utama_selenium (__main__.SeleniumWebTest) ...
✓ Test 1 - Judul halaman: Selenium
ok
test_navigasi_dokumentasi (__main__.SeleniumWebTest) ...
✓ Test 2 - Dokumentasi terbuka
ok
----------------------------------------------------------------------
Ran 3 tests in 12.45s
OK
Kenapa struktur seperti ini penting? Karena:
-
setUp otomatis jalan sebelum tiap test — browser selalu fresh
-
addCleanup(self.driver.quit) otomatis tutup browser setelah tiap test, walau test gagal
-
Setiap method
test_*jadi test case terpisah dan independen -
verbosity=2 ngasih output yang lebih informatif — kamu tau test mana yang pass dan butuh berapa lama
Sekali waktu MUGHU lupa pakai addCleanup dan cuma pakai tearDown. Bedanya, addCleanup tetap jalan walau setUp gagal di tengah jalan, sedangkan tearDown nggak. Buat testing dengan browser, ini perbedaan penting karena kalau browser kebuka tapi test gagal, kamu butuh pastikan browser tetap tutup.
Step 6: Pakai pytest untuk Testing yang Lebih Ekspresif
unittest oke, tapi kalau kamu pernah cobain pytest, kamu bakal ngerasa kalau pytest lebih ekspresif dan less boilerplate. Selain itu, pytest juga support fixtures yang lebih fleksibel buat managament resource.
Install pytest dulu:
pip install pytest
Lalu buat file test_pytest_selenium.py:
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
@pytest.fixture
def driver():
"""Fixture yang menyediakan WebDriver untuk setiap test."""
driver = webdriver.Chrome()
yield driver
driver.quit()
def test_judul_halaman_selenium(driver):
"""Verifikasi judul halaman utama Selenium."""
driver.get("https://selenium.dev")
assert "Selenium" in driver.title
def test_dokumentasi_terbuka(driver):
"""Verifikasi halaman dokumentasi bisa diakses."""
driver.get("https://selenium.dev/documentation")
assert "Selenium" in driver.title
def test_klik_link_webdriver(driver):
"""Verifikasi link WebDriver bisa diklik."""
driver.get("https://selenium.dev/documentation")
wait = WebDriverWait(driver, 10)
elem = wait.until(
EC.element_to_be_clickable((By.ID, "m-documentationwebdriver"))
)
elem.click()
assert "WebDriver" in driver.title
Jalankan:
pytest test_pytest_selenium.py -v
Output yang diharapkan:
============================= test session starts =============================
collected 3 items
test_pytest_selenium.py::test_judul_halaman_selenium PASSED [ 33%]
test_pytest_selenium.py::test_dokumentasi_terbuka PASSED [ 66%]
test_pytest_selenium.py::test_klik_link_webdriver PASSED [100%]
============================== 3 passed in 11.23s ==============================
Kenapa pytest sering lebih dipilih? Sederhananya — fixture pytest lebih clean daripada setUp/tearDown di unittest. Assert juga lebih natural: cukup assert "Selenium" in driver.title, nggak perlu self.assertIn(). Plus, output pytest lebih informatif dan komunitasnya udah mature banget di ecosystem Python testing.
Step 7: Mengkonfigurasi Browser Options
Di dunia nyata, kamu sering perlu kustomisasi cara browser jalan. Misalnya jalanin dalam mode headless (tanpa GUI — penting buat CI/CD), atur window size, atau disable notifikasi. Berikut caranya:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
# Mode headless - browser jalan tanpa GUI
options.add_argument("--headless=new")
# Atur ukuran window
options.add_argument("--window-size=1920,1080")
# Disable notifikasi
options.add_argument("--disable-notifications")
# Disable infobars ('Chrome is being controlled by automated software')
options.add_argument("--disable-infobars")
# User agent kustom
options.add_argument("--user-agent=Mozilla/5.0 (Test Agent)")
# Jalanin dalam mode incognito
options.add_argument("--incognito")
driver = webdriver.Chrome(options=options)
driver.get("https://selenium.dev")
print("Judul:", driver.title)
print("Ukuran window:", driver.get_window_size())
driver.quit()
Output yang diharapkan (headless mode):
Judul: Selenium
Ukuran window: {'width': 1920, 'height': 1080}
Kenapa ini penting? Dalam pipeline CI/CD kayak GitHub Actions atau Jenkins, server biasanya nggak punya display. Mode headless wajib pakai di situ. Tanpa opsi ini, Selenium bakal coba buka jendela browser yang nggak ada display-nya — dan gagal.
MUGHU dulu pernah setup test di Jenkins yang terus-terusan gagal dengan error WebDriverException: unknown error: Chrome failed to start: exited abnormally. Setelah berhari-hari debugging, ternyata cuma lupa kasih --headless. Pelajaran mahal: selalu set headless mode kalau jalanin di environment tanpa display.
Step 8: Mengambil Screenshot untuk Debugging
Salah satu hal yang paling membantu saat debugging test failure adalah screenshot. Begitu test gagal, kamu pengen tahu halaman kayak gimana saat itu.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
options = Options()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
driver.get("https://selenium.dev/documentation")
# Screenshot full page
driver.save_screenshot("screenshot_full.png")
print("✓ Screenshot full page tersimpan")
# Screenshot elemen tertentu
elem = driver.find_element("id", "m-documentationwebdriver")
elem.screenshot("screenshot_elem.png")
print("✓ Screenshot elemen tersimpan")
driver.quit()
Saat pakai save_screenshot, file PNG bakal tersimpan di working directory. Kalau test kamu flaky atau gagal intermitent, screenshot adalah bukti visual yang nggak terbantahkan kondisi halaman saat kejadian.
Beberapa praktik baik soal screenshot:
-
Kasih nama file yang descriptive, misal:
test_login_gagal_{timestamp}.png -
Taruh di folder khusus, misal
screenshots/, dan tambahkan ke.gitignore -
Hanya simpan screenshot saat test gagal, bukan saat pass — keluwes
-
Kombinasi dengan logging buat trace yang lengkap
Step 9: Menangani Multiple Browser (Cross-Browser Testing)
Salah satu keuntungan utama Selenium adalah dukungan untuk banyak browser. Berikut cara bikin test yang jalan di beberapa browser:
Baca juga Codex CLI dari OpenAI: Panduan Lengkap Ngoding di Terminal
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.edge.options import Options as EdgeOptions
def create_driver(browser_name, headless=True):
"""Factory function buat bikin WebDriver sesuai browser yang dipilih."""
if browser_name == "chrome":
options = ChromeOptions()
if headless:
options.add_argument("--headless=new")
return webdriver.Chrome(options=options)
elif browser_name == "firefox":
options = FirefoxOptions()
if headless:
options.add_argument("--headless")
return webdriver.Firefox(options=options)
elif browser_name == "edge":
options = EdgeOptions()
if headless:
options.add_argument("--headless=new")
return webdriver.Edge(options=options)
else:
raise ValueError(f"Browser {browser_name} tidak didukung")
@pytest.fixture(params=["chrome", "firefox", "edge"])
def driver(request):
"""Fixture yang jalan untuk tiap browser."""
driver = create_driver(request.param, headless=True)
yield driver
driver.quit()
def test_judul_selenium(driver):
"""Test yang otomatis jalan di Chrome, Firefox, dan Edge."""
driver.get("https://selenium.dev")
assert "Selenium" in driver.title
print(f"✓ {driver.capabilities['browserName']}: judul = {driver.title}")
def test_dokumentasi_terbuka(driver):
"""Test dokumentasi di semua browser."""
driver.get("https://selenium.dev/documentation")
assert "Selenium" in driver.title
Jalankan:
pytest test_cross_browser.py -v
Output yang diharapkan:
============================= test session starts =============================
collected 6 items
test_cross_browser.py::test_judul_selenium[chrome] PASSED [ 16%]
test_cross_browser.py::test_judul_selenium[firefox] PASSED [ 33%]
test_cross_browser.py::test_judul_selenium[edge] PASSED [ 50%]
test_cross_browser.py::test_dokumentasi_terbuka[chrome] PASSED [ 66%]
test_cross_browser.py::test_dokumentasi_terbuka[firefox] PASSED [ 83%]
test_cross_browser.py::test_dokumentasi_terbuka[edge] PASSED [100%]
============================== 6 passed in 28.91s ==============================
Lihat bagaimana parameter params=["chrome", "firefox", "edge"] di fixture pytest otomatis bikin test jalan tiga kali — sekali di tiap browser. Ini pattern yang sangat powerful dan hemat kode.
Catatan: Pastikan browser-browser tersebut sudah terinstall di mesin kamu. Selenium Manager otomatis download driver yang sesuai, tapi browser-nya sendiri harus ada.
Step 10: Form Interaction yang Realistis - Login Test
Sekarang kita masuk ke skenario yang lebih realistis: test form login. Form login adalah salah satu flow yang paling sering dites di web app manapun.
Buat file test_form_interaction.py:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time
# Setup browser
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
# Buka halaman demo login
driver.get("https://the-internet.herokuapp.com/login")
# Verifikasi halaman login terbuka
wait = WebDriverWait(driver, 10)
heading = wait.until(
EC.visibility_of_element_located((By.TAG_NAME, "h2"))
)
assert "Login Page" in heading.text
print("✓ Halaman login terbuka")
# Cari input username dan isi
username = driver.find_element(By.ID, "username")
username.send_keys("tomsmith")
print("✓ Username diisi")
# Cari input password dan isi
password = driver.find_element(By.ID, "password")
password.send_keys("SuperSecretPassword!")
print("✓ Password diisi")
# Klik tombol login
login_button = driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
login_button.click()
print("✓ Tombol login diklik")
# Tunggu flash message muncul
flash = wait.until(
EC.visibility_of_element_located((By.ID, "flash"))
)
assert "You logged into" in flash.text
print(f"✓ Login berhasil! Pesan: {flash.text.strip()}")
# Verifikasi halaman setelah login
assert "secure" in driver.current_url
print(f"✓ URL sekarang: {driver.current_url}")
# Logout
logout_button = driver.find_element(By.CSS_SELECTOR, "a.button")
logout_button.click()
print("✓ Logout diklik")
# Verifikasi kembali ke halaman login
flash_logout = wait.until(
EC.visibility_of_element_located((By.ID, "flash"))
)
assert "You logged out" in flash_logout.text
print(f"✓ Logout berhasil! Pesan: {flash_logout.text.strip()}")
finally:
driver.quit()
print("Browser ditutup.")
Output yang diharapkan:
✓ Halaman login terbuka
✓ Username diisi
✓ Password diisi
✓ Tombol login diklik
✓ Login berhasil! Pesan: You logged into a secure area!
✓ URL sekarang: https://the-internet.herokuapp.com/secure
✓ Logout diklik
✓ Logout berhasil! Pesan: You logged out of the secure area!
Browser ditutup.
Skenario ini nunjukin flow yang lebih lengkap: mengisi form, submit, verifikasi flash message, navigasi ke secure area, lalu logout. Ini adalah pattern test end-to-end yang umum banget.
Beberapa hal penting dari kode di atas:
-
try/finally— Pastikan browser selalu ditutup walau ada error di tengah -
send_keys("teks")— Cara mengisi input field, bisa juga pakaiKeys.RETURNbuat submit -
EC.visibility_of_element_located— Lebih ketat daripadapresence_ofkarena elemen harus visible di layar -
driver.current_url— Mengambil URL saat ini buat verifikasi navigasi
Step 11: Menghadapi Alert, Popup, dan Frame
Web gak cuma tentang halaman datar. Kadang kamu harus berurusan dengan alert, popup window, dan iframe. Selenium punya cara khusus buat masing-masing.
JavaScript Alerts
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.alert import Alert
driver = webdriver.Chrome()
driver.get("https://the-internet.herokuapp.com/javascript_alerts")
# Trigger JS Alert
driver.find_element(By.CSS_SELECTOR, "button[onclick='jsAlert()']").click()
# Tunggu alert muncul
wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())
# Ambil teks alert
print(f"Teks alert: {alert.text}")
# Klik OK
alert.accept()
print("✓ Alert diterima")
# Trigger JS Confirm
driver.find_element(By.CSS_SELECTOR, "button[onclick='jsConfirm()']").click()
confirm = wait.until(EC.alert_is_present())
print(f"Teks confirm: {confirm.text}")
confirm.dismiss() # Klik Cancel
print("✓ Confirm di-dismiss")
# Trigger JS Prompt
driver.find_element(By.CSS_SELECTOR, "button[onclick='jsPrompt()']").click()
prompt = wait.until(EC.alert_is_present())
prompt.send_keys("Halo dari Selenium!")
prompt.accept()
print("✓ Prompt diisi dan diterima")
driver.quit()
Beralih ke iframe
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://the-internet.herokuapp.com/iframe")
# Switch ke iframe
iframe = driver.find_element(By.ID, "mce_0_ifr")
driver.switch_to.frame(iframe)
# Sekarang bisa interaksi dengan elemen di dalam iframe
editor = driver.find_element(By.ID, "tinymce")
print(f"Teks di iframe: {editor.text}")
# Kembali ke main content
driver.switch_to.default_content()
print("✓ Kembali ke main content")
driver.quit()
Kenapa ini penting? Karena iframe adalah konteks terpisah — kamu nggak bisa langsung find_element buat elemen yang ada di dalam iframe tanpa switch dulu. Ini salah satu error paling umum: NoSuchElementException padahal elemen ada di layar — tapi di dalam iframe.
Step 12: Integrasi dengan CI/CD Pipeline
Untuk tim yang serius, test hanya berguna kalau jalan otomatis tiap ada code baru. Berikut contoh setup GitHub Actions buat jalanin Selenium test:
Buat file .github/workflows/selenium-tests.yml:
name: Selenium Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install Chrome
uses: browser-actions/setup-chrome@v1
- name: Install dependencies
run: |
pip install -U selenium pytest
- name: Run tests
run: |
pytest -v --tb=short
- name: Upload screenshots on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-screenshots
path: screenshots/
Commit file ini ke repository, dan mulai sekarang, tiap push atau pull request bakal otomatis trigger test Selenium. Kalau ada yang fail, screenshot bakal diupload sebagai artifact.
Kenapa CI/CD integration penting? Karena test yang nggak jalan otomatis pada akhirnya bakal di-skip. Manusia itu malas by nature — kalau harus ngejalanin test manual tiap deploy, lama-lama bakal dilupain. Dengan CI/CD, test jalan whether you like it or not.
Error dan Troubleshooting: Masalah yang Sering Muncul
Sekarang MUGHU mau bahas error-error yang paling sering bikin anteng jadi uring-uring saat nulis script Selenium. Teman-Teman bakal sering ketemu hal-hal ini di lapangan.
1. NoSuchElementException
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
Penyebab:
-
Elemen belum muncul di DOM (halaman belum selesai loading)
-
Locator salah — ID, class, atau XPath berubah
-
Elemen ada di dalam iframe yang belum di-switch
Solusi:
-
Pakai WebDriverWait dengan expected condition yang tepat
-
Verifikasi locator manual via DevTools (F12 → Console →
document.getElementById("id-anda")) -
Cek apakah elemen ada di dalam iframe
2. TimeoutException
selenium.common.exceptions.TimeoutException: Message:
Penyebab:
-
Elemen benar-benar nggak ada di halaman
-
Halaman load terlalu lambat (server lambat atau jaringan lemot)
-
Elemen ada tapi nggak visible (hidden, display:none)
Solusi:
Baca juga CodeBuddy: Editor Kode AI untuk Coding Lebih Cepat
-
Tingkatkan timeout value kalau memang halaman lambat
-
Kombinasikan dengan explicit wait yang spesifik
-
Cek apakah ada loading overlay yang nutup elemen
3. WebDriverException: Chrome Failed to Start
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally
Penyebab:
-
Browser tidak terinstall atau versi driver tidak cocok
-
Jalanin di environment tanpa display (CI server) tanpa mode headless
-
Konflik dengan process Chrome yang sudah jalan
Solusi:
-
Pastikan browser terinstall dan versinya terbaru
-
Tambahkan
--headless=newke options -
Kill semua process Chrome yang tertinggal (
taskkill /f /im chrome.exedi Windows ataupkill chromedi macOS/Linux) -
Tambahkan
--no-sandboxdan--disable-dev-shm-usagekalau jalanin di Docker
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
4. StaleElementReferenceException
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
Penyebab:
- Elemen yang kamu simpan referensinya sudah dihapus dari DOM atau di-render ulang (re-render)
Solusi:
-
Cari ulang elemen sebelum berinteraksi dengannya
-
Pakai retry logic dengan exception handling
from selenium.common.exceptions import StaleElementReferenceException
def find_and_click(driver, by, value, retries=3):
for attempt in range(retries):
try:
elem = driver.find_element(by, value)
elem.click()
return
except StaleElementReferenceException:
if attempt == retries - 1:
raise
import time
time.sleep(0.5)
5. SessionNotCreatedException
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version XXX
Penyebab:
- Versi chromedriver tidak cocok dengan versi Chrome yang terinstall
Solusi:
-
Kalau pakai Selenium 4.x, Selenium Manager harusnya otomatis download driver yang cocok
-
Kalau tetap error, update Chrome ke versi terbaru
-
Atau manual download driver yang sesuai dari ChromeDriver page
Dulu sebelum ada Selenium Manager, masalah versi driver ini bikin MUGHU uring-uring tiap kali Chrome auto-update. Selalu harus cek versi Chrome, cari chromedriver yang cocok, download, taruh di PATH. Sekarang dengan Selenium Manager, semua itu jadi automated — alasan kuat buat pastikan kamu selalu pakai versi Selenium terbaru.
Studi Kasus: Implementasi Selenium di Tim E-commerce
Biar lebih applicable, MUGHU mau bagikan pengalaman implementasi Selenium di salah satu project. Ini bukan fiksi — ini pattern yang umum di tim engineering Indonesia. Mari kita telusuri dari background sampai hasilnya.
Background
Sebuah tim engineering di sebuah e-commerce yang di Jakarta punya regression suite manual yang butuh hampir 4 jam buat jalan lengkap. Setiap kali ada deploy ke staging, satu QA engineer harus duduk depan laptop, buka browser, jalanin test case satu per satu — dari login, pencarian produk, add to cart, checkout, sampe payment flow. Kalau ada bug, mereka harus screenshot, catat step-by-step replay, lalu submit ke developer.
Challenge
-
Waktu test manual terlalu lama — 4 jam per cycle, dua minggu sekali
-
Flaky karena human error — kadang QA lupa ngetes satu edge case
-
Sulity scale ke multiple browsers — harus test di Chrome, Firefox, dan Safari manual
-
CI/CD belum integrated — nggak ada automated gate sebelum deploy ke production
Approach
Tim akhirnya putuskan buat adopt Selenium WebDriver dengan pytest sebagai framework. Mereka mulai dengan test yang paling critical dulu — login, search, dan checkout flow.
Implementation
Minggu 1-2: Setup dasar
-
Install Selenium dan pytest
-
Bikin base fixture yang reusable untuk WebDriver setup
-
Konfigurasi headless mode untuk CI
-
Mulai test suite dengan 5 test case paling critical
# conftest.py — Shared fixtures
import pytest
from selenium import webdriver
@pytest.fixture(scope="session")
def browser():
"""Browser instance yang dipakai selama satu test session."""
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(5)
yield driver
driver.quit()
@pytest.fixture
def logged_in_user(browser):
"""Fixture yang sudah pre-logged-in, siap pakai."""
browser.get("https://shop.contoh.co.id/login")
browser.find_element("id", "email").send_keys("[email protected]")
browser.find_element("id", "password").send_keys("password123")
browser.find_element("css", "button[type='submit']").click()
yield browser
# Logout setelah tiap test
browser.get("https://shop.contoh.co.id/logout")
Minggu 3-6: Scale test suite
-
Tambahkan test untuk search, product detail, add to cart
-
Implementasi Page Object Model buat bikin test lebih maintainable
-
Integrate ke GitHub Actions
Minggu 7-8: Cross-browser dan parallel
-
Tambahkan Firefox dan Edge ke test matrix
-
Setup Selenium Grid buat paralel execution
Results
Setelah dua bulan implementasi, ini hasil yang didapat:
Metrik | Sebelum Selenium | Setelah Selenium | Peningkatan |
|---|---|---|---|
Waktu regression test | 4 jam | 12 menit | 95% lebih cepat |
Browser yang dites | 1 (manual Chrome) | 3 (Chrome, Firefox, Edge) | 3x lipat |
Test coverage | ~60% (manual) | ~85% (automated) | +25% |
Bug post-deploy | 3-5 per release | 0-1 per release | ~70% drop |
Waktu QA per cycle | 4 jam | 15 menit (review) | 94% lebih efisien |
Key Learnings
Beberapa pelajaran berharga dari implementasi ini:
-
Mulai dari test yang paling critical — jangan target 100% coverage di hari pertama. Login dan checkout dulu, sisanya menyusul
-
Page Object Model itu game changer — pisahkan logic page interaction dari test case bikin test jauh lebih gampang di-maintain
-
Headless mode wajib untuk CI — tanpa itu, test nggak bakal jalan di server pipeline
-
Flaky test harus segera di-fix atau di-isolasi — jangan biarkan satu test flaky bikin seluruh suite nggak reliable
-
Screenshot saat fail adalah MUY importante — debugging tanpa screenshot itu kayak nyari kucing dalam ruang gelap
Best Practices yang Wajib Kamu Tahu
Berdasarkan pengalaman ngoding Selenium tahun-tahun ini, berikut best practices yang udah MUGHU validasi di lapangan:
1. Gunakan Page Object Model (POM)
POM adalah pattern yang ngepisahin logic interaksi halaman dari test case. Contohnya:
# pages/login_page.py
from selenium.webdriver.common.by import By
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.url = "https://shop.contoh.co.id/login"
# Locators
self.email_input = (By.ID, "email")
self.password_input = (By.ID, "password")
self.submit_button = (By.CSS_SELECTOR, "button[type='submit']")
self.error_message = (By.CLASS_NAME, "error-msg")
def load(self):
self.driver.get(self.url)
def login(self, email, password):
self.driver.find_element(*self.email_input).send_keys(email)
self.driver.find_element(*self.password_input).send_keys(password)
self.driver.find_element(*self.submit_button).click()
def get_error(self):
return self.driver.find_element(*self.error_message).text
# tests/test_login.py
from pages.login_page import LoginPage
def test_login_valid(driver):
login_page = LoginPage(driver)
login_page.load()
login_page.login("[email protected]", "password123")
assert "dashboard" in driver.current_url
def test_login_invalid(driver):
login_page = LoginPage(driver)
login_page.load()
login_page.login("[email protected]", "salah")
assert "Email atau password salah" in login_page.get_error()
Kenapa POM penting? Kalau UI berubah — misal ID input berubah dari email ke user-email — kamu cukup update di satu tempat (di kelas Page), bukan di semua test case.
2. Hindari Implicit Wait yang Terlalu Tinggi
# AVOID:
driver.implicitly_wait(30) # Terlalu tinggi, bikin test lambat
# BETTER:
driver.implicitly_wait(3) # Default reasonable
# Lalu pakai explicit wait buat kasus yang butuh waktu lebih
wait = WebDriverWait(driver, 15)
elem = wait.until(EC.element_to_be_clickable((By.ID, "slow-loading-btn")))
Implicit wait itu global dan nunggu penuh kalau elemen nggak ditemukan. Kalau diset 30 detik dan ada satu elemen yang memang nggak ada, tiap test yang nyari elemen itu bakal nunggu 30 detik percuma.
3. Bersihkan Data Test Sebelum dan Sesudah
Test yang bergantung pada data dari test sebelumnya adalah resep flaky. Selalu pastikan tiap test dimulai dengan state yang bersih.
Baca juga GitHub Copilot: Cara Mempercepat Kerja Tim
@pytest.fixture
def clean_cart(browser):
"""Reset cart sebelum tiap test."""
browser.get("https://shop.contoh.co.id/cart/clear")
yield browser
browser.get("https://shop.contoh.co.id/cart/clear")
4. Jangan Test Hal yang Sama Dua Kali
Kalau di unit test kamu udah ngetest logic calculation, jangan test lagi di Selenium. Selenium itu buat test integration dan UI behavior, bukan bisnis logic. Test yang overlap bikin suite lambat dan susah di-maintain.
5. Beri Nama Test yang Deskriptif
# BAD:
def test_1(driver): ...
def test_login(driver): ...
# GOOD:
def test_login_dengan_email_dan_password_valid_arah_ke_dashboard(driver): ...
def test_login_dengan_email_tidak_terdaftar_tampilkan_pesan_error(driver): ...
Nama test yang deskriptif bikin laporan test failure jauh lebih actionable. Kamu tau persis apa yang gagal dan dalam konteks apa.
Kesalahan yang Sering Dilakukan dan Cara Menghindarinya
Buat melengkapi pembahasan, ini beberapa kesalahan yang sering MUGHU lihat di tim — dan mungkin kamu juga pernah ngelakuin ya (MUGHU juga dulu gitu).
1. Pakai time.sleep() Sebagai Wait
# BAD:
import time
driver.get("https://contoh.co.id")
time.sleep(5) # Nunggu halaman load
button = driver.find_element(By.ID, "submit")
# GOOD:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.get("https://contoh.co.id")
wait = WebDriverWait(driver, 10)
button = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
time.sleep() itu kaku — nunggu penuh walau elemen udah muncul. WebDriverWait otomatis lanjut begitu kondisi terpenuhi.
2. Lupa Tutup Browser
Kalau kamu pakai webdriver.Chrome() tapi lupa driver.quit(), process Chrome dan chromedriver bakal tetap jalan di background. Lama-lama, memory mesin kamu habis.
Selalu pakai pattern try/finally atau fixture yang otomatis cleanup.
3. XPath yang Terlalu Rapuh
# BAD — kalau DOM berubah sedikit, langsung broke:
elem = driver.find_element(By.XPATH, "/html/body/div[3]/div[2]/ul/li[5]/a")
# GOOD — lebih resilient:
elem = driver.find_element(By.XPATH, "//a[contains(@class, 'product-link')][contains(text(), 'Sepatu')]")
XPath yang hardcode posisi node (div[3]/ul/li[5]) adalah jaminan test kamu bakal broke setiap kali ada perubahan kecil di layout.
4. Test Depends on Test Lain
Test A bikin user di database. Test B pakai user dari Test A buat login. Kalau Test A gagal, Test B otomatis fail juga. Tiap test harus independen.
5. Tidak Test di Environment yang Sama dengan Production
Test yang pass di local Windows tapi production jalan di Linux Docker — bisa beda hasil. Selalu test di environment yang se-mirip mungkin dengan production, terutama untuk browser version dan OS.
Selenium Grid: Scaling Test ke Level Berikutnya
Sekarang kita masuk ke topik yang lebih advanced tapi penting kalau test suite kamu udah tumbuh besar.
Selenium Grid memungkinkan kamu jalanin test secara paralel di banyak mesin. Bayangin punya 100 test case yang di jalan satu-satu butuh 30 menit. Kalau di-distribusi 10 parallel di 10 mesin, 3 menit selesai.
Konsep Dasar Grid
Grid punya dua peran utama:
-
Hub — Central point yang menerima test request dan distribute ke node yang tersedia
-
Node — Mesin yang jalanin test dengan browser yang terinstall
Setup Grid dengan Docker
Cara paling gampang buat nyobain Grid adalah pakai Docker:
# Jalankan Selenium Grid dalam mode standalone
docker run -d -p 4444:4444 --name selenium-grid selenium/standalone-chrome
# Atau pakai docker-compose untuk setup yang lebih kompleks
Buat file docker-compose.yml:
version: "3"
services:
selenium-hub:
image: selenium/hub:latest
ports:
- "4444:4444"
chrome-node:
image: selenium/node-chrome:latest
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_CONSUME_PORT=4443
firefox-node:
image: selenium/node-firefox:latest
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_CONSUME_PORT=4443
Jalankan:
docker-compose up -d
Buka browser dan ke http://localhost:4444 buat lihat Grid console. Dari situ kamu bisa lihat node yang tersedia dan session yang aktif.
Pakai Remote WebDriver
Setelah Grid jalan, kamu bisa connect ke Grid pakai Remote WebDriver:
from selenium import webdriver
from selenium.webdriver.common.options import ArgOptions
# Hub URL
hub_url = "http://localhost:4444"
# Chrome options
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
# Connect ke Grid
driver = webdriver.Remote(
command_executor=hub_url,
options=options
)
driver.get("https://selenium.dev")
print("Title:", driver.title)
print("Browser:", driver.capabilities["browserName"])
print("Platform:", driver.capabilities["platformName"])
driver.quit()
Kenapa Grid penting dari perspektif bisnis? ROI dari Grid datang dari pengurangan test execution time. Kalau kamu punya 500 test case yang masing-masing butuh rata-rata 5 detik:
-
Sequential (1 node): ~42 menit
-
Paralel 10 nodes: ~4.2 menit
-
Paralel 25 nodes: ~1.7 menit
Waktu yang dihemat ini langsung berdampak ke waktu feedback loop developer — semakin cepat tau ada bug, semakin murah fix-nya.
Alternatif Selenium: Kapan Mempertimbangkan yang Lain
Jujur saja, Selenium emang powerful tapi nggak selalu jawaban terbaik buat semua skenario. MUGHU mau jujur soal ini.
Baca juga Mengenal Astro 7.1: Framework JavaScript Ringan untuk Website
Alternatif | Kelebihan | Kekurangan | Best For |
|---|---|---|---|
Playwright | Lebih cepat, built-in auto-wait, API modern | Komunitas lebih kecil | Test modern web app (SPA) |
Cypress | Developer experience keren, real-time reload | Browser terbatas (Chromium-based), test berbayar untuk fitur paralel | Small-to-medium team, MVP testing |
Puppeteer | Sangat cepat, native Chrome DevTools Protocol | Chrome-only (Firefox support terbatas) | Scraping, Chrome-specific automation |
Selenium | Cross-browser solid, ekosistem besar, support banyak bahasa | Setup lebih ribet, API kadang verbose | Cross-browser testing yang serius, tim multi-bahasa |
Rekomendasi by use case:
-
Tim kecil yang 100% JavaScript/TypeScript dan cuma butuh test Chromium → Playwright atau Cypress
-
Enterprise yang butuh cross-browser comprehensive dan multi-bahasa → Tetap Selenium
-
Butuh otomatisasi non-test (scraping, repetitive task) → Selenium atau Puppeteer
-
Just starting out and want industry standard → Selenium, karena dokumentasi, komunitas, dan tenaga kerja yang udah familiar dengan tool ini
Salah satu alasan Selenium tetap jadi pilihan banyak enterprise adalah dukungan multi-bahasa. Tim yang punya developer Java, QA yang nulis Python, dan devops yang pakai JavaScript — semua bisa pakai Selenium dengan API masing-masing yang familiar.
Strategi Membangun Test Suite yang Maintainable
Dari pengalaman MUGHU nulis ratusan test case Selenium, ini framework mental yang MUGHU pakai:
Mulai Kecil, Tumbuh Organik
Jangan langsung bikin 200 test case di awal. Mulai dengan 5-10 test yang paling critical — login, checkout, atau flow bisnis utama. Kalau pattern-nya udah solid dan stabil, baru tambah lebih banyak.
Sekali MUGHU bikin kesalahan dengan langsung bikin 50 test case dalam seminggu. Setengahnya flaky karena belum paham timing halaman, dan bikin tim enggak percaya sama test suite. Butuh dua minggu buat stabilize semua test itu. Kalau mulai dari 5 test dan validasi pattern-nya dulu, masalahnya jadi jauh lebih kecil.
Prioritaskan Berdasarkan Business Impact
Test yang paling penting adalah test yang ng-cover flow bisnis paling critical. Buat e-commerce, itu checkout. Buat SaaS, itu signup dan onboarding. Buat banking, itu transfer dan balance inquiry.
Kalau jumlah test terbatas, fokus yang bikin duit keluar kalau broke. Test yang cek warna tombol kurang penting daripada test yang verifikasi transaksi berhasil.
Test harus Bisa Di-trust
Kalau test suite sering false-fail (flaky), developer bakal mulai menggalkan dan mengabaikan alert. Dan kalau mereka mengabaikan alert, test suite praktis nggak berguna. Lebih baik punya 50 test yang reliable daripada 200 test yang flaky.
Aturan MUGHU: kalau satu test fail lebih dari sekali tanpa code change, masuk ke "flaky list" untuk di-fix atau di-quarantine.
Invest di Infrastructure
-
Bikin test data yang consistent dan terisi otomatis
-
Setup CI/CD pipeline sejak hari pertama
-
Bikin reporting yang jelas — HTML report, Slack notification, atau Dashboard
-
Monitor test execution time — kalau suite mulai lambat, cari cara buat paralel
Kesalahan Setup yang Umum di Environment Tim
Beberapa masalah yang MUGHU sering lihat di tim, khususnya yang baru mulai adopt Selenium:
1. Versi Selenium yang Berbeda di Mesin Berbeda
Developer A pakai Selenium 4.20, Developer B pakai 4.40, CI pakai 4.30. Setiap orang dapat beda hasil. Solusi: Lock version di requirements.txt:
selenium==4.45.0
pytest==8.0.0
Dan pakai virtual environment + requirements.txt (atau pyproject.toml) di setiap mesin, termasuk CI.
2. Hardcode URL di Setiap Test File
# BAD:
driver.get("https://staging.contoh.co.id/login")
driver.get("https://staging.contoh.co.id/dashboard")
Kalau environment berubah dari staging ke production, harus replace di semua file. Solusi: Pakai config file atau environment variable.
# config.py
import os
BASE_URL = os.getenv("BASE_URL", "https://staging.contoh.co.id")
# test file
from config import BASE_URL
driver.get(f"{BASE_URL}/login")
3. Test Data yang Tidak Konsisten
Test register pakai email [email protected] yang sudah ada di database dari test lalu. Error terus. Solusi: Bikin test data dinamis dengan timestamp atau UUID.
import uuid
test_email = f"test_{uuid.uuid4().hex[:8]}@contoh.co.id"
test_user.register(email=test_email)
Performance Tuning untuk Selenium Test
Kalau test suite mulai terasa lambat, ada beberapa trik buat mempercepat:
1. Headless Mode
Headless browser jalan sekitar 30% lebih cepat karena nggak render GUI. Selalu pakai headless di CI.
2. Paralel Execution dengan pytest-xdist
pip install pytest-xdist
pytest -n 4 # Jalan 4 test secara paralel
Atau otomatis detect CPU cores:
pytest -n auto
3. Matikan Fitur yang Tidak Perlu
options = webdriver.ChromeOptions()
# Block image loading — hemat bandwidth dan waktu
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
# Disable extension
options.add_argument("--disable-extensions")
# Disable GPU (headless)
options.add_argument("--disable-gpu")
Memblok image loading bisa mempercepat test sampai 40% untuk halaman yang banyak gambar — asal test kamu nggak mau verifikasi visual image.
4. Reuse Browser Session untuk Test yang Berurutan
Kalau banyak test butuh setup yang mahal (login, load data berat), pertimbangkan buat share browser session:
@pytest.fixture(scope="session")
def browser():
"""Browser hidup sepanjang test session."""
driver = webdriver.Chrome()
yield driver
driver.quit()
@pytest.fixture(scope="class")
def logged_in(browser):
"""Login sekali per class test."""
browser.get("https://contoh.co.id/login")
browser.find_element("id", "email").send_keys("[email protected]")
browser.find_element("id", "password").send_keys("pass123")
browser.find_element("css", "button[type='submit']").click()
yield browser
Tapi hati-hati — sharing session berarti test jadi tidak fully independen. Trade-off antara speed dan isolation harus dipertimbangkan.
Baca juga 9Router v0.5.35: Solusi Rate Limit AI Coding
Selenium untuk Web Scraping: Bukan Hanya Testing
Satu hal yang jarang dibahas — Selenium juga sangat powerful buat web scraping, terutama buat site yang pakai JavaScript rendering berat.
Kasusnya gini: kamu mau ambil data dari site e-commerce buat compare harga. Tapi site-nya pakai React/Next.js, jadi kontennya di-render setelah JS jalan. requests library Python nggak bisa handle ini karena HTML yang diterima masih kosong.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
driver.get("https://books.toscrape.com/")
# Tunggu produk card muncul
wait = WebDriverWait(driver, 10)
product_cards = wait.until(
EC.presence_of_all_elements_located((By.CLASS_NAME, "product_pod"))
)
products = []
for card in product_cards:
title = card.find_element(By.CSS_SELECTOR, "h3 a").get_attribute("title")
price = card.find_element(By.CSS_SELECTOR, ".price_color").text
availability = card.find_element(By.CSS_SELECTOR, ".instock").text
products.append({
"title": title,
"price": price,
"availability": availability
})
print(f"Ditemukan {len(products)} produk:")
for p in products[:5]:
print(f" - {p['title']} | {p['price']} | {p['availability']}")
driver.quit()
Output yang diharapkan:
Ditemukan 20 produk:
- A Light in the Attic | £51.77 | In stock
- Tipping the Velvet | £53.74 | In stock
- Soumission | £50.10 | In stock
- The Sharp Objects | £47.82 | In stock
- Sapiens: A Brief History of HumanKind | £25.17 | In stock
Tapi ingat — Selenium bukan tool scraping paling efisien. Kalau site bisa di-scrape tanpa JS rendering, requests + BeautifulSoup jauh lebih cepat dan hemat resource. Selenium jadi pilihan kalau tidak ada cara lain selain render JS.
Penutup Teknis: Checklist Sebelum Test Kamu Go-Live
Sebelum kamu anggap test suite kamu siap dipakai tim, MUGHU punya checklist yang biasa dipakai buat memvalidasi:
Semua test jalan di mode headless tanpa error
Test di-install di fresh environment (dan lulus)
requirements.txtataupyproject.tomlmenentukan semua dependency dengan version pinCI/CD pipeline dikonfigurasi dan jalan green
Screenshot disimpan saat test fail
Test data setup dan teardown berfungsi
Tidak ada
time.sleep()sebagai wait strategyLocators pakai strategi yang stabil (ID > CSS > XPath)
Test di jalan minimal 3x berturut-turut dan hasilnya konsisten
Test run time masih dalam batas wajar (target: <15 menit untuk full suite)
Dilakukan setidaknya satu code review oleh teammate
Catatan tambahan untuk tim yang di Indonesia: Jika infrastruktur test kamu berlokasi di server local Jakarta atau cloud region Singapore, latency ke situs internasional umumnya 50-100ms yang cukup baik. Untuk situs lokal (.co.id), latency bisa lebih rendah dan test umumnya lebih cepat jalan. Pertimbangkan lokasi server Selenium Grid agar dekat dengan target application kamu untuk hasil yang konsisten.
Dunia otomatisasi browser dengan Selenium luas banget, dan MUGHU baru nguping permukaannya di panduan ini. Dari setup environment, interaksi dasar, framework testing, cross-browser, CI/CD, Grid scaling, sampai scraping — Selenium punya ekosistem yang mature dan terbukti di industri.
Kunci sukses bukan ada di menulis script Selenium yang pertama, tapi di membangun test suite yang reliable, maintainable, dan terintegrasi dengan workflow tim kamu. Mulai kecil, lakukan dengan benar, tumbuh organik.
Jika kamu ingin belajar lebih lanjut, dokumentasi resmi di selenium.dev cukup komprehensif, dan halaman Wikipedia Selenium (software) memberikan konteks historis yang bagus.
Kesimpulan
Perjalanan kita dari baris kode driver.get() pertama sampai konfigurasi Selenium Grid yang terdistribusi menunjukkan satu hal jelas: Selenium bukan sekadar tool, tapi ekosistem lengkap untuk otomasi browser. Dalam pengalaman MUGHU, perbedaan antara tim yang sukses dan yang terjebak bukan ada di versi library atau bahasa pemrograman yang dipilih — melainkan pada disiplin membangun test suite yang stabil, strategi locator yang konsisten, dan integrasi CI/CD yang benar-benar berjalan. Checklist go-live yang kita bahas tadi bukan formalitas, tapi jaring pengaman antara "test jalan di laptop saya" dan "test bisa dipercaya seluruh tim."
Dari sisi praktis, ada satu kebenaran yang sering diabaikan: pilih tool yang tepat untuk masalah yang tepat. Selenium bersinar saat kamu butuh interaksi browser nyata — form submission, rendering JS dinamis, validasi alur UI lintas browser. Tapi ketika halaman statis dan requests + BeautifulSoup sudah cukup, paksa diri kamu pakai Selenium justru memboroskan resource dan memperlambat eksekusi. Mengetahui kapan berhenti menggunakan Selenium sama pentingnya dengan mengetahui kapan memulainya. Untuk konteks tim di Indonesia, faktor infrastruktur seperti lokasi server Grid dan latency ke target aplikasi juga berperan besar dalam konsistensi hasil — jangan remehkan aspek geografis ini.
Setelah semua konsep, contoh kode, dan praktik yang kita bahas, langkah berikutnya ada di tangan kamu. Ambil satu kasus nyata dari proyek kamu sekarang — entah itu validasi form login, monitoring perubahan harga, atau regression test untuk fitur critical path — dan tulis satu test case dengan benar. Lalu jalankan ulang besok, dan besok lagi. Test yang lulus sekali mungkin kebetulan; test yang lulus sepuluh kali adalah fondasi. Komunitas Selenium dan dokumentasi resmi Selenium selalu terbuka sebagai referensi, tapi yang mengubah test suite kamu dari konsep jadi produksi hanyalah konsistensi kamu sendiri.
Referensi
Selenium. (2026). Selenium WebDriver: Robust Browser-Based Regression Automation and Testing.
Selenium. (2026). The Selenium Browser Automation Project: Tools and Libraries for Web Browser Automation.
WebMD. (2026). Selenium: Benefits, Uses, Side Effects, Dosage, and More.
Wikipedia. (2026). Selenium: Chemical Element, Isotopes, and Properties.
Wikipedia. (2026). Selenium (Software): Open-Source Browser Automation Tools and Framework.
WebMD. (2026). Selenium: Overview, Uses, Side Effects, Precautions, and Dosage.
Selenium. (2026). What Is Selenium? Open-Source Tool Suite for Web Application Test Automation.
Baca juga Cursor Composer 3: AI Coding 1,5T Parameter Segera Rilis
TutorialsPoint. (2026). Selenium Tutorial: Components, Features, and Usage with Examples.
Office of Dietary Supplements. (2026). Selenium: Health Professional Fact Sheet.
PyPI. (2026). Selenium: Automated Browser and Driver Management for Python.
Komentar (0)
Belum ada komentar. Jadilah yang pertama berbagi pendapat!
Tinggalkan komentar