40
s66 테테테 테테 테테테 테테테 테테 테테 테테테 테테 s66 GOOS 23, 24, 25

S66 goos-w7

  • Upload
    -

  • View
    36

  • Download
    0

Embed Size (px)

Citation preview

Page 1: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

s66 GOOS23, 24, 25

Page 2: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

지난주 복습

Page 3: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

20 장에서 다룰 내용

‘ 왜’ 테스트 하기 어려운가 ?

• 테스트를 작성하기 어려운 경우• ‘ 테스트 악취’1. 불분명 , 불안정한 테스트2. 테스트하기 어려운 코드

Page 4: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

21 장에서 다룰 내용

읽기 쉬운

테스트 작성 가이드

Page 5: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

22 장에서 다룰 내용테스트를 위해 필요한 객체를 생성하고 싶을때마다 우리는 생성자 인자를 모두 직접 작성해야 한다 .

- 또 이 객체를 생성하는 코드가 많아지면 테스트를 읽기 매우 어려워진다 .

- 생성자 인자나 구조를 변경하는 순간 여러 테스트가 깨지게 된다 .

이 문제를 해결해서 복잡한 내용을 담은 테스트 코드를 읽기 쉽게 만들어야 한다 .

Page 6: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

23 장에서 다룰 내용• 테스트가 실패하면 어디서 왜 테스트가 실패했는지 알 수 있게 쓰자 .

Page 7: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 실패 ! 제품 정상 동작 실패테스트 성공 ! 제품 정상 동작테스트 결과만 보고도 제품 동작이 보였으면

테스트에 기대하는 것 1

Page 8: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트에 기대하는 것 2테스트만 보고도 제품의 문제점이 도출 되어야 함 실패 메시지가 매우 구체적이고 읽기 편해야 함 .

If, 테스트 실패에도 어디가 문제인지 찾을 수 없다면높은 가능성으로 , 테스트를 지울 것이다 .

Page 9: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 1• 이름 잘 짓기

Page 10: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 2단정에 이름 부여하기assertEquals(16301, customer.getBalance());

assertEquals(“user balance”, 16301, customer.getBalance());

Page 11: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 3Matcher 를 사용하기매쳐의 장점1. 코드가 의도를 표현한다2. 실패시 좋은 메시지를 보여준다

Page 12: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 4

Date namedDate(long timeValue, final String name){ return new Date(timeValue) { public String toString() { return name; } }}

객체에 자가 서술 추가하기 => 실패 메시지에 이름 출력

Page 13: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 5한 눈에 알아볼 수 있는 값으로 비교하기Integer.MAX_VALUE, -1 …

Page 14: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 잘 작성하기 6jMock 객체에 이름 부여하기final LineItem item1 = context.mock(LineItem.class,”item1”);

Page 15: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

테스트 실패 ! 제품 정상 동작 실패테스트 성공 ! 제품 정상 동작테스트 결과만 보고도 제품 동작이 보였으면

테스트에 기대하는 것

Page 16: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

23 장If, 테스트가 실패하면어디가 / 어떻게 / 얼만큼 왜 틀렸는지 자세하게 표현해야 한다 .자세하게 표현하는 방법을 몇 가지를 안내함 .

테스트만 보고도 제품의 문제점이 도출 되어야 함

Page 17: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

24 장에서 다룰 내용목표 : 회복력 있는 테스트 작성하기- jUnit, Hamcrest, jMock 으로 검사문을 잘 작성하자- 재사용성이 뛰어나게 작성하기- 예상문으로 검사하는 법 (jMock 사용법 )

Page 18: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

1. Null 을 전달하지 않는다 .

public static final Customer NO_CUSTOMER_FOUND = null;

Maybe<Customer> NO_CUSTOMER_FOUND = Maybe.nothing()

Maybe 인터페이스 요구사항1. 해당 객체를 하나를 넣고 받을 수 있어야 한다 .2. 객체가 비어있는 상태를 null 말고 표현해야 한다 .

Page 19: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

2. 단정문 활용하기assertEquals(“price”, 92, instrument.getStrikePrice());

- 입력값이 바뀌면 ? 값을 계산하는 이율이 바뀌면 ?

assertThat(instrument.getTransactionId(),largerThan(PREVIOUS_TRANSACTION_ID)

- 트랜잭션 ID 가 늘어나더라도 테스트 실패하지 않음 .- 실패시 메시지를 훨씬 더 잘 표현함 .

Page 20: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

2-1. 문자열 단정하기assertEquals(“err msg”, “price=92, id=FGD.430 request item is expired”, failureMessage);

- 출력 형식에 유연하지 않은 테스트assertThat(failureMessage,

allOf(containsString(“strikePrice=92”),containsString(“id=FGD.430”),containsString(“is expired”));

- 다른 메시지가 추가될 수 있음 .- 출력 순서에 유연한 단정문

Page 21: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

3. 예상문 작성하기assertThat(failureMessage,

allOf(containsString(“strikePrice=92”),containsString(“id=FGD.430”),containsString(“is expired”));

oneOf(auditTrail).recordFailure(with(allOf(containsString(“strikePrice=92”),

containsString(“id=FGD.430”),containsString(“is expired”));

- 단정문은 예상문으로 확장할 수 있음

Page 22: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

jMock 호출 순서 조절하기oneOf(searchListener).searchMatched(ACTION1);

oneOf(searchListener).searchFinished();

만약 , searchFinished 가 먼저 호출 되고 searchMatched 가 호출되면 ? - 테스트 실패 했으면 좋겠다 .

호출 순서가 바뀌어도테스트가 성공한다 !

Page 23: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

jMock 호출 순서 조절하기 - SequenceSequence events = context.sequence(“events”);oneOf(searchListener).searchMatched(ACTION1); inSequence(events);oneOf(searchListener).searchMatched(ACTION2); inSequence(events);

oneOf(searchListener).searchFinished(); inSequence(events);

테스트 - searchFinished 는 match 함수 이후에 호출 되어야 한다 . ( 단 , action1 과 action2 는 순서가 보존되어야 한다 .)

Page 24: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

jMock 호출 순서 조절하기 - StatesStates searching = context.states(“searching”);oneOf(searchListener).searchMatched(ACTION1); oneOf(searchListener).searchMatched(ACTION2);

oneOf(searchListener).searchFinished();

테스트 – 두 함수 호출 상태를 관리한다 .

when(searching.isNot(“finished”);when(searching.isNot(“finished”);

then(searching.is(“finished”));

Page 25: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

jMock 호출 순서 조절로 테스트 구성하기allowing(searchListener).isReady(); will(returnValue(true));

then(listenerState.is(“ready”);oneOf(searchListener).searchMatched(ACTION1));

when(listenerState.is(“ready”);

searchListener.isReady() 함수가 호출되어 (allowing) true 를 반환하면 ,searchListener.searchMatched(ACTION) 이 호출되어야 한다 .

Page 26: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

24 장• jMock 사용법• http://www.jmock.org/getting-started.html

• jMock vs EasyMock• http://jeantessier.com/SoftwareEngineering/Mocking.html#jMock

Page 27: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

25 장에서 다룰 내용목표 : 데이터베이스 테스트하기- ORM 테스트 하기- 데이터베이트 테스트에 주의해야할 점

Page 28: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

예제 요구사항

Page 29: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

데이터베이스 테스트를 하기 전에…테스트 준비 / 정리 과정 중 데이터베이스 내용을 지우는 것은 언제 ?• 기존 테스트

프로세스 메모리에만 영향새로 실행할 때마다 항상 초기화 됨

• DB 테스트테스트 실행 후 기억 장치에 영향을 줌다음 실행할 때 기억 장치에 영향 받음

Page 30: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

정답 - 데이터베이스 테스트 전• 준비 과정에서 데이터베이스를 지우자1. 필요한 초기화를 테스트에 나타낼 수 있다 .이 테스트에 필요한 데이터베이스가 가시적으로 보인다2. 테스트가 끝나고 결과를 열어볼 수 있다 .테스트 후에 결과를 열어볼 수 있다 .

테스트 간에 영향을 주는 것들을 격리할 필요가 있다 .

Page 31: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

트랜잭션 테스트데이터베이스에 삽입 / 조회 테스트 작성하기

Page 32: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

1. 트랜잭션 열기2. 정의한 동작 실행

3. 커밋 시도4. 트랜잭션 실패시 롤백

DB 에 추가할 동작 정의

Page 33: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

1. 데이터 list 받아옴

2. 데이터 객체를 만들어서데이터베이스에 추가함 .

3. 데이터베이스에 데이터 추가 완료

정리한 조건에 따라 데이터를얻을 수 있는지 확인한다

Page 34: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

트랜잭션 테스트1. 트랜잭션을 관리하는 객체2. DB 에 전달할 동작을 전달하는 인터페이스3. 값 객체를 생성하여 인터페이스에 동작을 정의하여 객체를 실행시킨다 .

DB 연산에 대한 테스트를 작성하는 골격

Page 35: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

ORM 왕복 테스트데이터베이스와 상호작용하는 객체는 정상적으로 동작하는가 ?

Page 36: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

ORM 왕복 테스트테스트 하고자 하는 대상 – DB 와 데이터를 주고받을 객체-테스트 의도 : 객체 프로퍼티가 DB 에 반영이 되나 ?

Page 37: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

ORM 왕복 테스트객체 DB

멤버 : Train_ID, Train_type, Max_speed

필드 Train_ID, Train_type, Max_speed

Page 38: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

ORM 왕복 테스트1. Train_ID 선택2. Train_ID 엔티티 확인3. Train_ID 가 저장 가능한지 확인

검증대상 : Train_ID

23

Page 39: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

데이터베이스를 거친 테스트는 항상 느리다 !

메모리 내부단위테스트

외부 프로세스

통합테스트외부 서비스

통합테스트

Page 40: S66 goos-w7

s66 테스트 주도 개발로 배우는 객체 지향 설계와 실천

감사합니다