Selenium’da Page Object Pattern yapısı

Semih Saydam
4 min readMar 4, 2020

--

Merhabalar,

Öncelikle bana verdiği değerli bilgiler ve eğitim için Sayın Emre Orhan’a teşekkürlerimi sunarım.

Bu yazımda size Page Object Pattern yapısından bahsedeceğim ve bir uygulama da yapacağız. Bu yazıya geçmeden önce temel bilgiler ve kurulum’un olduğu bunu okuyunuz. Hadi başlayalım :)

Page Object Pattern sayesinde bakımı daha kolay , anlaşılır ve takip edilebilir kodlar yazarız. Tekrar kullanılabilir yapılar oluşturmamızı da sağlar. Özellikle agile bir process izliyorsanız testlerin sürdürebilirliğini artırır. Bir sistematiğe oturturuz ve bir şeyleri değiştirmek istediğimizde nereden değişiklik yapacağımızı biliriz. Kısa bir tanım verdikten sonra şimdi işe koyulma vakti.

Öncelikle Bu özet fotoğraf size tüm haritayı veriyor olacak. Biz de bu harita üzerinden kodlamamızı yapıyor olacağız. Util , database gibi işleri yapacağımız kısım fakat ana işlemlerimizi etkilemeyeceğinden onu özet bilgiye koymayacağım.

Harita

Şimdi haritamızda yazan class’ların içlerini dolduracağız. Öncesinde class’ları tanıtmak istiyorum. BasePage’de sürekli kullandığımız ifadeleri fonksiyonlama işlemlerini yapıyoruz. driver.findElement(By.id(“search”)) işlemini yapmak yerine bunu bir fonksiyona atıyoruz ve bu uzun ifadeyi yazmaktan kurtuluyoruz. Bunu sendKeys vb. çoğu şey için yapıyoruz.

BaseTest’de ise gerekli kurulumları yapacağız. ChromeDriver’la ilgili işlemler, gideceğimiz site vs. gibi işlemleri burada tutacağım.

ConstantsLoginPage kısmında ise sabitlerimizi tanımlayacağız. Sabitleri büyük harf ve istenirse alt çizgi ile isimlendiriyoruz. public static final ile tanımlayacağız. Örneğin public static final By INPUT = By.id(“search”) şeklinde bir tanımlama yapıyoruz. Artık driver.findElement(INPUT) dememiz yeterli oluyor search id’li elementi bulabilmek için. Buna fonksiyonlamayı da eklediğimizde çok kısa bir yazım oluyor. Constants’lar By tipinde olduğu gibi String gibi tiplerde de olabilir. ConstantsLoginPage class’ımızın içine yazdıklarımızı başka bir class içinde kullanmak için kullanacağım class’da import yapmamız gerekiyor.

Evet yukarıda yazdığımız classlar LoginPage’imizi besleyecek. Gerekli fonksiyonları, Stringleri ve By ifadelerini bize sağlayacak. LoginPage’de Base ve Constants’tan gelenleri birleştiriyoruz ve bunlarla işlerimizi methodlara döküyoruz. Mesela bir yere tıklanacaksa BasePage’de tanımlanan tıklanma kısaltmasını alıyoruz ve içine Constants’dan gelen tıklanacak yerin By locator’ını alıyoruz ve oraya tıklıyoruz. Yani LoginPage birleştirici bir görev yapıyor.

Son olarak LoginPageTest yani artık Run işlemini yapacağımız class’ımıza bakalım. Burada LoginPage’imizden bilgileri alıp istediğimiz senaryoyla uygulayacağız. Burası senaryomuzun yönetildiği kısım olacaktır. Mesela LoginPage kısmındaki bir fonksiyon sepete tıklıyor diyelim, ben o sepete ne zaman tıklanacağı, hangi işlemden sonra olacağını vs. LoginPageTest kısmında yapıyorum.

Umarım kafanızda bir harita oluşmuştur. Şimdi bir senaryo verelim ve yapmaya çalışalım. Yine senaryoyu kısa tutacağım. Çünkü burada asıl amacımız Page Object Pattern ‘i anlayabilmek.

Hepsiburada sitesine gidip giriş yapalım ardından arama kısmına bir yazı yazalım ve aratalım. Bu şekilde kısa bir senaryo yeterli olacaktır.

Yapı şu şekilde gözükmelidir :

Haritaya uyalım Ve BaseTest.java ile başlayalım. Fakat başlamadan önce bu link üzerindeki son sürüm Selenium Java, Selenium Server ve Apache Log4j Core ‘un pom.xml ‘ içindeki <dependencies> kısmına eklenmiş olduğundan emin olunuz.

BaseTest.java

Burada oluşturulan getter ve setter yapısına dikkat edelim. Options ile tarayıcı ile ilgili ayarları yaptık(notifications engelleme, başlangıçta büyük ekran başlatma). En önemlisi chromeDriver’ın konumunu verdik. Ve gitmek istediğimiz siteye navigate olduk.

Şimdi BasePage.java dosyamızı oluşturalım.

BasePage.java

Gördüğünüz üzere işlemlerimizi methodlaştırdık. Mesela en basiti driver.findElement(By.id(..)) yazmak yerine findElement(By.id) yazsak artık yeterli olacaktır. Tabii ki BasePage’ten kalıtım alman lazım yazacağın class’ta. Bunun haricinde elementin text’ini çekmek için, elemente text göndermek ve en önemlisi hoverElement() ile bir elementin üzerine gitme yazdık. Önemli diyorum çünkü action işlemidir. Action ve Select işlemlerini araştırabilmeniz için linkleri bırakıyorum. Ve BasePage için bir constructor oluşturduk. Böylelikle BasePage’den object oluşturmak istediğiniz anda constructor yani yapıcı methodumuz bir driver isteyecektir. Verdiğiniz driver BasePage’in kimliğini oluşturacak ve yukarıdaki methodları o driver’a göre çalıştırıyor olacaktır.

Şimdi ConstantsLoginPage’i yazalım. Burada By locators ile ihtiyacımız olacak elementleri yakalayıp hepsini yazacağız ki LoginPage’i besleyebilelim.

ConstantsLoginPage.java

Bulduğum elementleri sabitlere atadıktan sonra artık LoginPage’ime geçebilirim.

LoginPage.java

Öncelikle üst kısımdan başlarsak, Constants’ları import ettiğimize dikkat edelim. Eğer import etmezsen sabitlerini kullanamazsın. İkinci dikkat etmemiz gereken şey ise yazdığım methodlardan LoginPage tipinde bir çıktı istiyorum return ile. Bu olay recursive yani öz yinelemedir. Bu sayede biz az sonra LoginPageTest’de methodlarımızı ardı ardına çağırabileceğiz. Mesela loginPage.sendPassword().clickButton()… şeklinde.

Bir de mesela search methodumuzu inceleyerek olayı anlayalım. İçindeki sendKeys() ‘ bizim BasePage’de yazdığımız bir methoddu. Yani BasePage’den beslendik. Sonra sendKeys( )’ içindeki SEARCH_AREA ise ConstantsLoginPage’den geliyor. Yani ConstanstLoginPage’den de beslenmiş olduk. Bu beslemeleri harmanladık ve şimdi LoginPageTest’imizde çağırıp çalıştıracağız.

LoginPageTest.java

LoginPageTest’imizi çalıştırdık ve senaryomuz gerçekleşti. Burada “@Test” kısmında fonksiyonları LoginPage’den ardı ardına çekebildiğimize dikkat edelim. Burada BaseTest’ten kalıtım aldığımıza ve loginPage’e driver’ı yolladığımıza dikkat edelim.

Biraz karmaşık bir olay ama alıştıktan sonra eminim daha rahat edeceksiniz. Özetle, BasePage bir anne ve loginpage gibi birçok çocuğu var. Ve bu çocuklara driver’ı kullanma ve driver üzerinden tıklama vb. gibi yetenekleri veriyor. Fakat driver’ı direkt çocuklarına vermiyor. BaseTest ise driver sağlayıcısı ve test yapabilmeniz için bir driver’ınız olmanız gerekiyor. Örneğin LoginPage çocuğu, test yapmak istediğinde LoginPageTest üzerinde yapıyor ve annesinden aldığı yetenekleri burada sergileyecek. Fakat driver’ı eksik olduğu için BaseTest’ten yani babasından driver’ını alıp, annesinin yeteneklerini kullanıyor :)

Başka bir yazıda görüşmek üzere. Mutlu günler dilerim :)

--

--

Semih Saydam
Semih Saydam

Written by Semih Saydam

QA / DevOps Engineer — Be happy :)

No responses yet