Otomatisasi di Selenium: Model Objek Halaman dan Pabrik Halaman
Diterbitkan: 2022-03-11Menulis tes otomatis lebih dari sekadar kemewahan bagi tim pengembangan perangkat lunak yang gesit. Ini adalah kebutuhan, dan merupakan alat penting untuk menemukan bug dengan cepat selama fase awal siklus pengembangan perangkat lunak. Ketika ada fitur baru yang masih dalam tahap pengembangan, pengembang dapat menjalankan pengujian otomatis dan melihat bagaimana bagian lain dari sistem terpengaruh oleh perubahan tersebut. Artikel ini akan menjelaskan bagaimana Anda dapat mempercepat pengujian otomatis menggunakan model Objek Halaman di Selenium.
Melalui otomatisasi pengujian, dimungkinkan untuk menurunkan biaya perbaikan bug dan membawa peningkatan keseluruhan pada proses jaminan kualitas perangkat lunak (QA). Dengan pengujian yang tepat, pengembang mendapat kesempatan untuk menemukan dan menyelesaikan bug bahkan sebelum mencapai QA. Otomatisasi pengujian lebih lanjut membantu kami mengotomatiskan kasus pengujian dan fitur yang terus mengalami kemunduran. Dengan cara ini QA memiliki lebih banyak waktu dalam menguji bagian lain dari aplikasi. Selain itu, ini membantu dalam memastikan kualitas produk dalam rilis produksi. Hasilnya, kami mendapatkan produk yang secara efektif lebih stabil, dan proses QA yang lebih efisien.
Meskipun menulis tes otomatis mungkin tampak seperti tugas yang mudah bagi pengembang dan insinyur, masih ada kemungkinan berakhir dengan tes yang diimplementasikan dengan buruk, dan biaya pemeliharaan kode yang tinggi dalam proses tangkas apa pun. Mencoba untuk terus-menerus memberikan perubahan atau fitur dalam proyek pengembangan tangkas apa pun dapat terbukti mahal saat pengujian dilibatkan. Mengubah satu elemen pada halaman web yang diandalkan oleh 20 pengujian akan memerlukan satu untuk melalui 20 rutinitas pengujian ini dan memperbarui masing-masing untuk beradaptasi dengan perubahan yang baru diperkenalkan ini. Hal ini tidak hanya dapat sangat memakan waktu, tetapi juga merupakan faktor de-motivasi yang serius dalam hal penerapan pengujian otomatis sejak dini.
Tapi, bagaimana jika kita bisa membuat perubahan di satu tempat saja, dan setiap tes rutin yang relevan menggunakannya? Pada artikel ini, kita akan melihat pengujian otomatis di Selenium, dan bagaimana kita dapat menggunakan model Objek Halaman untuk menulis rutinitas pengujian yang dapat dipelihara dan digunakan kembali.
Model Objek Halaman di Selenium
Model Objek Halaman adalah pola desain objek di Selenium, di mana halaman web direpresentasikan sebagai kelas, dan berbagai elemen pada halaman didefinisikan sebagai variabel di kelas. Semua kemungkinan interaksi pengguna kemudian dapat diimplementasikan sebagai metode di kelas:
clickLoginButton(); setCredentials(user_name,user_password);
Karena metode yang diberi nama baik di kelas mudah dibaca, ini berfungsi sebagai cara yang elegan untuk mengimplementasikan rutinitas pengujian yang dapat dibaca dan lebih mudah untuk dipelihara atau diperbarui di masa mendatang. Sebagai contoh:
Untuk mendukung model Objek Halaman, kami menggunakan Pabrik Halaman. Page Factory di Selenium adalah ekstensi dari Page Object dan dapat digunakan dengan berbagai cara. Dalam hal ini kita akan menggunakan Page Factory untuk menginisialisasi elemen web yang didefinisikan dalam kelas halaman web atau Objek Halaman.
Kelas halaman web atau Objek Halaman yang berisi elemen web perlu diinisialisasi menggunakan Pabrik Halaman sebelum variabel elemen web dapat digunakan. Ini dapat dilakukan hanya melalui penggunaan fungsi initElements di PageFactory:
LoginPage page = new LoginPage(driver); PageFactory.initElements(driver, page);
Atau, lebih sederhana:
LoginPage page = PageFactory.intElements(driver,LoginPage.class)
Atau, di dalam konstruktor kelas halaman web:
public LoginPage(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }
Page Factory akan menginisialisasi setiap variabel WebElement dengan referensi ke elemen yang sesuai pada halaman web sebenarnya berdasarkan "pencari" yang dikonfigurasi. Ini dilakukan melalui penggunaan anotasi @FindBy . Dengan anotasi ini, kita dapat menentukan strategi untuk mencari elemen, bersama dengan informasi yang diperlukan untuk mengidentifikasinya:
@FindBy(how=How.NAME, using="username") private WebElement user_name;
Setiap kali metode dipanggil pada variabel WebElement ini, driver pertama-tama akan menemukannya di halaman saat ini dan kemudian mensimulasikan interaksi. Jika kami bekerja dengan halaman sederhana, kami tahu bahwa kami akan menemukan elemen pada halaman setiap kali kami mencarinya, dan kami juga tahu bahwa kami pada akhirnya akan keluar dari halaman ini dan tidak kembali ke sana, kami dapat menyimpan cache bidang yang dicari dengan menggunakan anotasi sederhana lainnya:
@FindBy(how=How.NAME, using="username") @CacheLookup private WebElement user_name;
Seluruh definisi variabel WebElement ini dapat diganti dengan bentuknya yang jauh lebih ringkas:
@FindBy(name="username") private WebElement user_name;
Anotasi @FindBy mendukung beberapa strategi lain yang membuat segalanya sedikit lebih mudah:
id, name, className, css, tagName, linkText, partialLinkText, xpath
@FindBy() private WebElement user_name; @FindBy(name="passsword") private WebElement user_password; @FindBy(className="h3") private WebElement label; @FindBy(css=”#content”) private WebElement text;
Setelah diinisialisasi, variabel WebElement ini kemudian dapat digunakan untuk berinteraksi dengan elemen terkait di halaman. Kode berikut akan, misalnya:
user_password.sendKeys(password);
… kirim urutan penekanan tombol yang diberikan ke bidang kata sandi di halaman, dan itu setara dengan:
driver.findElement(By.name(“user_password”)).sendKeys(password);
Selanjutnya, Anda akan sering menemukan situasi di mana Anda perlu menemukan daftar elemen pada halaman, dan saat itulah @FindBys berguna:
@FindBys(@FindBy(css=”div[class='yt-lockup-tile yt-lockup-video']”))) private List<WebElement> videoElements;
Kode di atas akan menemukan semua elemen div yang memiliki dua nama kelas "yt-lockup-tile" dan "yt-lockup-video". Kita dapat lebih menyederhanakan ini dengan menggantinya dengan yang berikut:
@FindBy(how=How.CSS,using="div[class='yt-lockup-tile yt-lockup-video']") private List<WebElement> videoElements;
Selain itu, Anda dapat menggunakan @FindAll dengan beberapa anotasi @FindBy untuk mencari elemen yang cocok dengan salah satu locator yang diberikan:
@FindAll({@FindBy(how=How.ID, using=”username”), @FindBy(className=”username-field”)}) private WebElement user_name;
Sekarang kita dapat merepresentasikan halaman web sebagai kelas Java dan menggunakan Page Factory untuk menginisialisasi variabel WebElement dengan mudah, sekarang saatnya kita melihat bagaimana kita dapat menulis tes Selenium sederhana menggunakan pola Page Object dan Page Factory.
Proyek Otomatisasi Uji Selenium Sederhana di Jawa
Untuk tutorial model Objek Halaman kami, mari otomatiskan pendaftaran pengembang ke Toptal. Untuk melakukan itu, kita perlu mengotomatiskan langkah-langkah berikut:
Kunjungi www.toptal.com
Klik tombol "Terapkan Sebagai Pengembang"
Di Halaman Portal, periksa dulu apakah itu dibuka
Klik tombol “Gabung Toptal”
Isi formulir
Kirim formulir dengan mengklik tombol "Gabung Toptal"
Menyiapkan Proyek
Unduh dan instal Java JDK
Unduh dan instal InteliJ Idea
Buat proyek Maven baru
Tautkan "Project SDK" ke JDK Anda, misalnya: di Windows "C:\Program Files\Java\jdkxxx"
Siapkan groupId dan artifactId:
<groupId>SeleniumTEST</groupId> <artifactId>Test</artifactId>
- Tambahkan dependensi Selenium dan JUnit Maven di file POM proyek Anda
<dependencies> <!-- JUnit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- Selenium --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-firefox-driver</artifactId> <version>${selenium.version}</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-support</artifactId> <version>${selenium.version}</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>${selenium.version}</version> </dependency> </dependencies>
Ganti versi Selenium dan Versi JUnit dengan nomor versi terbaru yang dapat ditemukan dengan mencari JUnit Maven di Google dan di situs Selenium.
Pada titik ini, jika pembuatan otomatis diaktifkan, dependensi akan mulai diunduh secara otomatis. Jika tidak, cukup aktifkan Plugins > install > install:install di bawah panel Maven Projects di sisi kanan IDE IntelliJ Idea Anda.
Setelah proyek di-bootstrap, kita dapat mulai membuat paket pengujian di bawah "src/test/java". Beri nama paket "com.toptal", dan buat dua paket lagi di bawahnya: "com.toptal.webpages" dan "com.toptal.tests".

Kami akan menyimpan kelas Objek Halaman/Pabrik Halaman kami di bawah "com.toptal.webpages" dan rutinitas pengujian di bawah "com.toptal.tests".
Sekarang, kita dapat mulai membuat kelas Objek Halaman.
Objek Halaman Beranda
Yang pertama kita perlu menerapkan adalah untuk homepage Toptal (www.toptal.com). Buat kelas di bawah "com.toptal.webpages" dan beri nama "HomePage".
package com.toptal.webpages; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.How; import org.openqa.selenium.support.PageFactory; public class HomePage { private WebDriver driver; //Page URL private static String PAGE_URL="https://www.toptal.com"; //Locators //Apply as Developer Button @FindBy(how = How.LINK_TEXT, using = "APPLY AS A DEVELOPER") private WebElement developerApplyButton; //Constructor public HomePage(WebDriver driver){ this.driver=driver; driver.get(PAGE_URL); //Initialise Elements PageFactory.initElements(driver, this); } public void clickOnDeveloperApplyButton(){ developerApplyButton.click(); } }
Menentukan Pencari Elemen
Di beranda Toptal, kami tertarik pada satu elemen khususnya, dan itu adalah tombol "Terapkan sebagai Pengembang". Kita dapat menemukan elemen ini dengan mencocokkan teks, yang sedang kita lakukan di atas. Saat memodelkan halaman web sebagai kelas Objek Halaman, menemukan dan mengidentifikasi elemen seringkali bisa menjadi tugas. Dengan alat debugging Google Chrome atau Firefox, ini dapat dibuat lebih mudah. Dengan mengklik kanan pada elemen apa pun di halaman, Anda dapat mengaktifkan opsi "Periksa Elemen" dari menu konteks untuk mengetahui informasi terperinci tentang elemen tersebut.
Salah satu cara umum (dan pilihan saya) adalah menemukan elemen menggunakan ekstensi FireBug Firefox, yang dikombinasikan dengan driver web Firefox di Selenium. Setelah menginstal dan mengaktifkan ekstensi FireBug, Anda dapat mengklik kanan pada halaman dan memilih "Inspect element with FireBug" untuk membuka FireBug. Dari tab HTML FireBug, Anda dapat menyalin XPath, CSS Path, Tag name, atau “Id” (jika tersedia) dari elemen apa pun di halaman.
Dengan menyalin XPath elemen pada tangkapan layar di atas, kita dapat membuat bidang WebElement untuknya di Objek Halaman kita sebagai berikut:
@FindBy(xpath = "/html/body/div[1]/div/div/header/div/h1") WebElement heading;
Atau untuk menyederhanakannya, kita dapat menggunakan nama tag “h1” di sini, asalkan secara unik mengidentifikasi elemen yang kita minati:
@FindBy(tagName = "h1") WebElement heading;
Objek Halaman DeveloperPortalPage
Selanjutnya, kita membutuhkan Objek Halaman yang mewakili halaman portal pengembang, yang dapat kita jangkau dengan mengklik tombol “Terapkan Sebagai Pengembang”.
Di halaman ini, kami memiliki dua elemen yang menarik. Untuk menentukan apakah halaman telah dimuat, kami ingin memverifikasi keberadaan heading. Dan kami juga menginginkan bidang WebElement untuk tombol "Gabung Toptal".
package com.toptal.webpages; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class DeveloperPortalPage { private WebDriver driver; @FindBy(xpath = "/html/body/div[1]/div/div/header/div/h1") private WebElement heading; @FindBy(linkText = "JOIN TOPTAL") private WebElement joinToptalButton; //Constructor public DeveloperPortalPage (WebDriver driver){ this.driver=driver; //Initialise Elements PageFactory.initElements(driver, this); } //We will use this boolean for assertion. To check if page is opened public boolean isPageOpened(){ return heading.getText().toString().contains("Developer portal"); } public void clikOnJoin(){ joinToptalButton.click(); } }
Objek Halaman DeveloperApplyPage
Dan akhirnya, untuk objek halaman ketiga dan terakhir untuk proyek ini, kami mendefinisikan satu yang mewakili halaman yang berisi formulir aplikasi pengembang. Karena kita harus berurusan dengan sejumlah bidang formulir di sini, kita mendefinisikan satu variabel WebElement untuk setiap bidang formulir. Kami menemukan setiap bidang dengan "id" mereka dan kami mendefinisikan metode penyetel khusus untuk setiap bidang yang mensimulasikan penekanan tombol untuk bidang yang sesuai.
package com.toptal.webpages; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class DeveloperApplyPage { private WebDriver driver; @FindBy(tagName = "h1") WebElement heading; @FindBy() WebElement developer_email; @FindBy() WebElement developer_password; @FindBy() WebElement developer_password_confirmation; @FindBy() WebElement developer_full_name; @FindBy() WebElement developer_skype; @FindBy() WebElement join_toptal_button; //Constructor public DeveloperApplyPage(WebDriver driver){ this.driver=driver; //Initialise Elements PageFactory.initElements(driver, this); } public void setDeveloper_email(String email){ developer_email.clear(); developer_email.sendKeys(email); } public void setDeveloper_password(String password){ developer_password.clear(); developer_password.sendKeys(password); } public void setDeveloper_password_confirmation(String password_confirmation){ developer_password_confirmation.clear(); developer_password_confirmation.sendKeys(password_confirmation); } public void setDeveloper_full_name (String fullname){ developer_full_name.clear(); developer_full_name.sendKeys(fullname); } public void setDeveloper_skype (String skype){ developer_skype.clear(); developer_skype.sendKeys(skype); } public void clickOnJoin(){ join_toptal_button.click(); } public boolean isPageOpened(){ //Assertion return heading.getText().toString().contains("Apply to join our network as a developer"); } }
Menulis Tes Selenium Sederhana
Dengan kelas Objek Halaman yang mewakili halaman kita, dan interaksi pengguna sebagai metodenya, sekarang kita dapat menulis rutin pengujian sederhana kita sebagai serangkaian pemanggilan metode dan pernyataan sederhana.
package com.toptal.tests; import com.toptal.webpages.DeveloperApplyPage; import com.toptal.webpages.DeveloperPortalPage; import com.toptal.webpages.HomePage; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import java.net.URL; import java.util.concurrent.TimeUnit; public class ApplyAsDeveloperTest { WebDriver driver; @Before public void setup(){ //use FF Driver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); } @Test public void applyAsDeveloper() { //Create object of HomePage Class HomePage home = new HomePage(driver); home.clickOnDeveloperApplyButton(); //Create object of DeveloperPortalPage DeveloperPortalPage devportal= new DeveloperPortalPage(driver); //Check if page is opened Assert.assertTrue(devportal.isPageOpened()); //Click on Join Toptal devportal.clikOnJoin(); //Create object of DeveloperApplyPage DeveloperApplyPage applyPage =new DeveloperApplyPage(driver); //Check if page is opened Assert.assertTrue(applyPage.isPageOpened()); //Fill up data applyPage.setDeveloper_email("[email protected]"); applyPage.setDeveloper_full_name("Dejan Zivanovic Automated Test"); applyPage.setDeveloper_password("password123"); applyPage.setDeveloper_password_confirmation("password123"); applyPage.setDeveloper_skype("automated_test_skype"); //Click on join //applyPage.clickOnJoin(); } @After public void close(){ driver.close(); } }
Menjalankan Tes
Pada titik ini, struktur proyek Anda akan terlihat seperti ini:
Jika Anda ingin menjalankan tes, pilih "ApplyAsDeveloperTest" dari pohon, klik kanan padanya dan kemudian pilih Jalankan 'ApplyAsDeveloperTest' .
Setelah pengujian dijalankan, Anda dapat melihat hasilnya di sudut kiri bawah IDE Anda:
Kesimpulan
Objek Halaman dan Pabrik Halaman memudahkan untuk memodelkan halaman web di Selenium dan mengujinya secara otomatis dan membuat kehidupan pengembang dan QA jauh lebih sederhana. Jika dilakukan dengan benar, kelas Objek Halaman ini dapat digunakan kembali di seluruh rangkaian pengujian Anda dan memberi Anda kesempatan untuk mengimplementasikan pengujian Selenium otomatis untuk proyek Anda sejak awal, tanpa mengorbankan pengembangan yang gesit. Dengan mengabstraksikan interaksi pengguna dalam model objek halaman Anda dan menjaga rutinitas pengujian Anda tetap ringan dan sederhana, Anda dapat menyesuaikan rangkaian pengujian Anda dengan perubahan persyaratan dengan sedikit usaha.
Saya harap saya telah berhasil menunjukkan kepada Anda cara menulis kode pengujian yang bagus dan bersih yang mudah dirawat. Saya akan mengakhiri artikel dengan kutipan QA favorit saya:
Pikirkan dua kali, kode sekali!