Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Effective unit testing ch3. 테스트더블

1,607 views

Published on

  • D0WNL0AD FULL ▶ ▶ ▶ ▶ http://1lite.top/CM0v0 ◀ ◀ ◀ ◀
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • D0WNL0AD FULL ▶ ▶ ▶ ▶ http://1lite.top/CM0v0 ◀ ◀ ◀ ◀
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes.........ACCESS WEBSITE Over for All Ebooks ..... (Unlimited) ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THAT BOOKS/FILE INTO AVAILABLE FORMAT - (Unlimited) ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes Christian, Classics, Comics, Contemporary, Cookbooks, Art, Biography, Business, Chick Lit, Children's, Manga, Memoir, Music, Science, Science Fiction, Self Help, History, Horror, Humor And Comedy, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes.........ACCESS WEBSITE Over for All Ebooks ..... (Unlimited) ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Effective unit testing ch3. 테스트더블

  1. 1. Effective Unit Testing 테스트 더블 최용은
  2. 2. 테스트 더블 “테스트 더블”은 무엇인가? 테스트하려는 코드를 주변에서 분리하게 도와 주는 놈! 또는 테스트 작성 시 테스트 대상 코드와 상호작용하는 객체
  3. 3. 테스트 대상 코드와 협력 객체를 분리 출처 : Effective Unit Testing
  4. 4. 테스트 더블의 위력! ● 테스트 대상 코드를 격리한다. ● 테스트 속도를 개선한다. ● 예측 불가능한 실행 요소를 제거한다. ● 특수한 상황을 시뮬레이션한다. ● 감춰진 정보를 얻어낸다.
  5. 5. 예) 테스트 대상코드(Car)와 협력 객체(Engine과 Rout) public class Car { private Engine engine; public Car(Engine engine) { this.engine = engine;} public void start() { engine.start(); } public void drive(Route route) { for(Directions directions : route.directions()){ directions.follow(); } } public void stop(){ engine.stop(); } }
  6. 6. 테스트 대상 코드를 격리한다. ● Car는 Engine과 Route를 직접 사용하지만, Directions는 Route를 통해 간접적으로 만 사용 ● 즉, 협력 객체로 부터 Car를 격리하는 일은 Engine과 Route만 테스트 더블로 교체. 출처 : Effective Unit Testing 출처 : Effective Unit Testing
  7. 7. 테스트 속도를 개선한다. ● 만약 Car가 이동할 최단경로를 구할 때 Route가 가중 그래프 검색 알 고리즘을 이용한다면 ? ○ 알고리즘을 계산하느라, 속도가 느려짐 ● 테스트 더블을 이용해서 사전에 계산해둔 경로를 반환 한다면? ○ 테스트는 눈부시게 빨리짐!
  8. 8. 예측 불가능한 실행 요소를 제거한다. public class Route { private Clock clock = new Clock(); private ShortestPath algorithm = new …(); public Collection<Directions> directions() { if(clock.isRushHour()) { return algorithm.avoidBusyIntersections(); } return algorithm.calculateRouteBetween(...); } } 혼잡한 시간에는 경로 계산 결과가 달라진다! ● 비결정적인 요인을 다룰땐, 테스트 더블! ○ 항상 똑같은 시간을 알려주는 테스트 더블로 변경!
  9. 9. 특수한 상황을 시뮬레이션한다. ● Route가 Directions를 구할 때 구글 맵스를 이용한다고 가정 해보자. ○ 목적지까지 경로를 요청하는 도중 인터넷이 끊긴 경우 Route는 잘 대처하는지 어떡해 확인 할 수 있을까? 연결 요청을 처리하는 부분을 테스트 더블로 대체해서 예외 발생시키자!
  10. 10. 감춰진 정보를 얻어낸다. ● 시나리오 ○ 누군가 Car의 시동을 걸면 Car는 Engine을 가동한다. ○ 이 동작이 실제로 일어났는지 어떻게 확인 할 수 있을 까? ● 역시 테스트 더블이 해결책!
  11. 11. 감춰진 정보를 얻어낸다. public class CarTest { @Test public void engineIsStartedWhenCarStarts() { TestEngine engine = new TestEngine(); new Car(engine).start(); assertTrue(engine.isRunning()); } } public class TestEngine extends Engine { private boolean isRunning; public void start(){isRunning = true;} public boolean isRunning(){return isRunning;} }
  12. 12. 테스트 더블의 종류 테스트 더블 테스트 스텁 가짜 객체 테스트 스파이 Mock 객체
  13. 13. 테스트 스텁 - 유난히 짧다. ● 스텁의 사전적 정의 ○ 스텁 (명사) 끝이 잘렸거나 유난히 짧은 것 ● 테스트 스텁의 목적은 원래의 구현을 최대한 단순한 것으로 대체 하는 것 스텁의 전형적인 모습! ( 아.무.것.도.하.지.않.아.요 ) public class LoggerStub implements Logger { public void log(LogLevel level, String message) { } }
  14. 14. 테스트 스텁 - 유난히 짧다. public class LoggerStub implements Logger { public void log(LogLevel level, String message) { // 여전히 아무 일도 하지 않는다. } public LogLevel getLogLevel() { return LogLevel.WARN; // 하드코딩된 값을 반환한다. } } LogLevel을 반환하는 메서드 정의 스텁을 사용하는 세 가지 이유 1. 테스트는 대상 코드가 로깅하는 내용에는 전혀 관심 없다. 2. 가동 중인 로그 서버가 없으니 로깅은 어차피 실패했을 거다. 3. 테스트 스위트가 콘솔로 대량의 정보를 쏟아내는 건 바라지 않는다. (파일에 쓰는 건 별로 상관없다.)
  15. 15. 가짜 객체 - 뒤끝 없이 처리한다. ● 언제 사용? ○ 최소한의 행동을 취해주거나 입력값에 따라 다르게 행동 할때 사용! ● 왜 사용? ○ 진짜 객체를 사용할때 생기는 부수효과나 연쇄동작이 일어나지 않게 경 량화 및 최적화 한 것
  16. 16. 가짜 객체 - 뒤끝 없이 처리한다. public class FakeUserRepository implements UserRepository { private Collection<User> users = …. // 인메모리 데이터베이스 public void save(User user){ if( findById(user.getId()==null ) { users.add(user); } } public User findById(long id) { for( User user : users ) { if( user.getId() == id ) return user; } return null; } } public interface UserRepository { void save(User user); User findById(long id); }
  17. 17. 테스트 스파이 - 기밀을 훔친다. ● 언제 사용? ○ 입력 인자로 사용되는 객체가 테스트에 필요한 정보를 알려주는 API를 제 공하지 않을 때 유용 ○ 구현 어디에도 전달된 메시지가 잘 기록되었는지 알려주는 메서드가 보이 지 않을 시 주의 : 테스트 스파이를 사용해야 하는 상황이 발생하면 설계가 제대로 되었는지 한번쯤 의심을 ;ㅁ;
  18. 18. 테스트 스파이 - 기밀을 훔친다. 코드 - 테스트에 필요한 정보를 제공하지 않아 테스트 스파이가 필요한 상황 public class DLog{ private final DLogTarget[] targets; public DLog(DLogTarget… targets) { this.targets = targets; } public void write(Level level, String message) { for (DlogTarget each : targets) { each.write(level, message); } } } public interface DLogTarget { void write(Level level, String message); }
  19. 19. 테스트 스파이 - 기밀을 훔친다. public class DLogTest{ @Test public void writeEachMessage…() { SpyTarget spy = new SpyTarget(); DLog log = new DLog(spy); log.write(Level.INFO, “message”); assertTrue(spy.received(Level.INFO, “message”); } private class SpyTarget implements DLogTarget { private List<String> log = ….; public void write(Level level, String message) { log.add(concatenated(level, message)); } boolean received(Level level, String message) { return log.contains(concatenated(level, message)); } private String concatenated(Level level, String message){ return level.getName() + “: “ + message; } } } 코드 - 간단히 구현해본 테스트 스파이
  20. 20. Mock 객체 - 예기치 않은 일을 막아준다. ● 특정 조건이 발생하면 미리 약속된 행동을 취하고, 약속된 행동이 취해지지 않으면 바 로 테스트 실패가 된다. ○ 예 ■ UserRespository 으로 설명 하자면, findById()의 파라미터로 123을 주면 null, 124를 주면 가짜 user객체를 반환하는 식이다. ● 메서드를 파라미터에 따라 다르게 처리하게 한 스텁 수준 이지만, 이게 다가 아니다. ■ 하지만 123,124 외에 인자를 넘겼거나 다른 메서드를 호출하면 테스트를 실패하게 만들 수 있다. ● 이전 보다(스텁,가짜,스파이) 훨씬 정교한 테스트를 만들 수 있다. ○ 메서드가 호출되었는지? 몇번 호출되었는지 확인 할 수 있다.
  21. 21. Mock 객체 - 예기치 않은 일을 막아준다. ● Mock 객체 라이브러리 ○ Mockito ○ JMock ○ EasyMock
  22. 22. Mock 객체 - 예기치 않은 일을 막아준다. public class TestTranslator { @Test public void userInternetForTranslation() { //given final Internet internet = mock(Internet.class); given(internet.get(with(containsString(“langpair=en%7Cfi”))) .willReturn(returnValue(“{“translatedText”:”kukka”}”)); //when Translator t = new Translator(internet); String translation = t.translate(“flower”, ENGLISH, FINNISH); //then assertEquals(“kukka”, translation); } }
  23. 23. 테스트 더블 활용 지침 ● 용도에 맞는 도구를 꺼내 써라 ● 준비하고, 시작하고, 단언하라 ● 구현이 아니라 동작을 확인하라 ● 자신의 도구를 선택해라 ● 종속 객체를 주입하라
  24. 24. 용도에 맞는 더블을 선택해라. ● “가독성” - 테스트를 가장 읽기 쉽게 만들어주는 선택 ● 그 외 ○ 두 객체 간 상호작용의 결과로 특정메서드가 호출되었는지 확인하고 싶다면 Mock 객체 ○ …... ○ 이도 저도 아니라면 동전을 던져보자, 앞면 Mock, 뒷면 스텁
  25. 25. 용도에 맞는 더블을 선택해라. ● 결론 ○ 스텁은 질문하고 Mock은 행동한다.
  26. 26. 구현이 아니라 동작을 확인하라. ● 검증 목적과 관련 없는 지극히 사소한 변경마저도 테스트 실패 한다면.. ○ 못질을 너무 많이 해서 구멍이 송송 뚫린 불쌍한 목판처럼 되어 버린다. ● 테스트는 오직 한 가지만 검사해야 하고 그 의도를 명확히 전달하도록 작성되어야 한 다. ● 핵심 ○ “구현이 아니라 동작을 검증 하자!”
  27. 27. 종속 객체를 주입하라 ● 진짜 객체를 테스트 더블 객체로 교체할 수 있어야 한다. 교체할 수 없다면 단위 테스트 작성도 못한다. ○ 종속 객체를 private 필드에 저장하거나 팩토리 메서드 등을 통 해 외부로부터 얻도록 해야 함 ○ 보통 생성자 주입 방식을 많이 애용 함
  28. 28. Thank U

×