• Why Test? : 우리가 개발한 것 확인 가능. 모듈들이 결합해서 동작상에 버그가 없는 것을 확인하기 위해 필요
  • 시스템 테스트 방법 3가지(Testing Pyramid)
    (1) E2E(UI) Testing (10%)
    (2) Integrating Testing (20%)
    (3) Unit Testing (70%)

1. Test가 왜 필요한가?

  • 테스트는 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수는 없다. (by 에츠허르 비버 데이크스트라)

=> 모든 테스트가 모든 버그를 잡을 순 없지만, 테스트를 통해 최소한의 버그를 잡을 순 있다.


2. Test 자동화의 중요성

< Manual Test >

  • End-to-End test 또는 UI Test 라고 함

  • 장점

    • 사용자 입장에서 사용자가 사용하는 것처럼 테스트
    • 따라서 코드 상에서 발생할 수 있는 버그 보다는 사용자 입장에서 나타날 수 있는 버그를 알 수 있음
    • 눈에 바로 보이므로, 어떤 버그가 발생하는지 명확히 알 수 있음
  • 단점

    • (1) 테스트 실행 속도 저하 : 예상하는 시나리오대로 인력이 투입되어 A부터 Z까지 모두 진행해야 함
    • (2) 인력소모 커짐 : 테스트할 기능이 많다면 한 사람으로는 부족하므로 많은 사람이 투입되어야 하고 그에 따라 인력이 소모 됨
    • (3) 테스트의 불안정성 커짐 : 테스트 자체도 사람이 하는 일이다 보니 놓칠 수 있는 부분 발생
    • (4) 비용 증가 : 속도가 느리고 그만큼 시간 투자 및 인력투자가 필요

3. 시스템 테스트 방법 3가지 (Testing Pyramid)

  • Google Test Automation Conference 에서 제안된 테스트 피라미드
  • 전체 테스트 비중을 아래와 같은 수치로 구현하는 것이 권장됨

    (1) End-To-End Testing (UI Testing) - 10%
    (2) Integrating Testing - 20%
    (3) Unit Testing - 70%
  • 위 3가지 테스트 모두 사람이 직접 눌러서 테스트 하는 것이 아닌, 코드로 코드를 테스트 하는 것임

  • 테스트 단위가 좀 더 쪼개질수록 어느 부분에서 에러가 발행했는지 좀 더 찾기가 쉬워짐

    • 즉, End-To-End Testing 보다는 Integrating Testing 에 테스트 비중을 좀 더 많이 가져가야 하고
    • Integrating Testing 보다 더 쪼개진 단위인 Unit Testing 에 테스트 비중을 좀 더 많이 가져가야 함

3-1. End-To-End test

  • 크롬 브라우저를 띄운 다음, 내가 만든 검색페이지로 들어가서 검색을 해보고 검색한 내용이 제대로 나오는지 화면상에서 확인하거나 직접 회원가입을 해보고 회원가입후에 로그인 되는지 직접 브라우저 상에서 값을 입력해서 테스트 하는방법

  • UI Testing이 가장 어렵고 까다로움

  • Manual Testing은 실행하기 쉽다는 장점이 있지만 비용이 많이 들고 부정확하며 실행 시간이 오래 걸림

  • 자동화 할 수 있지만 UI Testing은 자동화 하기가 가장 까다롭고 또 실행하기도 까다로움

< UI test tools - cypress >

  • 프론트엔드와 백엔드 모두 코드가 완성된 상태에서 진행하는 test

  • 사람이 테스트할 기능들을 모두 직접 실행하는 테스트가 아닌, 그 시나리오를 코드로 짜는 것

    • 해당 코드를 실행함으로써 사람이 직접 실행하는 것보다 더 빠른 속도로 Manual Test 같은 효과를 볼 수 있음
  • 이런 테스트는 주로 프론트엔드 단에서 많이 함

    • 프론트엔드는 Unit Test 보다는 UI Test를 사용할 확률이 높음

3-2. Integrating test

  • 최소 두 개 이상의 클래스 또는 서브 시스템의 결합을 테스트하는 방법
    • (ex) 장고로 서버를 띄우고 모델 클래스와 결합하여 데이터베이스 시스템과 연동한 테스트

  • Postman 또는 httpie 로 호출해서 Json response가 제대로 출력되는지 확인

  • Integration Testing이 E2E Testing 다음으로 공수가 많이 듬

< Client tools - postman, httpie >

  • 내가 client인 척(프론트엔드)하면서 백엔드 서버에 요청을 보내고, 그 요청에 대한 응답을 보낼 수 있는 테스트

  • 프론트엔드 및 백엔드 각각 분리된 서버를 통해 각각 테스트 하는 것

    • 1차 프로젝트 때 가장 많이 했던 test로, test를 위해 백엔드 서버가 다 켜져 있어야 하고, 서버가 정상적으로 동작 해야 함
  • 장점

    • 프론트엔드 및 백엔드 모두 완성된 상태가 아니어도 각각 따로 테스트할 수 있음
    • 분리되어 테스트 하므로 프론트엔드 또는 백엔드 중 어디에서 에러가 발생했는지 찾기 수월

3-3. Unit test

  • code로 code를 테스트
  • Unit Testing이 가장 쉬우며 효과가 좋음
  • 빠르고 비용이 싸므로 개발할 때 필수적으로 작성해야 함
  • What is Unit Test?

    • 테스트 할 수 있는 가장 작은 단위 를 테스트 하는 코드를 작성하여 테스트 하는 것
    • 함수 또는 메소드 를 테스트하게 됨
  • Testing 라이브러리

    • 프론트엔드 : jest(가장 많이 사용), enzyme
    • 백엔드 : pytest, unittest(장고에서 기본적으로 사용)
  • [참고] Python Unit Test 개념 및 용어

    • TestCase : 어떤 함수를 테스트 할 것인지가 있어야 함
    • Fixture : 테스트를 진행할 때는 실제 데이터를 가지고 테스트 하지 않음. 이 테스트를 진행하기 위한 데이터를 만들어 줘야 하는데 그것을 Fixture 라 함
    • assertion : Unit Test 를 실행하면서 assertion 부분에서 내가 테스트 한 것이 맞는지 여부를 판단하게 됨
  • Unit Test 는 이미 우리가 작성한 코드가 정해져 있고, input 과 output 을 미리 결정 함

    • 그래서 input 을 우리가 작성한 코드에 넣었을 때, 내가 원하는 output 이 나오는지 여부를 테스트하게 됨
    • 그것을 assertion에서 체크하게 됨
  • 보통 Unit Test 를 할 때는 3가지를 진행

    • (1) 성공해야 할 때 제대로 성공하는가(ex.우리가 원하는 결과가 나오는가) '1'[참]
    • (2) 실패해야 할 때 제대로 실패하는가(ex.로직상 들어오면 안되는 값이 들어왔을 때 잘 처리가 되는지) '-1'[거짓]
    • (3) 예외처리 제대로 되어있는가(ex. 로직과 상관없이 key 에러, json 디코더 에러 등에 대해) '0'[예외처리]

4. Unit test 구현 시 일반 원칙

  • 테스트 유닛은 각 기능의 가장 작은 단위(ex. 함수, 메소드)에 집중

    • 해당 기능이 정확히 동작하는지 증명
  • 각 테스트 유닛은 반드시 독립적이어야 함

    • 각 테스트는 혼자서도 실행 가능해야 하고, 테스트 슈트로도 실행 가능해야 함
  • 테스트가 빠르게 동작할 수 있도록 만들기 위해 노력

    • CI/CD : 배포할 때 배포하기 전에 테스트가 먼저 진행이 되고, 자동 배포 하게끔 하는 것
      • 보통 Github 이벤트로 많이 하게 됨
      • push 한 branch가 merge 되기 전에 테스트가 동작하도록 만듬
      • 테스트는 생각보다 자주 돌리게 됨

< 참고 >

  • CI는 Continuous Integration 즉, 지속적인 통합이라는 의미
  • 지속적인 통합 이란, 어플리케이션의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트 되어 공유 repository에 통합하는 것을 의미(가능하다면 하루에 여러번까지)

< 참고 >

  • CD는 Continuous Delivery 혹은 Continuous Depolyment 두 용어 모두의 축약어
  • 지속적인 서비스 제공 혹은 지속적인 배포 라는 의미
  • Continuous Delivery 는 공유 repository로 자동으로 Release 하는 것을 의미
  • Continuous Deployment 는 Production 레벨까지 자동으로 deploy 하는 것을 의미

< 참고 >

  • 즉, CI 는 새로운 소스코드의 빌드, 테스트, 병합까지를 의미
  • CD 는 개발자의 변경 사항이 repository를 넘어, 고객의 프로덕션(Production) 환경까지 Release 되는 것을 의미
  • 지금 사용하고 있는 툴에 대해 개별 테스트나 테스트 케이스를 어떻게 수행하는지 배워야 함

  • 그 날의 코딩을 시작하기 전에 항상 풀 테스트 슈트를 돌려야 함

    • 내가 작업해서 발생한 에러인지, 원래 있던 에러 상태에서 내가 작업을 한 것인지 모르게 되므로
  • 모두가 공유하는 저장소(ex. Github)에 코드를 merge 하기 전에 자동으로 모든 테스트를 수행하도록 하는 훅을 구현하는 것이 좋음

  • 코드를 디버깅할 때 가장 먼저 시작할 일은 버그를 찝어내는 새로운 테스트를 작성하는 것

  • 테스트 함수에는 길고 서술적인 이름을 사용해야 함

    • 그래야 이 테스트가 어떤 함수 또는 상황에 대해서 테스트를 하는지 다른 팀원들도 정확히 알 수 있음
  • 테스트 코드의 또다른 사용 방법은 새로운 개발자들을 위한 안내서로 쓰는 방법임

    • ex. 일종의 API 문서 같은 느낌으로 사용될 수 있음

<출처> wecode(코딩 부트캠프) 세션

0개의 댓글