ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 5. Java + Selenium 테스트를 만들 수 있다
    스프링개발자/202 - 디버깅+테스팅 2020. 8. 15. 05:16

    이번 글은 API testing 이 아니라 Front-end UI testing 이다.

    Fullstack testing?이라는게 있는지는 모르겠지만, backend application 도 간단한 홈페이지 정도는 있는 경우가 많으니, 웹 자동테스팅도 알면 나쁠건 없다.


    1. 의존성 추가

    mvnrepository.com에서 selenium java를 검색한 결과이다

    다음의 의존성을 gradle에 추가하자

    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'

    2. SeleniumConfig

    package me.ndPrince.routeOptimization.selenium.config;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    import java.util.concurrent.TimeUnit;
    
    public class SeleniumConfig {
    
        static {
            System.setProperty("webdriver.chrome.driver", "D:\\chromedriver\\chromedriver.exe");
        }
    
        private WebDriver driver;
        private static SeleniumConfig instance = null;
    
        private SeleniumConfig() {
            driver = new ChromeDriver();
            driver.manage().window().fullscreen();
            driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        }
    
        // Singleton: same instance injected/autowired wherever called from
        public static SeleniumConfig getInstance() {
            if (instance != null) return instance;
            return new SeleniumConfig();
        }
    
        public void clickElement(WebElement element){
            element.click();
        }
    
        public void close(){
            driver.close();
        }
    
        public void navigateTo(String url){
            driver.navigate().to(url);
        }
    
        public WebDriver getDriver(){
            return driver;
        }
        
    }
    

    1) 컴퓨터에 설치된 크롬 버전에 맞는, 크롬드라이버를 다운받고, 경로를 설정해준다

    2) 인스턴스가 하나만 만들어지게끔, private consturctor와 public static getInstance 메소드를 사용해준다

    3) 자주 사용하는 기능들을 여기에 메소드로 정의해둔다

     

    3. BasePage

    package me.ndPrince.routeOptimization.selenium.page;
    
    import me.ndPrince.routeOptimization.selenium.config.SeleniumConfig;
    
    public class BasePage {
    
        SeleniumConfig config = SeleniumConfig.getInstance();
        protected static final String URL = "http://demo.guru99.com/test/login.html";
    
        // Example of shared code
        public void closeWindow() {
            config.close();
        }
    
        public String currentPageUrl(){
            return config.getDriver().getCurrentUrl();
        }
    }
    

    1) guru99의 selenium 튜토리얼의 도움을 받았다. 그 곳의 데모 페이지를 예제로 설정한다

    2) 웹테스트는, 테스트의 대상이 모두 페이지 안에 있으므로, 세부 페이지들이 BasePage를 extend 하게끔 설계한다

     

    4. HomePage

    package me.ndPrince.routeOptimization.selenium.page;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;
    
    public class HomePage extends BasePage {
    
        @FindBy(className = "gLFyf gsfi")
        private WebElement searchTextBox;
    
        @FindBy(className = "gNO89b")
        private WebElement searchButton;
    
        public HomePage(){}
    
        public HomePage(WebElement searchTextBox, WebElement searchButton) {
            this.searchTextBox = searchTextBox;
            this.searchButton = searchButton;
        }
    
        public void goToHomePage(){
            config.navigateTo(URL);
        }
    
        public void enterEmailText(String address){
            WebElement email = config.getDriver().findElement(By.id("email"));
            email.sendKeys(address);
        }
    
        public void enterPassword(String pw){
            WebElement password = config.getDriver().findElement(By.name("passwd"));
            password.sendKeys(pw);
        }
    
        public void clickLoginButton(){
            WebElement login = config.getDriver().findElement(By.id("SubmitLogin"));
            login.click();
        }
    }
    

    1) BasePage를 extends 하는 세부 페이지, 홈페이지를 만든다

    2) 홈페이지에 국한된 WebElement와 action들을 필드와 메소드로 만들어 놓는다

     

    5. HomePageTest

    package me.ndPrince.routeOptimization.selenium.page;
    
    import org.junit.Assert;
    import org.junit.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    
    
    class HomePageTest {
        private static HomePage home;
    
        @BeforeAll
        public static void setUp(){
            home = new HomePage();
        }
    
        @AfterAll
        public static void tearDown(){
            home.closeWindow();
        }
    
        @Test
        public void HomePage_EnterEmail() throws InterruptedException {
            home.goToHomePage();
            Thread.sleep(2000);
            home.enterEmailText("abc@gmail.com");
            Thread.sleep(2000);
            home.enterPassword("abc");
            Thread.sleep(2000);
            home.clickLoginButton();
            Thread.sleep(2000);
            String currentURL = home.currentPageUrl();
            Assert.assertEquals("asdf", currentURL);
        }
    }

    1) action중간중간에 sleep을 줘야 할 때가 있다. 눈으로 직접 보고 싶을때, 인터넷이 느리거나, 응답 받는데 시간이 걸리는 경우.. 은근히 많이 발생하는 상황이다

    2) Login버튼을 누르면, 로그인 홈페이지가 아니라 다른 페이지로 이동한다.

    3) 일부로 expected URL을 "asdf"로 두었다. 실패하는 것을 확인하려고. 비디오를 첨부한다.

     

    유튜브에서 보려면 https://youtu.be/lrT7JlEJK_w

    Selenium testing또한 이전과 마찬가지로 전용 어노테이션과 함께 gradle task를 만들어 관리할 수 있다.

     

    이번 시리즈도 여기서 끝.

     

    300레벨의 테스트에서는 우리가 로컬에서 구현한 테스트들을 Cloud환경으로 올려서 운영과 logging, monitoring, dashboard, alert 등의 기능을 구현해보자.

     

    소스코드

    https://github.com/2ndPrince/routeOptimization/tree/selenium_java

     

    바로 이전 branch와 diff를 보고 싶으면 아래 클릭

    https://github.com/2ndPrince/routeOptimization/compare/spring_validation_3_value_added...selenium_java

     

Designed by Tistory.