미니옵빠의 code stubs

Selendroid 따라해보기 본문

Test

Selendroid 따라해보기

미니옵빠 2016. 12. 19. 15:51

Selendroid 따라해보기

  • Selendroid가 무엇인지, 어떻게 동작하는지 이해하기 위해 간단히 따라해보기 위한 목적

Selendroid: Selenium for Android

Getting started

준비물

  1. Java SDK (1.6 이상). 이 문서는 jdk1.8.0_51 기준
  2. Android SDK

    • https://developer.android.com/studio/index.html 여기에서 Android Studio를 다운 받아 설치. 이 문서는 Studio 2.2.3 (145.3537739) / SDK 25.0.2 기준
    • 가이드에는 SDK만 필요하다고 되어 있으나, 실제 실행에 필요한 build-tools/aapt.exe 파일 등이 설치되지 않음
    • 설치 추천 위치

      • Studio: C:\Android Studio
      • SDK: C:\Android


  3. Selendroid standalone jar 다운로드
  4. selendroid test app 다운로드
  5. 시스템 환경 변수 설정

    • JAVA_HOME 설정. jdk Path를 설정. jre로는 실행 안됨
      • 예) JAVA_HOME=C:\Program Files\Java\jdk1.8.0_51
    • ANDROID_HOME 설정. SDK Path를 설정
      • 예) ANDROID_HOME=C:\Android\sdk
    • 설정법 참고

      • 시스템 속성 > 환경 변수


      • 이 경우는 PC를 껐다 켜거나, 새로운 명령 프롬프트(cmd.exe)를 켜면 적용됨

    • 또는 명령 프롬프트에서 명령어로 직접 설정

      set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_51
      set ANDROID_HOME=C:\Android\sdk
      
      • 새로운 명령 프롬프트를 실행할 때마다 reset 됨. 해당 창마다 session 단위
  6. Android virtual devices (avd) 다운로드
  7. Junit 테스트를 위해 Eclipse IDE + Maven plugin 준비

Selendroid Standalone 구동

  1. 명령 프롬프트에서 C:\selendroid 로 이동
  2. 아래 명령어 실행

    java -jar selendroid-standalone-0.17.0-with-dependencies.jar -app selendroid-test-app-0.17.0.apk

    • 아래와 같은 오류 메시지가 엄청나게 뜨는데, 무시해도 됨

      Executing shell command: C:\Android\sdk\build-tools\25.0.1\aapt.exe remove C:\Users\tod2\AppData\Local\Temp\android-driver3618093378546726334.apk META-INF/MANIFEST.MF
      Executing shell command: C:\Android\sdk\build-tools\25.0.1\aapt.exe remove C:\Users\tod2\AppData\Local\Temp\android-driver3618093378546726334.apk META-INF/ANDROIDD.RSA
      
    • https://github.com/selendroid/selendroid/issues/1029#issuecomment-175031563

  3. 아래와 같이 서버 정상 구동 확인

    12월 19, 2016 11:55:18 오전 io.selendroid.standalone.android.impl.DefaultAndroidEmulator getScreenSizeFromSkin
    경고: Failed to get dimensions for skin:
    12월 19, 2016 11:55:18 오전 io.selendroid.standalone.server.model.DeviceStore addEmulators
    정보: Adding: AndroidEmulator [screenSize=null, targetPlatform=null, serial=null, avdName=Nexus_5_API_24, model=, apiTargetType=android]
    12월 19, 2016 11:55:18 오전 io.selendroid.standalone.server.SelendroidStandaloneServer start
    정보: Selendroid standalone server has been started on port: 4444
    
  4. http://localhost:4444/wd/hub/status 에 접속하여 설정 정보 확인

    {
    "value":{
      "os":{
         "name":"Windows 7",
         "arch":"x86",
         "version":"6.1"
      },
      "build":{
         "browserName":"selendroid",
         "version":"0.17.0"
      },
      "supportedDevices":[
    
      ],
      "supportedApps":[
         {
            "mainActivity":"io.selendroid.testapp.HomeScreenActivity",
            "appId":"io.selendroid.testapp:0.17.0",
            "basePackage":"io.selendroid.testapp"
         },
         {
            "mainActivity":"io.selendroid.androiddriver.WebViewActivity",
            "appId":"io.selendroid.androiddriver:0.17.0",
            "basePackage":"io.selendroid.androiddriver"
         }
      ]
    },
    "status":0
    }
    
    • supportedDevices는 USB로 연결된 기기가 있을 경우 노출

Junit을 이용한 실제 테스트

  1. 앞의 Selendroid Standalone 은 종료
  2. Eclipse > 신규 Maven Project 생성
  3. Maven Dependency 설정

    예)

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>selendriod</groupId>
    <artifactId>modoo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <repositories>
        <repository>
            <id>snapshot</id>
            <name>snapshot repository</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
            <layout>default</layout>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    
    <dependencies>
        <dependency>
            <groupId>io.selendroid</groupId>
            <version>0.17.0</version>
            <artifactId>selendroid-standalone</artifactId>
        </dependency>
        <dependency>
            <groupId>io.selendroid</groupId>
            <version>0.17.0</version>
            <artifactId>selendroid-client</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    </project>
    
  4. 테스트 코드 작성

    • 모바일 웹
      1. Test 파일 생성
        • src/test/java 하위에 원하는 파일명으로 생성
          • 여기서는 selendroid.MobileWebTest.java 파일을 생성
      2. 테스트 코드 작성
        • webview (브라우저)를 열어 http://m.ebay.de 에 접속 > 검색어 Nexus 5 입력 > Document.title 출력
    package selendriod;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.remote.DesiredCapabilities;
    
    import io.selendroid.client.SelendroidDriver;
    import io.selendroid.common.SelendroidCapabilities;
    import io.selendroid.standalone.SelendroidConfiguration;
    import io.selendroid.standalone.SelendroidLauncher;
    
    /**
    * @author tod2
    */
    public class MobileWebTest {
    private SelendroidLauncher selendroidServer = null;
    private WebDriver driver = null;
    
    @Test
    public void shouldSearchWithEbay() {
        // And now use this to visit ebay
        driver.get("http://m.ebay.de");
    
        // Find the text input element by its id
        WebElement element = driver.findElement(By.id("kw"));
    
        // Enter something to search for
        element.sendKeys("Nexus 5");
    
        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();
    
        // Check the title of the page
        System.out.println("Page title is: " + driver.getTitle());
        driver.quit();
    }
    
    @Before
    public void startSelendroidServer() throws Exception {
        if (selendroidServer != null) {
            selendroidServer.stopSelendroid();
        }
    
        SelendroidConfiguration config = new SelendroidConfiguration();
    
        selendroidServer = new SelendroidLauncher(config);
        selendroidServer.launchSelendroid();
    
        DesiredCapabilities caps = SelendroidCapabilities.android();
    
        driver = new SelendroidDriver(caps);
    }
    
    @After
    public void stopSelendroidServer() {
        if (driver != null) {
            driver.quit();
        }
        if (selendroidServer != null) {
            selendroidServer.stopSelendroid();
        }
    }
    }
    
    1. Junit 실행
      • Jre 설정으로 인해 테스트 실행 실패할 경우, Run Configurations > Environment 내 JAVA_HOME으로 JDK 경로를 추가 

    2. 결과


    • 모바일 앱 (Native)
      1. apk 파일 복사
        • selendroid-test-app-0.17.0.apk 파일을 src/test/resources 하위에 복사
      2. Test 파일 생성
        • src/test/java 하위에 원하는 파일명으로 생성
          • 여기서는 UserRegistrationTest.java 파일을 생성
          • 테스트를 위해 UserDO.java 파일도 생성
      3. 테스트 코드 작성
        • webview (브라우저)를 열어 앱 구동 > 값 입력 확인
    // UserDO.java
    
    package selendriod;
    
    /**
    * @author tod2
    */
    public class UserDO {
    public String username;
    public String email;
    public String password;
    public String name;
    public String programmingLanguage;
    
    public UserDO(String username, String email, String password, String name, String programmingLanguage) {
        super();
        this.username = username;
        this.email = email;
        this.password = password;
        this.name = name;
        this.programmingLanguage = programmingLanguage;
    }
    }
    
    // UserRegistrationTest.java
    
    package selendriod;
    
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    
    import io.selendroid.client.SelendroidDriver;
    import io.selendroid.common.SelendroidCapabilities;
    
    /**
    * @author tod2
    */
    public class UserRegistrationTest {
      private WebDriver driver = null;
    
      @Before
      public void setup() throws Exception {
        driver = new SelendroidDriver(new SelendroidCapabilities("io.selendroid.testapp:0.17.0"));
      }
    
      @Test
      public void assertUserAccountCanRegistered() throws Exception {
        // Initialize test data
        UserDO user = new UserDO("u$erNAme", "me@myserver.com", "mySecret", "John Doe", "Python");
    
        registerUser(user);
        verifyUser(user);
      }
    
      private void registerUser(UserDO user) throws Exception {
        driver.get("and-activity://io.selendroid.testapp.RegisterUserActivity");
    
        WebElement username = driver.findElement(By.id("inputUsername"));
        username.sendKeys(user.username);
    
        driver.findElement(By.name("email of the customer")).sendKeys(user.email);
        driver.findElement(By.id("inputPassword")).sendKeys(user.password);
    
        WebElement nameInput = driver.findElement(By.xpath("//EditText[@id='inputName']"));
        Assert.assertEquals(nameInput.getText(), "Mr. Burns");
        nameInput.clear();
        nameInput.sendKeys(user.name);
    
        driver.findElement(By.tagName("Spinner")).click();
        driver.findElement(By.linkText(user.programmingLanguage)).click();
    
        driver.findElement(By.className("android.widget.CheckBox")).click();
    
        driver.findElement(By.linkText("Register User (verify)")).click();
        Assert.assertEquals(driver.getCurrentUrl(), "and-activity://VerifyUserActivity");
      }
    
      private void verifyUser(UserDO user) throws Exception {
        Assert.assertEquals(driver.findElement(By.id("label_username_data")).getText(), user.username);
        Assert.assertEquals(driver.findElement(By.id("label_email_data")).getText(), user.email);
        Assert.assertEquals(driver.findElement(By.id("label_password_data")).getText(), user.password);
        Assert.assertEquals(driver.findElement(By.id("label_name_data")).getText(), user.name);
        Assert.assertEquals(driver.findElement(By.id("label_preferedProgrammingLanguage_data"))
            .getText(), user.programmingLanguage);
        Assert.assertEquals(driver.findElement(By.id("label_acceptAdds_data")).getText(), "true");
      }
    
      @After
      public void teardown() {
        driver.quit();
      }
    }
    
    1. 상단의 Selendroid Standalone 구동
    2. Junit 실행
    3. 결과