왜 테스트 해야 하는가?

  • 새로운 비지니스를 준비해야 함.

    *   그런데 인력이 충분치 않음.
    
  • 그럼 어떻게 해야 할까?

    *   새로운 인력을 추가하거나 기존 인력이 하는 일을 더는 방법 밖에 없음.
    
    • 새로운 인력을 추가하는 일은 이미 채용 공고를 올려 진행 중.
  • 기존 인력이 하는 일을 어떻게 덜까?

    *   반복되는 업무는 자동화를 시켜버리자.
    
  • 반복되는 업무는 뭐가 있을까?

    *   고객사 납품 직전에 제품을 테스트 하는 일 (이밖에도 많겠지만)
    
    • 그래! 제품 테스트를 자동화 해보자
  • 제품 테스트는 어떻게 했었나?

    *   제품 테스트는 고객 요구사항이나 새로운 기능 위주로 테스트.
    
  • 여기서 문제점은 무엇인가?

    *   기존에 되던 기능들이 안되면 정말 난감.
    
    • 만약 안 될 경우 기능 고치고 테스트하고 납품하는 일을 다시 한 번 해야함.
    • 그렇다고 기존 기능까지 매번 반복해서 테스트 하는 것은 괴로운 일.
  • 올~ 제품 테스트 자동화 의미가 있는 것 같음. 한 번 해보자.

어떤 것을 테스트 할 것인가?

  • ‘최소한 이것은 테스트해야 된다’ 정도로 중요한 기능(주관적인 것이라…)을 테스트 하자.

    *   논의를 거쳐서 테스트할 기능을 쭉 리스팅했다.
    
    • 그리고 기능을 토대로 테스트 시나리오 작성.

어떻게 구현할 것인가?

  • 이미 우리는 Nightwatch를 이용하여 간단한 시나리오를 작성하고 E2E 테스트를 돌리고 있는 상태.
  • 여기에 시나리오를 추가해서 앞서 리스팅한 내용을 모두 테스트할 수 있게 만들자.
  • E2E 테스트 코드를 작성할 때에는 아래를 항상 생각해보자.

    *   E2E 테스트의 기본을 지킨다.
    
            *   E2E 테스트는 내부 구현을 고려하지 않고 오로지 기능을 테스트 하는 것이다.
    *   E2E 테스트는 UAT(user-acceptence-testing)이다.
    
                    *   UAT는 유저가 제품을 사용하는데 문제가 없는지를 테스트 하는 것이다.
        *   예를 들어, 오탈자나 세세한 오작동은 신경쓰지 않고, 시스템이 깨지거나, 에러가 나서 더이상 진행을 할 수 없는 지를 테스트 한다.
    
                            *   참고: [end-to-end-testing-with-nightwatch-js-node-js-at-scale](https://blog.risingstack.com/end-to-end-testing-with-nightwatch-js-node-js-at-scale)
    
    • 코드는 읽기 쉬워야 한다.
    • 모든 시나리오는 독립적으로 실행될 수 있다.

      *   시나리오가 다른 시나리오에 종속되면, 테스트 해보고 싶은 시나리오 하나 돌리는 것이 귀찮은 일이 된다.
      
      • 그런데 막상 해보니 테스트 하고자 하는 기능에 선행되어야 하는 조건이 많은 경우가 있었다.

        *   스텝7을 테스트 하기 위해선 스텝1 ~ 6이 먼저 선행되는 것처럼…
        
      • 결국은 테스트 시나리오를 실행하기 전에, 테스트할 기능이 필요한 내용들을 미리 다 만들어 두는 시나리오를 따로 작성했다.
    • 하나의 시나리오는 하나의 목적만 갖는다 => 복잡하게 만들지 않는다.

      *   중간에 다른 길로 세지 않으려고…
      
    • 시나리오에서 만들어진 데이터는 제거한다.

      *   필요 없으니까!
      
    • 테스트를 위해 로직을 바꾸진 않는다.

      *   코드 자체를 바꾸고 싶진 않았지만, selector를 편하게 가져가기 위해 id를 꽤많이 추가했다.
      

구현하면서 도움이 되었던 것

  • E2E 테스트 범위 설정

    *   사용자가 어플리케이션 이용 목적에 해당되는 내용만 테스트 한다.
    
    • 세세한 테스트는 유닛 테스트가 가져가야 할 문제.
    • 만약 세세한 테스트 까지 작성하려면, 테스트 돌리는 시간과 이를 작성하는 비용이 굉장히 많이 든다.

      *   유닛테스트와 결합하여 사용할 수 있긴 하다. [unit-testing](http://nightwatchjs.org/guide#unit-testing)
      
  • 페이지 오브젝트 활용

    *   페이지 별로 테스트를 구성할 수 있음.
    
    • 페이지 오브젝트에 커맨드를 정의 하면 여러 시나리오에서 가져다 사용하기 편함.
    • 시나리오를 작성할 때 사용자 중심으로 코드를 작성하는데 도움이 됨.

      *   페이지 오브젝트의 모든 커맨드 네이밍을 사용자 중심으로 함.
      
      • 그 안의 내용은 Nightwatch의 API 같은 프로그래밍 요소를 사용하여 테스트를 실행.

        *   예를 들어, `.uploadDataSource` 커맨드를 선언함.
        
        • 실제하는 일은 type이 file인 input 엘리먼트의 data 속성을 변경하는 일.
      • 이렇게 구성하면 시나리오 내용만 보고도 Nightwatch가 어떤 식으로 작동될지 예상할 수 있음.
    • 또한, 페이지 오브젝트에서 엘리먼트 또는 섹션을 제공해주는데, 복잡한 Selector를 어떠한 엘리먼트인지 정의할 수 있어서 코드 읽기가 수월해짐.

      *   실제로 `.someClass > div > span` 이런 것만 봐서는 어떤 엘리먼트인지 알기 어려움
      
      • 엘리먼트나 섹션을 이용해서 infoText: '.someClass > div > span' 같이 정의해주는 것이 훨씬 명확함.
      • 각 페이지마다 공통 되는 요소들(ProgressBar, Tab 등)은 Common 페이지를 하나 선언해서 공통적으로 사용할 수 있게 만들어 놓음.
    • 참고: page-objects
  • 스크린샷 활용

    *   프로덕트의 중요한 화면의 경우는 직접 눈으로 보고 싶음 => 눈으로 봐서 이상이 없는지도 확인하고 싶음.
    
    • 이때 스크린샷 기능을 활용하면 도움이 됨.
    • 특정 페이지로 가서 스크린샷 기능을 이용하여 원하는 이름으로 이미지 파일을 생성할 수 있음.

      *   현재 gitlab.ci E2E 파이프라인에서 E2E 테스트가 모두 끝나면, Docker를 이용하여 스크린샷들을 웹화면에서 볼 수 있게 세팅했음.
      
      • Docker image (image-gallery) 사용.
    • 참고

      *   [스크린샷](http://nightwatchjs.org/api/saveScreenshot.html)
      
  • Docker selenium에서 데이터 업로드 테스트

    *   여기서 삽질 꽤 많이 함.
    
    • Docker selenium을 이용하면 이상하게 파일 업로드가 되질 않았음.
    • 해결법은 단순했음, volume을 이용하여 파일을 공유하면 되었음.
    • 참고
  • Gitlab Scheduled Pipeline

    *   E2E 테스트 파이프라인을 만들고, 매번 M.R 후에 돌리게 하니 시간을 상당히 잡아먹음. (45분 정도.)
    
    • 이게 뭐가 문제가 되는데?

      *   (작업 성격 상) M.R이 수시로 일어남. => 수시로 E2E 테스트가 실행 => 45분 테스크가 수시로 실행
      
    • 그래서 E2E 테스트 파이프라인을 스케쥴링 해서 매일 새벽4시에 돌리게 만들어 놓음. (그냥 새벽에 돌려놓게 만듦)

      *   우리 솔루션은 수정되는 내용이 바로바로 고객사에 배포되는 것도 아님 => 버그에 민감하게 반응하지 않아도 된다(?)
      

구현하고 나서 무엇이 달라졌는가?

  • 피부로 와닿는 장점은 적어도 메인 기능을 이용하는데 어플리케이션이 깨지거나 버그가 생기는지 매일 확인할 수 있는 점.
  • 그것도 사람이 아닌 소프트웨어가 자동으로…!