테스트에 대해서..

윤예은·2022년 9월 5일
post-thumbnail

필요성

  • 개발 초기에 문제를 발견할 수 있다면?
  • 코드 리팩토링이나 라이브러리 업그레이드 했을 때 기존 기능이 올바르게 작동하는지 확인할 수 있다.
  • 기능에 대한 불확실성을 감소시킬 수 있다.
  • 시스템에 대한 문서를 제공한다.
  • 테스트 코드를 통해 동작하는 방식 및 결과 확인이 가능하다.

주의할 점

  • 테스트 코드를 신경써서 짜기

    테스트 코드를 쓰기 위한 테스트 코드 No! No!

AssertEquals(true,true)
  • 테스트 코드도 사람이 짠 것! 맹신하지 말기

    테스트를 모두 통과했으니까 이 코드는 아무런 문제가 없어! (X)

테스트 관련 용어들

Coverage

테스트 코드가 얼마나 많은 코드를 실행하였는지에 대한 수치를 나타내는 값이다. (퍼센트)

가짜 객체

Mock

동일한 기능을 하지는 않지만 대략 어떤지 알려주는 용도

  • 테스트의 출력/결과가 중요할 때

     class OrderInteractionTester...
    
     public void testOrderSendsMailIfUnfilled() {
       Order order = new Order(TALISKER, 51);
       Mock warehouse = mock(Warehouse.class);
       Mock mailer = mock(MailService.class);
       order.setMailer((MailService) mailer.proxy());
    
       mailer.expects(once()).method("send");
       warehouse.expects(once()).method("hasInventory")
         .withAnyArguments()
         .will(returnValue(false));
    
       order.fill((Warehouse) warehouse.proxy());
     }
    }

Stub

호출 되면 준비된 답변으로 응답하는 가짜 객체 (일부)

  • 테스트의 입력과 그 값에 따라 리턴하는 결과값이 중요할 때
class OrderStateTester...

  public void testOrderSendsMailIfUnfilled() {
    Order order = new Order(TALISKER, 51);
    MailServiceStub mailer = new MailServiceStub();
    order.setMailer(mailer);
    order.fill(warehouse);
    assertEquals(1, mailer.numberSent());
  }

테스트의 종류

단위 테스트

  • 소형 테스트
  • 클래그의 작은 함수의 기능에 대한 유효성
  • 빠른 실행. 각각의 조건에 대한 유효성 검증

통합 테스트

  • 중형 테스트
  • 클래스 간 상호작용의 유효성 검사
  • 모듈 간의 데이터 흐름을 검사.
  • 테스트 코드를 작성하기가 복잡함
  • 더 넓은 범위의 종속성을 테스트하면서 더 유의미한 검사.

UI 테스트

  • 대형 테스트
  • 실 사용자들에게 보여지는 화면에 대한 테스트로 서비스의 기능이 정상적인지 검증
  • 사용자 흐름에 대해 테스트, 사전에 UI 변경사항으로 발생할 수 있는 문제를 차단.
  • 실행 시간이 오래 걸리고 디자인이 변하면 대형공사가 필요.
  • 유지보수 비용이 크다.

테스트 코드 팁

가독성 높이기 (중요)

어떤 값으로 무엇을 했을 때 어떤 결과를 원하는지를 직관적으로 알 수 있게 작성하는 것을 추천한다.

테스트 코드를 보고 아! 맞다 이런 것도 만들었었지! 하고 알 수 있는 경우도 많다.

바로바로 반영/업데이트

api 수정 등 변동사항이 있을 때에는 꼭 테스트코드도 변경하고 테스트를 진행하여야 한다.

TDD란?

개발 전에 테스트 코드를 먼저 작성하는 것.

개발 방법론. 테스트를 먼저 짜고, 그에 대한 코드를 짜서 테스트 진행.
실패하는 테스트를 먼저 작성하고 그에 해당하는 기능 만들기.

특징

예외 케이스를 미리 모두 생각하기
행위의 결과를 확인하기
케이스가 자동화

장점

설계자의 관점에서 개발할 수 있다.
요구사항과 목표를 점검하며 개발
테스트 통과율이 높아진다.
설계에 대한 피드백이 빠르다.

DI

의존성 주입이란?

햄버거에 고기패티 대신 새우패티를 넣으면 새우버거
==> 햄버거는 패티를 의존한다.!

햄버거가 내부에서 불고기를 생성해서(setter 함수 없이) 쓰고 있었다면 밖에서 건들 수 없다. 그러나 불고기를 외부에서 주입받게 된다면 어떨까?? (생성자를 통해서든, setter 함수를 통해서든..)
외부에서 이것이 불고기 버거가 될 지 새우 버거가 될 지 결정할 수 있다는 것!

의존성 주입의 유용함..

class A{
	B b = new B();
}

테스트를 위해 진짜 B가 아닌 모의 객체 B'를 넣고 싶다면??

Class A{
	B b;
  public A(B b){
  	this.b = b;
  }
}

그러면 A를 사용하던 모든 곳으로 가서 고치라고?? A를 100곳에서 사용한다면?? 1000곳에서 사용한다면??
-> 프로그래머가 환장하는 보일러 플레이트 코드

DI를 사용하여 자동으로 A에게 B를 주입하여 사용할 수 있다.

참고

https://velog.io/@pih6585/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0
https://galid1.tistory.com/783
https://hanamon.kr/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1/
https://www.crocus.co.kr/1555
https://luran.me/343
https://black-jin0427.tistory.com/104

profile
안녕하세요!!

0개의 댓글