Web Automation Testing Menggunakan Java, Selenium, dan Cucumber Dengan Design Pattern POM dan Page Factory

Di artikel ini dijelaskan dari A-Z bagaimana melakukan automation testing pada web dari instalasi sampai membuat report untuk automation testing.

Supaya lebih jelas, pembaca dapat membaca artikel sebelumnya yang membahas tentang:

Persiapan

1. Download dan Install

Download dan instal untuk setiap item di bawah ini:

ItemURL
EditorIntellij IDEA Community
https://www.jetbrains.com/idea/download/
Web DriverChrome
https://chromedriver.chromium.org/
Mozilla Firefox
https://github.com/mozilla/geckodriver/releases
JavaJDK 8
https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
Browser versi terbaruChrome
https://www.google.com/chrome/
Mozilla
https://www.mozilla.org/en-US/firefox/new/

2. Memulai project

Sesuai design pattern yang digunakan, maka kita perlu membuat package pages dan steps beserta package atau folder lainnya sesuai yang kita butuhkan. Berikut contoh struktur folder-nya:

Keterangan:

  • helpers: package untuk menyimpan class atau method yang tidak unik, dan sering digunakan. Misal: class Runner, class ScreenSction, dll.
  • pages: semua screen atau page web yang dijadikan class, semuanya ada di package ini.
  • setups: class-class atau method yang digunakan untuk mengkonfigurasi automation, semuanya ada di package ini.
  • steps: package yang berisi class-class step definitions.
  • features: untuk menyimpan skenario automation yang ditulis menggunakan Gherkin.

3. Instalasi Web Driver

Pada artikel ini, web driver yang akan digunakan adalah chromedriver untuk browser Chrome dan geckodriver untuk Mozilla Firefox.

Windows, Linux, dan Mac OS

Salin chromedriver dan geckodriver yang sudah diunduh ke direktory/folder resources yang ada di dalam struktur folder project.

4. Environment Variable

Untuk pengaturan environment, dapat dilakukan dengan membaca artikel sebelumnya di sini.

5. Import dependency dari Maven Repository

Untuk memahami dependency, dapat membaca artikel sebelumnya di sini.

Berikut minimal dependency yang di-import ke file pom.xml:

artifactIdgroupIdversion
selenium-javaorg.seleniumhq.selenium3.141.59
selenium-firefox-driverorg.seleniumhq.selenium3.12.0
selenium-safari-driverorg.seleniumhq.selenium3.12.0
selenium-chrome-driverorg.seleniumhq.selenium3.12.0
cucumber-junitinfo.cukes1.2.5
cucumber-javainfo.cukes1.2.5
cucumber-javaio.cucumber6.9.1
cucumber-coreinfo.cukes1.2.5
gherkininfo.cukes2.12.2
java-clientio.appium7.2.0
selenium-apiorg.seleniumhq.selenium3.141.59
testngorg.testng6.14.3

Tambahkan kode di bawah di bawah tag <project> pada pom.xml.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Memulai Web Automation Testing

Kita akan menggunakan web Google Search sebagai contoh automation testing-nya.

1. Menulis skenario dengan Gherkin

Tentang Gherkin, rekan pembaca dapat membaca artikel sebelumnya di sini.

Semua skenario disimpan di dalam folder features, sebagai berikut langkahnya:

Pada artikel ini, kita membuat 1 feature yaitu Searching.

  1. Dengan menggunakan editor Intellij Idea, kita buat file baru.
  2. Tuliskan 1 feature di bawah.
  3. Jika sudah, simpan dengan ekstensi .feature

Searching.feature

@SearchingGoogle
Feature: Searching Google

@sosmed @smoke
Scenario Outline:  User want to search sosmed
Given User open google web
Then User type the keyword "<sosmed>"
Then User want to check the result "<sosmed>"
Examples:
| sosmed |
| @twitter |
| @facebook |
| @instagram |

@price @smoke
Scenario:  User want to search a price
Given User open google web
Then User type the keyword "camera harga Rp 300000"
Then User want to check the result "camera harga Rp 300000"

Step-step di atas terlihat seperti ter-highlight, dikarenakan belum ada glue step-nya, yang artinya, step-step pada skenario di atas belum dibuat step definition-nya. Saat dibuat step definition-nya, maka highlight kuning akan hilang dengan sendirinya.

Rekan pembaca dapat menambahkan step pada feature Searching, atau juga dapat menambahkan file feature sendiri.

3. Men-setup automation

Berikutnya kita akan mengatur automation-nya dengan membuat class-class pada package setups:

  • BrowserPool.java
  • BrowserSetup.java
  • Hook.java

BrowserPool.java

package setups;

import org.openqa.selenium.WebDriver;

public class BrowserPool {
    private static WebDriver browserInstance;

    public static WebDriver getBrowserInstance() {
        return BrowserPool.browserInstance;
    }

    public void setBrowserInstance(WebDriver instance) {
        BrowserPool.browserInstance = instance;
    }
}

Class BrowserPool ini merupakan setter getter untuk browser yang ada di class BrowserSetup.

BrowserSetup.java

package setups;

import org.openqa.selenium.chrome.ChromeDriver;

public class BrowserSetup extends BrowserPool{
    ChromeDriver browser;

    protected void startBrowser() {
        System.setProperty("webdriver.chrome.driver","src/test/resources/chromedriver");
        browser = new ChromeDriver();
        setBrowserInstance(browser);
    }

    protected void stopBrowser() {
        browser.close();
    }
}

Hook.java

package setups;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hook extends BrowserSetup{
    @Before
    public void before() throws Exception {
        startBrowser();
    }

    @After
    public void after() throws Exception {
        stopBrowser();
    }
}

Anotasi @Before, berarti method akan dijalankan sebelum step definition dijalankan.

Anotasi @After, berarti method akan dijalankan setelah step definition selesai dijalankan.

4. Membuat pages

Karena menggunakan design pattern POM, maka kita perlu membuat pages. Untuk konsep design pattern POM dapat membaca artikel sebelumnya di sini.

Berdasarkan skenario di atas, kita akan membuat 2 pages: Home Page dan Search Page.

Untuk mendapatkan nama-nama element, dapat membaca artikel sebelumnya di sini.

HomePage.java

package pages;

import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class HomePage {
    private WebDriver browser;

    public HomePage(){

    }

    public HomePage(WebDriver browser){
        this.browser = browser;
        PageFactory.initElements(browser, this);
    }

    @FindBy(name = "q")
    private WebElement searchField;

    @FindBy(name = "btnK")
    private WebElement searchBtn;

    @FindBy(name = "btnI")
    private WebElement luckyBtn;

    public void inputKeyword(String keyword) throws InterruptedException {
        searchField.sendKeys(keyword);
        Thread.sleep(2000);
    }

    public void clickSearchBtn() throws InterruptedException {
        searchBtn.click();
        Thread.sleep(2000);
    }

    public void clickLuckyBtn() throws InterruptedException {
        luckyBtn.click();
        Thread.sleep(2000);
    }

    public void pressEnter(){
        searchField.sendKeys(Keys.RETURN);
    }
}

SearchPage.java

package pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class SearchPage {
    private WebDriver browser;

    public SearchPage(){

    }

    public SearchPage(WebDriver browser){
        this.browser = browser;
        PageFactory.initElements(browser, this);
    }

    @FindBy(name = "q")
    private WebElement searchField;

    public void inputKeyword(String keyword) throws InterruptedException {
        searchField.sendKeys(keyword);
        Thread.sleep(2000);
    }

    public void clearKeyword() throws InterruptedException {
        searchField.clear();
        Thread.sleep(2000);
    }
}

5. Mendefinisikan step

Step inilah yang nantinya akan melakukan interaksi-interaksi seperti yang dilakukan secara manual oleh tangan manusia. Di dalam step definition, kode-kode automation dituliskan.

File steps diletakkan di dalam folder step_definitions.

Step definition di-generate berdasarkan skenario yang sudah ditulis menggunakan Gherkin tadi. Tiap step pada Gherkin menjadi method-method pada Java.

Cara men-generate step-nya adalah sebagai berikut:

1. Buka file skenario.
2. Letakkan kursor pada baris pertama atau baris step yang belum di-generate step-nya.


3. Tekan kombinasi tombol pada keyboard Alt + Enter untuk Windows/Linux atau Option + Enter untuk MacOS.


4. Klik Create step definition.


5. Berikan nama class step definition dan pilih Java, pastikan file location di dalam package steps, lalu klik OK.

Ulangi langkah di atas untuk semua step yang belum di-generate.
Pilih class SearchingStep setelah klik Create step definition.

Jika semua sudah di-generate, maka tampilan SearchingStep.java menjadi seperti berikut:

SearchingStep.java

Dari step di atas, dimodifikasi untuk disesuaikan dengan class pages yang sudah dibuat di atas tadi. Menjadi demikian:

package steps;

import cucumber.api.PendingException;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import pages.HomePage;

import static setups.BrowserPool.getBrowserInstance;

public class SearchingStep {
    HomePage homePage = new HomePage(getBrowserInstance());

    @Given("^User open google web$")
    public void userOpenGoogleWeb() {
        getBrowserInstance().navigate().to("https://www.google.com/");
    }

    @Then("^User type the keyword \"([^\"]*)\"$")
    public void userTypeTheKeyword(String keyword) throws Throwable {
        homePage.inputKeyword(keyword);
        homePage.pressEnter();
    }

    @Then("^User want to check the result \"([^\"]*)\"$")
    public void userWantToCheckTheResult(String arg0) throws Throwable {

    }
}

6. Membuat helper

Package helper akan diisi class Runner dan class ScreenAction.
Class Runner menjadi class yang dipanggil untuk menjalankan automation-nya, tetapi juga class yang memiliki method untuk men-generate report secara otomatis. Sedangkan class ScreenAction digunakan untuk jenis-jenis interaksi seperti scroll, screenshot, dll.

Kedua class tersebut dibuat di dalam package helper.

Runner.java

package helpers;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
        features = {"src/test/resources/features"},
//        tags = {"@sosmed"},
        glue = {""},
        plugin = {"pretty","json:target/cucumber.json","html:target/report"},
        monochrome = true
)

public class Runner {

}

ScreenAction.java

package helpers;

import cucumber.api.Scenario;
import io.cucumber.java.AfterStep;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;

import static setups.BrowserPool.getBrowserInstance;

public class ScreenAction {
    @AfterStep
    public void screenShot(Scenario scenario){
        TakesScreenshot take = (TakesScreenshot) getBrowserInstance();
        byte[] tempImg = take.getScreenshotAs(OutputType.BYTES);
        scenario.embed(tempImg, "image/png");
    }
}

7. Menjalankan automation

  1. Buka class Runner.java.
  2. Klik kanan pada class tersebut.
  3. Klik Play

8. Screenshot contoh report

Dengan konfigurasi option pada Runner.java, maka report HTML akan ter-generate otomatis di folder target/report.

Leave a comment