테스트자동화를 버리고 자동테스트를 만들어라

Dahun Yoo·2021년 5월 26일
2

QA or Test

목록 보기
16/38
post-thumbnail

아래의 발표자료를 저 개인의 이해를 담아 번역해보았습니다.
https://speakerdeck.com/tsuemura/tesutowozi-dong-hua-surufalsewoyame-zi-dong-tesutowozuo-rou


테스트 자동화를 버리고 자동 테스트를 만들어라

  • 테스트 자동화 != 자동 테스트
  • 테스트 자동화의 성과물 != 자동 테스트

수동 테스트를 소박하게 자동화한다 하여도, 자동 테스트가 되진 않는다.

얘기할 내용들

  • 어째서 테스트 자동화는 실패하기 쉬운가.
  • 수동 테스트와 그것의 자동화, 그리고 자동 테스트는 어떻게 다른가?
  • 자동 테스트란 어떠한 형태여야하는가?
  • 수동 테스트의 자동화에는 가치가 없는 것인가?

이번에 주로 얘기하는 테스트는, E2E Test에 대해 서술한다.

어째서 테스트 자동화는 실패하기 쉬운가.

E2E 테스트란?

  • 빌드가 끝난 Application에 대해 Web이나 Mobile 기계에서 주로 GUI를 통하여 테스트를 실시하는 것.
  • 시스템 테스트라고도 하기도 한다.
  • QA (품질보증) 이나 테스터가 수동으로 진행하는 경우가 많음.

테스트 자동화란?

  • 주로 수동으로 진행하던 E2E테스트를 자동화 하는 것.
    - Selenium, Puppeteer, Cypress, Appium 등
  • 주로 실행Cost를 아끼거나 자주 실행하기 위함.
    - 부차적으로 테스트 실시자에 의한 판단 미스등을 감소시키기 위함이기도 함.
  • 테스트 순서는 수동 테스트의 순서를 재활용한다.
  • 개발 플로우 그 자체는 변화지 않는다.

테스트 자동화가 실패하는 자주 있는 패턴

수동으로 열심히 하던 테스트를 자동화하는 것은 좋지만....

  • 갑자기 동작하지 않는 경우가 있다. (유지보수 코스트가 높기도 하다)
    • Application은 동작하지만 테스트가 실패한다.
    • 불안정하여 성공하거나 실패하거나 한다.
  • 생각보다 효과가 좋지 않다. (비용대비 효과가 작다)
    • 테스트하지 않는 곳에서 버그가 계속나온다.
    • 버그의 조기 발견으로는 이어지지 않는다.

수동 테스트를 자동화하는 것으로 인해, 많은 관점들을 확인할 수 없게 됩니다.
자동화된 테스트 코드는 지정된 곳만 확인하기 때문입니다. 예를 들어 로그인할 때 로그인 버튼은 존재 하긴 하지만 CSS나 레이아웃이 깨져있다면 이것은 확인할 수 없습니다.

어째서 자동화한 테스트만이 제대로 동작하지 않게 될까?

  • 사실은 Unit Test도 비슷한 일은 많이 있다.
  • 다른 것은 개발사이클.
    • Unit Test는 개발 도중 에 실시 및 수정된다.
    • 자동화 된 테스트는 개발이 다 끝난 후 실시 및 수정된다.
      • 애시당초 테스트 하던 패턴이 개발이 끝나고 테스트를 진행해왔기 때문.
  • 릴리즈 직전에 테스트가 실행안되는 것을 알게된 경우라면, 테스트하지 않고 그냥 릴리즈할 때가 있다.
    • 그 결과 테스트 코드의 유지보수는 나중으로 미루게 된다.
  • 실행빈도가 높고, 개발중에도 테스트 실행이 가능하게 된다면, 테스트는 문제없이 돌아갈 확률이 높아진다. 즉, 유지보수를 열심히 해야한다.

단순히 실행 빈도를 높이면 되는 것인가?

  • 실행 빈도를 높인다고 해도 문제가 해결되는 것은 아니다.
  • 횟수가 아니라 실행환경의 폭을 넓혀야만 한다.
    • 예를들어, 애당초 스테이징환경에서만 실행했다면 그것을 개발환경이나 CI환경에서도 실행할 수 있어야 한다.
  • 수동 테스트를 단순히 자동화하여도, 전제조건이나 사전 준비는 자동화되지 않는 경우가 많다.
    • 특정 환경에 의존한 테스트 케이스가 되어버리기 쉽다.
  • 환경이나 특정 테스트 데이터에 의존한다면 개발 사이클과 맞추어 실행하는 것은 어려워진다.
  • 의존관계를 해결하고 어느 환경에서던지 실행할 수 있는 테스트를 만들어야 한다.

테스트 자동화와 자동 테스트의 차이

자동 테스트의 일반적인 이미지

  • 코드로 작성한다.
  • xUnit이나 RSpec등의 테스트 프레임워크를 사용한다.
  • TDD나 Refactoring같은 단어를 접한다.
  • 안전한 개발을 위해 만든다는 이미지가 있다.
  • 그냥 어찌되었던간에 QA나 Tester가 실시하는 것과는 다른 스멜이 난다.

자동 테스트와 타입 검사, Linter

  • 자동 테스트 : Application이 기대한 동작을 하지 않으면 릴리즈할 수 없다.
  • 타입 검사 : 데이터 타입에 부정합이 있다면 빌드를 할 수 없다. (컴파일 / 빌드 실패)
  • Linter : 부적절한 코드작성법이라면 경고를 노출한다.

즉 각각의 테스트들은 담당 기능에서 강제성을 띈다.

Application과 자동 테스트의 관계

  • 둘 다 Product의 일부.
  • 둘 다 Specification을 구현한 것.
    • Application은 그 자체로는 큰 의미가 없고, 누군가가 사용할때야 말로 가치가 생김.
    • Application은 동작을 구현한 것.
    • 자동 테스트는 해당 Application의 사용방법을 구현한 것.
  • 자동 테스트는 Application을 속박한다.
    • Application의 특정 동작에 의존하는 것으로, 해당 동작을 속박한다. (해당 동작을 하지 않는다면 테스트 실패.)
    • 각각 코드로 작성되어져 있고, 실행가능한 형태로 기술되어져 있어 강제력을 발휘한다.

자동 테스트란 ?

  • Product의 일부이며 동시에 개발된다.
    • 개발 사이클이 한창일때 개발된다. (Test 공정에서의 자동화가 아니다.)
  • Application의 동작에 매우 밀접하게 의존한다.
  • 정적 소스코드 검사 등과 마찬가지로 빈번하게 실행되어 Specification과 맞지 않게 되는 것을 항상 방지한다.

소박한 테스트 자동화는 부분적인 변화만 가져올 뿐이다.

-수동 테스트테스트 자동화자동 테스트
개발 사이클개발과는 별개개발과는 별개개발과 동시 진행
실행 빈도적음적음많음
실행 순서애매하며 암묵적엄밀하며 구체적엄밀하며 구체적
검증 방법발견적인 경우가 많음코드의 체크포인트에 의해 보증되어있음.코드의 체크포인트에 의해 보증되어있음.

우리가 정말로 원하는 것은 무엇일까?

테스트 자동화의 동기

  • 인간이기 때문에 발생하는 문제로부터의 해방
    • 단순 작업으로부터의 해방
    • 리소스 부족의 해결
    • 이른바 속인화 라고 하는, 특정 인원에게 의존적인 상황의 해결
  • 고속화, 고 빈도화
    • Release 속도의 향상
    • 언제든지 테스트 가능
    • Refactoring

어째서 테스트 자동화로는 고속, 고빈도 실행이 실현되지 않는가?

고빈도화를 위한 시나리오 최적화

수동 테스트에 최적화된 상태.

  • 어떤 테스트로 만들어진 데이터를 다른 테스트에서 재이용하는 것.
    • 신규작성 시나리오에서 생성한 데이터를 업데이트 에서 재이용
  • 특정 환경에서만 존재하는 테스트용 데이터를 사용하는 것.

자동 테스트에 최적화시킬 것.

CI로의 실행이나 동시 실행 등을 가능하게 하기 때문.

  • 항상 새로운 데이터를 만들 것.
    • GUI가 아닌 API나 Command로 생성할 것.
  • 실행이 다른 테스트에 영향을 미치지 ㅇ낳을 것.
    • 예를 들어 테스트 데이터 생성 시의 랜덤한 문자열을 사용하는 등.
  • 환경 의존 부분을 배제할 것.
    • 환경변수를 사용할 것.

자동 테스트 스러운 테스트 자동화

  • 개발중에도 여러가지 환경에서 테스트.
  • 높은 빈도로 (commit이나 Push될 때) 실행되어 버그를 방지.
  • 안전성이 높다.
    • 다른 테스트 시나리오로부터 영향을 받지 않는다.
    • 몇번이고 동시에 실행하여도 문제없다.
    • 테스트 시나리오가 자주 유지보수된다.
    • 테스트 관점 이외의 조작은 API나 Command로 조작한다.

고빈도화는 실현되었다고 쳐도, Human-error로부터는 해방되었는가...?

자동화 코드를 작성하여도 오히려 유지보수 등을 포함한 업무가 추가되었기 때문에, 사람이 편해지진 않는다.

어느정도 두루뭉술 한 테스트도 필요하다.

자동 테스트에서는 놓치는 것들이 있다.

  • 환경 의존적인 데이터에 의존적인 것들은 찾아낼 수 없다.
    • 예) 대량의 관련 데이터를 가진 유저만 정상적으로 동작한다.
  • Assertion을 사용하지 않은 부분은, 찾아낼 수 없다.
    • 누가봐도 이상한 부분이지만, 코드에서는 검출할 수 없는 부분.
    • 특히 레이아웃 깨짐에 취약하다.

애당초 빡세게 요소요소 확인하는 것은 E2E 다운 방식이 아니다.

  • 빡빡하게 만든 테스트에서 검증할 수 있는 것은 어느정도 확실한 초점/관점으로 포인트를 맞춘 테스트
  • E2E는 애당초 여러 환경에서 있을 수 있는 리얼한 환경에서의 테스트가 목적.
  • 리얼한 환경에서 문제없는 것 처럼 동작하는 것을 확인하는 것이 바람직.

두루뭉술한 자동테스트는 실현 가능한가?

빡빡하게 체크하는 코드보다는 대충 확인하는 코드가 필요할지도.

$('#username').click()
$('[data-test=username]').click();

// 보다는 아래 코드라면, 레이아웃이 깨진다던지 내용이 표시안된다던지 하는 것을 체크할 수 있을지도.
$('유저 이름').click();

문언이나 구조에 따른 의미 있는 로케이터.
xx라는 메세지를 표시하고 있는 모달의 안에 yy라는 버튼 과 같은 구조를 지정한다면...?

AI에 의한 요소 검색 등.

여러개의 로케이터를 찾아내서 AI로 파악하는 등의 테스트.

두루뭉술한 검증

  • Assertion 지옥에서 도망쳐야한다.
    • 체크포인트를 하나하나 지정한다면 그만큼 유지보수 지옥이 된다는 것.
  • 사람이 보고 단번에 알 수 있는 레벨의 issue를 회피하는 것이 목적
    • 표시되어야하는 것이 표시되지 않는다던지
    • 레이아웃이 깨진다던지.

화면비교 (Visual-Regression)

  • 테스트 실행할 때마다 screenshot을 capture하여 비교.
  • 스타일이나 레이아웃이 깨져있진 않는지 확인.
  • 비교 대상에서 제외할 부분은 별도로 정의가 필요.
  • 좌표보정이 필요.

꼼꼼하고 빡빡하게 체크하는 것과, 두루뭉술하고 확인하는 것 중 어느쪽이 좋을까?

버그는 되도록 상위단계에서 잡아내는 것이 좋고, 그물망처럼 아랫단계에도 테스트를 한다는 개념이 좋음.

꼼꼼하고 빡빡한 테스트

  • 기능 테스트
  • 회귀 테스트

두루뭉술한 테스트

  • 호환성 (Cross-browser, multi-device) 테스트
  • use-case test
  • smoke test

결론

  • 수동 테스트를 소박하게 자동화하여도, 자동테스트가 되진 않는다.
  • 소박한 테스트 자동화는 자동화한 것 만큼의 효과도 없을 수 있다.
    • 신규 버그는 찾을 수 없고, 오히려 유지보수 코스트가 증가하게 된다.
  • 자동 테스트는, 빡빡하고 꼼꼼한 자동테스트와, 수동 테스트와 비슷하게 두루뭉술하게 하는 자동테스트가 있다.
  • 테스트 자동화를 목표로 하는 것이 아닌, Entry-point로서 자동 테스트에 입문하여 더욱 발전시켰으면 좋겠다.

ref

profile
QA Engineer

1개의 댓글

comment-user-thumbnail
2023년 10월 24일

잘 보고 갑니데이

답글 달기