SlideShare a Scribd company logo
1 of 85
Test-Driven Development
basic
Jinwoo Park, XFT-Aries, LMR PD TC3 Team
2
1. Test-Driven Development?
2. By Example: Action speaks louder than words
3. By Demonstration: 실천궁행(實踐躬行)
4. TDD Basic Strategy
5. Testing Pattern
6. Refactoring
7. Design Patterns in Test Framework: JUnit
8. Retrospective..
9. My & Your Assignment
10.Reference
Contents
3
› Learning how to do TDD
› NO!
› Learning the philosophy
› YES!
› So, How?
› 배운것을 실천하며 체득한다! : 지행일치(知行一致)
GOAL
4
Test-driven development?
Test-driven development
› 한국어로는 테스트 주도 개발
잠시만 안녕..
› 테스트? 주도 개발? 흠..
› 단일사고적(Monological) 접근으로!
› 논제를 쪼개보자.
›테스트 / 주도 개발
5
Test-driven development?
Test
› 도와줘요! 네이버사전!
› v. Test: 수작업의 느낌
› n. Test: 자동화된 느낌
› Quiz. TDD의 Test는 명사인가? 동사인가?
6
Test-driven development?
Automated Test
› 모든 테스트 케이스를 코드 스크립트로 변환한 집합체
<MCT Test>
7
Test-driven development?
Why we need it?
› 소프트웨어의 소스는 복잡하게 연결되어 있다.
8
Test-driven development?
Why we need it?
› 여기서 작은 부분이 수정된다면??
마음이 불안해진다..
9
Test-driven development?
Why we need it?
› 모든 기능을 다시 테스트해야 한다.
10
Test-driven development?
Why we need it?
› 또한 소스코드는 시간이 지나며 녹이 슨다.
11
Test-driven development?
Why we need it?
› 끊임없는 리펙토링이 필요.
12
Test-driven development?
Why we need it?
› 하지만 리펙토링이 녹록치 않다.
“We are waiting for you!”
13
Test-driven development?
Why we need it?
› 이 경우도 모든 기능을 다시 테스트 해야 한다.
14
Test-driven development?
No automated test?
› 버그 검출 능력 저하
› 소스 코드 품질 저하
› 자체 테스트 비용의 증가
15
Test-driven development?
So, Test automation == TDD ??
› 그렇다면 테스트 자동화가 곧 TDD일까?
Test -Driven Development
이제 헤어지지 말자..
› 생각을 확장할 때가 되었다.
16
Test-driven development?
Architecture-driven development
› 남녀노소 익숙한 개발 주기
설계
코딩
테스트
Next Cycle
› 자동화된 테스트코드의 작성이 불가능할까?
17
Test-driven development?
However..
› 누구나 겪어봤을 고통..
1. 설계: 불행하게도 초반에 완벽한 설계를 하기는 힘들다.
2. 코딩: 설계가 완벽하지 않기에 코딩이 산으로 간다.
3. 테스트: 설계<->코딩 주기를 반복하며, 요구사항이 어느
정도 구현되고 나서야 작성되기 시작한다.
4. 요구사항변경 or 설계미스발견: 테스트 코드작성은
아직 미완상태. 이제 모든것이 꼬이기 시작한다..
5. 리펙토링: 포기.
18
Test-driven development?
Again.. Again.. And again..
› 이런 상황이 계속되어 버리면..
스트레스
테스트
외부변수
악영향
악영향
<Influence Diagram>
19
Test-driven development?
It makes uncertainty
› 불확실성은 두려움을 만든다. 두려움은 우리를..
1. 망설이게 만든다.
2. 커뮤니케이션을 덜 하게 한다.
3. 피드백 받는 것을 피하도록 한다.
20
Test-driven development?
So we need courage!
› 용기를 얻기 위해선 어떻게 해야할까.
1. 불확실한 상태로 있는 대신, 가능하면 재빨리 구체적인 학습을 시작
한다.
2. 침묵을 지키는 대신 좀 더 분명하게 커뮤니케이션을 한다.
3. 피드백을 회피하지 말고 도움이 되는 구체적인 피드백을 찾는다.
21
Test-driven development?
For what?
› “Clean Code that works” – Ron Jeffries
› 궁극적 목표는 바로 “작동하는 깔끔한 코드”를 작성하는
것!
22
Test-driven development?
So.. How?
› 발상의 전환!
테스트우선
스트레스
외부변수
긍정적효과
긍정적효과
<Influence Diagram>
23
Test-driven development?
Test drives development
› 즉, 개발 주기에서 테스트 작성을 우선시한다!
TestCoding
“난 더이상 네 개가 아냐.”
24
Test-driven development?
This is Test-driven development!
테스트
실패를 확인
테스트를
통과시킨다
테스트
성공을 확인
작은 크기의
테스트작성
리펙토링
Next Cycle
25
Test-driven development?
What is the advantage?
› 아는 것을 행할시간.
› 실천을 통해 체감해본다.
26
By Example
Scenario
› 회사가 판매하는 채권 포트폴리오 관리 시스템의 새로운 고
객이 문득 이런 요구사항을 던진다.
"시스템이 제공하는 기능들에 굉장히 감탄했습니다. 헌데, 미
합중국 달러로 명명된 채권만 다루고 있더군요.
저는 새로운 채권 펀드를 시작하려고 하는데 제 전략상 다른
화폐로 채권을 다룰 필요가 있습니다.“
27
By Example
System implementation
› 시스템이 기존에 제공했던 기능은 다음과 같을 것이다.
종목 주 가격 합계
IBM 1000 25 25000
GE 400 100 40000
합계 65000
28
By Example
System implementation
› To-Do List를 작성해본다.
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
29
By Example
System implementation
› 테스트 코드를 작성해본다.
› 컴파일 실패!
1. 아직 Dollar 클래스가 존재하지 않는다.
2. Dollar 내부엔 int를 입력받는 생성자가 필요할 것이다.
3. Dollar 내부엔 times(int) 라는 함수가 필요할 것이다.
30
By Example
System implementation
› 재빠르고 비열하게 코드를 작성한다.
› 컴파일 성공!
31
By Example
System implementation
› 테스트를 실행해본다.
› 테스트 실패!
32
By Example
System implementation
› 비열하게 테스트를 통과시켜보자.
› 컴파일 성공!
33
By Example
System implementation
› 비열하게 테스트를 통과시켜보자.
› 테스트 성공!
34
By Example
System implementation
› 마지막 단계! 리펙토링.
› 상수로 선언된 부분을 추상화한다.
35
By Example
System implementation
› 코드를 변경하였으니 테스트를 통과시켜보자.
› 테스트 성공!
36
By Example
System implementation
› To-Do List를 갱신한다.
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
37
By Example
System implementation
› 시스템이 앞으로 제공해야 할 기능은 다음과 같을 것이다.
종목 주 가격 합계
IBM 1000 25USD 25000USD
Novartis 400 150CHF 60000CHF
합계 65000USD
※ 환율 : 1.5CHF = 1USD
38
By Example
System implementation
› To-Do List를 갱신한다.
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
- USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
39
By Example
System implementation
› 테스트 코드를 작성해본다.
› 컴파일 실패!
1. 아직 Franc 클래스가 존재하지 않는다.
2. Franc 내부엔 int를 입력받는 생성자가 필요할 것이다.
3. Franc 내부엔 times(int) 라는 함수가 필요할 것이다.
40
By Example
System implementation
› Dollar Class를 이용하여 Franc 클래스를 만든다.
› 물론, 테스트는 성공한다.
41
By Example
System implementation
› 리펙토링 단계
› Dollar클래스와 Franc 클래스 사이의 중복들이 거슬린다.
› 둘을 묶을 수 있는 상위 클래스가 있다면 어떨까?
› To-Do List는 항상 열려있다.
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
- USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
- Dollar와 Franc 클래스의 상위 클래스인 Money 클래스
42
By Example
System implementation
› Money 클래스 작성.
43
By Example
System implementation
› Dollar 클래스 변경.
44
By Example
System implementation
› Franc 클래스 변경.
45
By Example
System implementation
› 테스트 성공
› 이번 사이클에서는 Dollar와 Franc에 대폭 변화가 있었다.
› 기존 테스트들이 Dollar와 Franc의 기능을 검증해준다!
›코드 변경에 용기가 샘솟는다!
46
By Example
System implementation
› 리펙토링.
› 중복을 제거하자
1. 생성자 중복
2. 멤버변수 중복
3. times(int) 중복
47
By Example
System implementation
› Money: 변경이 없다.
48
By Example
System implementation
› Dollar, Franc: 부모클래스가 제공하는 Method를 이용한다.
› 테스트 통과 확인!
49
By Example
System implementation
› To-Do List 갱신
› Dollar와 Franc의 amount가 같더라도 둘의 가치는 다르다.
› Dollar와 Franc 클래스를 비교하는 기능이 필요하다.
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
- USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
- Dollar와 Franc 클래스의 상위 클래스인 Money 클래스
- Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
50
By Example
System implementation
› 테스트 코드 작성
› 컴파일 에러
› equal(Money*)함수가 존재하지 않는다.
51
By Example
System implementation
› Money: equal(Money*)함수 구현
52
By Example
System implementation
› 테스트 실패
› 환율에 대한 고려가 전혀 없다.
53
By Example
System implementation
› 테스트를 통과하려면? (전략수립)
1. Dollar와 Franc에서 각각의 통화가 무엇인지 기억한다.
2. 객체간 비교시, 각 개체의 통화정보를 기준으로 USD로 변
경한 후 비교를 수행한다.
3. 환율정보를 갖고 있는 ‘무언가’가 필요하다.
4. ‘무언가’의 이름으로는 Bank가 적절할 것 같다.
54
By Example
System implementation
› 다시 테스트 코드 작성
› 컴파일 에러
› Bank 클래스가 존재하지 않는다
› equal(Bank, Money*)함수의 입력형태가 이전과 다르다
55
By Example
System implementation
› Bank Class 작성1
› 각 화폐는 addRate시, 자신이 갖고있는 currency 식별자를
입력할 것이다.
56
By Example
System implementation
› Bank Class 작성2
57
By Example
System implementation
› Money Class: 화폐 식별자 currency 추가
58
By Example
System implementation
› Money Class: equal(Bank, Money*) 변경
› Bank에서 얻은 환율정보로 모든 화폐를 USD로 변경한다.
59
By Example
System implementation
› Dollar Class, Franc Class 작성
› 각 화폐 생성시 자신의 식별자가 setting된다.
60
By Example
System implementation
› 또 다시 테스트 실패
› 테스트 케이스에서 환율에 대한 정보를 입력하지 않았다.
› bank.addRate(“USD”, 1.0); //추가
› bank.addRate(“CHF”, 1.0); //추가
61
By Example
System implementation
› 테스트가 통과하는 것을 확인
62
By Example
System implementation
› To-Do List 갱신
› 드디어 서로 다른 통화간의 합이 남았다
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
- USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
- Dollar와 Franc 클래스의 상위 클래스인 Money 클래스
- Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
63
By Example
System implementation
› 테스트 코드 작성
› 컴파일에러!
› Money에 add(Bank, Money*, string)가 추가되어야 한다.
64
By Example
System implementation
› Money Class: add 함수 작성
› Money에 통화단위를 입력받는 생성자가 필요하다.
65
By Example
System implementation
› Money Class: 생성자 작성
› 이로써 모든 테스트가 통과했다.
› 예외처리, 리펙토링 등은 분량상 생략.
66
By Example
System implementation
› To-Do List 갱신
To-Do List
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
- USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD
- 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
- Dollar와 Franc 클래스의 상위 클래스인 Money 클래스
- Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
67
By Example
Does it make a sense?
› 머리가 복잡하시죠?
68
By Example
Does it make a sense?
› 방금 본 것은 잠시 잊으셔도 좋습니다.
›더 쉬운 예제로!
›눈 앞에서 직접!
69
By Demonstration
Fibonacci series
70
TDD basic strategy
Independent test
› 각 테스트는 독립성이 보장되어야 한다.
› 테스트는 충분히 빨라야한다.
Q. 테스트의 독립성을 위해 Test마다 시스템을 재가동 한다면
?
Q. 재빠른 테스트를 위해 한 가지 Test 내에서 두 가지 이상의
기능을 검증한다면?
› 잘만 지키면, 설계 응집도는 상승하고 결합도는 낮아진다.
71
TDD basic strategy
To-do list
› 적는 습관을 들인다!
› TO-DO LIST는 카테고리 별로 잘 정리한다!
-> 규모, 우선순위 등등
› 머릿속에만 의지하게 되면..
1. 경험이 축적될수록 TO-DO LIST가 많아진다.
2. LIST가 많을 수록 집중도가 떨어진다.
3. 집중도가 떨어지면 실수가 발생한다.
72
TDD basic strategy
Bottom-Up? Top-down?
› 간단한 한가지 사례를 나타내는 테스트에서 시작했다면?
-> Top-Down 식 구현.
› 전체의 작은 한 조각에 해당하는 테스트에서 시작했다면?
-> Bottom-UP 식 구현.
› 즉, TDD는 상향 또는 하향에 종속된 개념이 아니다.
‘Known-to-unknown’
73
TDD basic strategy
Assert first
› Test를 작성시 Assert를 제일 먼저 쓰고 시작하라.
› 시스템의 주요한 요구사항을 극도로 추상화 시킬 수 있다.
74
Testing pattern
Mock object
› 서버에 대한 테스트가 필요한데, 클라이언트가 없을 경우,
› 원격서버와의 통신중 물리환경에 의해 테스트가 실패될 때,
› 테스트 중 상대 객체에 대한 호출내역이 궁금할 때,
모의객체 (Mock Object)로 원하는 상황을 연출가능!
75
Testing pattern
Crash test dummy
› 에러 상황에 대해 테스트할 때 사용
› 객체 전체를 흉내내지 않는 점을 제외하면 Mock Object와 유
사.
› EX)
파일 시스템에 여유공간이 없는 상황을 연출하고 싶을 때.
76
Testing pattern
Crash test dummy
Private class FullFile extends File {
public FullFile(String path) {
super(path);
}
public boolean createNewFile() throws IOException {
throw new IOException();
}
}
77
Testing pattern
Crash test dummy
public void testFileSystemError(){
File f = new FullFile(“foo”);
try{
saveAs(f);
fail(); // 예외처리에 실패하면 테스트가 종료
} catch(IOException e) {
// Do Something
}
}
78
Refactoring
Main idea
› 중복을 제거한다.
› 구체화 -> 추상화시킨다.
› 과도한 제어흐름은 단순화 시킨다.
79
Design patterns
in junit
xunit?
› xUnit 은 스몰토크4의 테스트 프레임워크 SUnit 의 구조와 함
수들을 따라한 유닛 테스팅 프레임워크들을 총칭.
› 첫 글자는 사용하는 언어에서 따온다.
› 즉, JUnit은 자바를 위한 테스트 프레임워크다.
80
Design patterns
in junit
Junit patterns summary
81
Retrospective
Through TDD?
› 짧은 사이클의 반복으로 설계 방향을 누차 재점검 할 수 있다.
변화가 빨리 도입되는 극한적 상황에서 유리하다.
› 커뮤니케이션의 용이해진다. 테스트 코드는 곧 작업에 대한
history이기도 하다.
› 한참 뒤에 들이닥치는 변동사항에도 끄떡없다.
82
Retrospective
Once again, TDD?
› TDD는 테스팅 기술이 아니다.
분석 기술이며, 설계기술이기도 하다.
› 또한 개발의 모든 활동을 구조화하는 기술이다.
FOR
Clean code that works
83
My & your assignment
What else?
› 실제로 해보기! 많이!
› 읽어보기: TDD is dead long live testing by DHH
› 시청하기: 유닛테스트의 효용성 by 김포프
› TDD에 대한 ‘나’의 입장 정리해보기.
84
[1] Test Driven Development: By Examples, Kent Beck
[2] 테스트 주도 개발 (Test-Driven Development), 박상준
[3] 테스트 자동화와 TDD, 박경훈
[4] JUnit A Cook's Tour
[5] Java Reflection API, stackoverflow
[6] Design Patterns, Programcreek
[7] Extreme Programming, Wikipedia
[8] TDD는 죽었다, DHH, 이상욱 역
[9] C++ 유닛테스트, 김포프
references
Test Driven Development (TDD) basic

More Related Content

What's hot

단위테스트자동화지원도구 임성현 최종
단위테스트자동화지원도구 임성현 최종단위테스트자동화지원도구 임성현 최종
단위테스트자동화지원도구 임성현 최종guest7178884
 
Test driven development
Test driven developmentTest driven development
Test driven developmentJinho Song
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)SangIn Choung
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDDSunghyouk Bae
 
testing for agile?, agile for testing
testing for agile?, agile for testingtesting for agile?, agile for testing
testing for agile?, agile for testingSangIn Choung
 
E1_Deview nhn애자일개발 tdd_질문답
E1_Deview nhn애자일개발 tdd_질문답E1_Deview nhn애자일개발 tdd_질문답
E1_Deview nhn애자일개발 tdd_질문답NAVER D2
 
테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례SangIn Choung
 
짝 테스트(Pair Testing) 소개와 사례
짝 테스트(Pair Testing) 소개와 사례짝 테스트(Pair Testing) 소개와 사례
짝 테스트(Pair Testing) 소개와 사례SangIn Choung
 
C++ 코드 품질 관리 비법
C++ 코드 품질 관리 비법C++ 코드 품질 관리 비법
C++ 코드 품질 관리 비법선협 이
 
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018SangIn Choung
 
Tdd live spring camp 2013
Tdd live spring camp 2013Tdd live spring camp 2013
Tdd live spring camp 2013beom kyun choi
 
위험기반테스트접근 테스트계획 사례
위험기반테스트접근 테스트계획 사례위험기반테스트접근 테스트계획 사례
위험기반테스트접근 테스트계획 사례SangIn Choung
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질도형 임
 
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)SangIn Choung
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기Wonchang Song
 
자동화된 Test Case의 효과
자동화된 Test Case의 효과자동화된 Test Case의 효과
자동화된 Test Case의 효과도형 임
 

What's hot (19)

단위테스트자동화지원도구 임성현 최종
단위테스트자동화지원도구 임성현 최종단위테스트자동화지원도구 임성현 최종
단위테스트자동화지원도구 임성현 최종
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
C++과 TDD
C++과 TDDC++과 TDD
C++과 TDD
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDD
 
testing for agile?, agile for testing
testing for agile?, agile for testingtesting for agile?, agile for testing
testing for agile?, agile for testing
 
E1_Deview nhn애자일개발 tdd_질문답
E1_Deview nhn애자일개발 tdd_질문답E1_Deview nhn애자일개발 tdd_질문답
E1_Deview nhn애자일개발 tdd_질문답
 
테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례
 
TEST?
TEST?TEST?
TEST?
 
짝 테스트(Pair Testing) 소개와 사례
짝 테스트(Pair Testing) 소개와 사례짝 테스트(Pair Testing) 소개와 사례
짝 테스트(Pair Testing) 소개와 사례
 
C++ 코드 품질 관리 비법
C++ 코드 품질 관리 비법C++ 코드 품질 관리 비법
C++ 코드 품질 관리 비법
 
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018
코드 테스트와 커버리지 관련 설문 및 개선계획수립 in 2018
 
Tdd live spring camp 2013
Tdd live spring camp 2013Tdd live spring camp 2013
Tdd live spring camp 2013
 
위험기반테스트접근 테스트계획 사례
위험기반테스트접근 테스트계획 사례위험기반테스트접근 테스트계획 사례
위험기반테스트접근 테스트계획 사례
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질
 
Tdd
TddTdd
Tdd
 
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
자동화된 Test Case의 효과
자동화된 Test Case의 효과자동화된 Test Case의 효과
자동화된 Test Case의 효과
 

Similar to Test Driven Development (TDD) basic

TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDSuwon Chae
 
TDD in gameserver 발표자료
TDD in gameserver 발표자료TDD in gameserver 발표자료
TDD in gameserver 발표자료Vong Sik Kong
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...Kay Kim
 
DevRookie 리펙터링.pptx
DevRookie 리펙터링.pptxDevRookie 리펙터링.pptx
DevRookie 리펙터링.pptxMUUMUMUMU
 
TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기현승 배
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018Kenneth Ceyer
 
DebugIt/chapter1~4
DebugIt/chapter1~4DebugIt/chapter1~4
DebugIt/chapter1~4stupidfox
 
iOS개발에서 TDD 해보기 - XCTest, Unit Test
iOS개발에서 TDD 해보기 - XCTest, Unit TestiOS개발에서 TDD 해보기 - XCTest, Unit Test
iOS개발에서 TDD 해보기 - XCTest, Unit TestDoyKim
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)SangIn Choung
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"용근 권
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)도형 임
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018devCAT Studio, NEXON
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Daum DNA
 
Clean code chapter9
Clean code chapter9Clean code chapter9
Clean code chapter9ukjinkwoun
 
초보개발자의 TDD 체험기
초보개발자의 TDD 체험기초보개발자의 TDD 체험기
초보개발자의 TDD 체험기Sehun Kim
 
엔지니어의 학습, 그리고 테스트 코드
엔지니어의 학습, 그리고 테스트 코드엔지니어의 학습, 그리고 테스트 코드
엔지니어의 학습, 그리고 테스트 코드Mijeong Park
 
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기Ahreum Kim
 

Similar to Test Driven Development (TDD) basic (20)

TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDD
 
TDD in gameserver 발표자료
TDD in gameserver 발표자료TDD in gameserver 발표자료
TDD in gameserver 발표자료
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
 
TDD or TFD
TDD or TFDTDD or TFD
TDD or TFD
 
DevRookie 리펙터링.pptx
DevRookie 리펙터링.pptxDevRookie 리펙터링.pptx
DevRookie 리펙터링.pptx
 
TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기TDD - 테스트 주도로 개발하기
TDD - 테스트 주도로 개발하기
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
 
DebugIt/chapter1~4
DebugIt/chapter1~4DebugIt/chapter1~4
DebugIt/chapter1~4
 
iOS개발에서 TDD 해보기 - XCTest, Unit Test
iOS개발에서 TDD 해보기 - XCTest, Unit TestiOS개발에서 TDD 해보기 - XCTest, Unit Test
iOS개발에서 TDD 해보기 - XCTest, Unit Test
 
The Introduction to Refactoring
The Introduction to Refactoring The Introduction to Refactoring
The Introduction to Refactoring
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
 
Clean code chapter9
Clean code chapter9Clean code chapter9
Clean code chapter9
 
초보개발자의 TDD 체험기
초보개발자의 TDD 체험기초보개발자의 TDD 체험기
초보개발자의 TDD 체험기
 
애자일의 모든것
애자일의 모든것애자일의 모든것
애자일의 모든것
 
엔지니어의 학습, 그리고 테스트 코드
엔지니어의 학습, 그리고 테스트 코드엔지니어의 학습, 그리고 테스트 코드
엔지니어의 학습, 그리고 테스트 코드
 
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기
[FEConf 2018] Front-End 프로젝트의 Test code 작성경험기
 

Test Driven Development (TDD) basic

  • 1. Test-Driven Development basic Jinwoo Park, XFT-Aries, LMR PD TC3 Team
  • 2. 2 1. Test-Driven Development? 2. By Example: Action speaks louder than words 3. By Demonstration: 실천궁행(實踐躬行) 4. TDD Basic Strategy 5. Testing Pattern 6. Refactoring 7. Design Patterns in Test Framework: JUnit 8. Retrospective.. 9. My & Your Assignment 10.Reference Contents
  • 3. 3 › Learning how to do TDD › NO! › Learning the philosophy › YES! › So, How? › 배운것을 실천하며 체득한다! : 지행일치(知行一致) GOAL
  • 4. 4 Test-driven development? Test-driven development › 한국어로는 테스트 주도 개발 잠시만 안녕.. › 테스트? 주도 개발? 흠.. › 단일사고적(Monological) 접근으로! › 논제를 쪼개보자. ›테스트 / 주도 개발
  • 5. 5 Test-driven development? Test › 도와줘요! 네이버사전! › v. Test: 수작업의 느낌 › n. Test: 자동화된 느낌 › Quiz. TDD의 Test는 명사인가? 동사인가?
  • 6. 6 Test-driven development? Automated Test › 모든 테스트 케이스를 코드 스크립트로 변환한 집합체 <MCT Test>
  • 7. 7 Test-driven development? Why we need it? › 소프트웨어의 소스는 복잡하게 연결되어 있다.
  • 8. 8 Test-driven development? Why we need it? › 여기서 작은 부분이 수정된다면?? 마음이 불안해진다..
  • 9. 9 Test-driven development? Why we need it? › 모든 기능을 다시 테스트해야 한다.
  • 10. 10 Test-driven development? Why we need it? › 또한 소스코드는 시간이 지나며 녹이 슨다.
  • 11. 11 Test-driven development? Why we need it? › 끊임없는 리펙토링이 필요.
  • 12. 12 Test-driven development? Why we need it? › 하지만 리펙토링이 녹록치 않다. “We are waiting for you!”
  • 13. 13 Test-driven development? Why we need it? › 이 경우도 모든 기능을 다시 테스트 해야 한다.
  • 14. 14 Test-driven development? No automated test? › 버그 검출 능력 저하 › 소스 코드 품질 저하 › 자체 테스트 비용의 증가
  • 15. 15 Test-driven development? So, Test automation == TDD ?? › 그렇다면 테스트 자동화가 곧 TDD일까? Test -Driven Development 이제 헤어지지 말자.. › 생각을 확장할 때가 되었다.
  • 16. 16 Test-driven development? Architecture-driven development › 남녀노소 익숙한 개발 주기 설계 코딩 테스트 Next Cycle › 자동화된 테스트코드의 작성이 불가능할까?
  • 17. 17 Test-driven development? However.. › 누구나 겪어봤을 고통.. 1. 설계: 불행하게도 초반에 완벽한 설계를 하기는 힘들다. 2. 코딩: 설계가 완벽하지 않기에 코딩이 산으로 간다. 3. 테스트: 설계<->코딩 주기를 반복하며, 요구사항이 어느 정도 구현되고 나서야 작성되기 시작한다. 4. 요구사항변경 or 설계미스발견: 테스트 코드작성은 아직 미완상태. 이제 모든것이 꼬이기 시작한다.. 5. 리펙토링: 포기.
  • 18. 18 Test-driven development? Again.. Again.. And again.. › 이런 상황이 계속되어 버리면.. 스트레스 테스트 외부변수 악영향 악영향 <Influence Diagram>
  • 19. 19 Test-driven development? It makes uncertainty › 불확실성은 두려움을 만든다. 두려움은 우리를.. 1. 망설이게 만든다. 2. 커뮤니케이션을 덜 하게 한다. 3. 피드백 받는 것을 피하도록 한다.
  • 20. 20 Test-driven development? So we need courage! › 용기를 얻기 위해선 어떻게 해야할까. 1. 불확실한 상태로 있는 대신, 가능하면 재빨리 구체적인 학습을 시작 한다. 2. 침묵을 지키는 대신 좀 더 분명하게 커뮤니케이션을 한다. 3. 피드백을 회피하지 말고 도움이 되는 구체적인 피드백을 찾는다.
  • 21. 21 Test-driven development? For what? › “Clean Code that works” – Ron Jeffries › 궁극적 목표는 바로 “작동하는 깔끔한 코드”를 작성하는 것!
  • 22. 22 Test-driven development? So.. How? › 발상의 전환! 테스트우선 스트레스 외부변수 긍정적효과 긍정적효과 <Influence Diagram>
  • 23. 23 Test-driven development? Test drives development › 즉, 개발 주기에서 테스트 작성을 우선시한다! TestCoding “난 더이상 네 개가 아냐.”
  • 24. 24 Test-driven development? This is Test-driven development! 테스트 실패를 확인 테스트를 통과시킨다 테스트 성공을 확인 작은 크기의 테스트작성 리펙토링 Next Cycle
  • 25. 25 Test-driven development? What is the advantage? › 아는 것을 행할시간. › 실천을 통해 체감해본다.
  • 26. 26 By Example Scenario › 회사가 판매하는 채권 포트폴리오 관리 시스템의 새로운 고 객이 문득 이런 요구사항을 던진다. "시스템이 제공하는 기능들에 굉장히 감탄했습니다. 헌데, 미 합중국 달러로 명명된 채권만 다루고 있더군요. 저는 새로운 채권 펀드를 시작하려고 하는데 제 전략상 다른 화폐로 채권을 다룰 필요가 있습니다.“
  • 27. 27 By Example System implementation › 시스템이 기존에 제공했던 기능은 다음과 같을 것이다. 종목 주 가격 합계 IBM 1000 25 25000 GE 400 100 40000 합계 65000
  • 28. 28 By Example System implementation › To-Do List를 작성해본다. To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
  • 29. 29 By Example System implementation › 테스트 코드를 작성해본다. › 컴파일 실패! 1. 아직 Dollar 클래스가 존재하지 않는다. 2. Dollar 내부엔 int를 입력받는 생성자가 필요할 것이다. 3. Dollar 내부엔 times(int) 라는 함수가 필요할 것이다.
  • 30. 30 By Example System implementation › 재빠르고 비열하게 코드를 작성한다. › 컴파일 성공!
  • 31. 31 By Example System implementation › 테스트를 실행해본다. › 테스트 실패!
  • 32. 32 By Example System implementation › 비열하게 테스트를 통과시켜보자. › 컴파일 성공!
  • 33. 33 By Example System implementation › 비열하게 테스트를 통과시켜보자. › 테스트 성공!
  • 34. 34 By Example System implementation › 마지막 단계! 리펙토링. › 상수로 선언된 부분을 추상화한다.
  • 35. 35 By Example System implementation › 코드를 변경하였으니 테스트를 통과시켜보자. › 테스트 성공!
  • 36. 36 By Example System implementation › To-Do List를 갱신한다. To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD
  • 37. 37 By Example System implementation › 시스템이 앞으로 제공해야 할 기능은 다음과 같을 것이다. 종목 주 가격 합계 IBM 1000 25USD 25000USD Novartis 400 150CHF 60000CHF 합계 65000USD ※ 환율 : 1.5CHF = 1USD
  • 38. 38 By Example System implementation › To-Do List를 갱신한다. To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
  • 39. 39 By Example System implementation › 테스트 코드를 작성해본다. › 컴파일 실패! 1. 아직 Franc 클래스가 존재하지 않는다. 2. Franc 내부엔 int를 입력받는 생성자가 필요할 것이다. 3. Franc 내부엔 times(int) 라는 함수가 필요할 것이다.
  • 40. 40 By Example System implementation › Dollar Class를 이용하여 Franc 클래스를 만든다. › 물론, 테스트는 성공한다.
  • 41. 41 By Example System implementation › 리펙토링 단계 › Dollar클래스와 Franc 클래스 사이의 중복들이 거슬린다. › 둘을 묶을 수 있는 상위 클래스가 있다면 어떨까? › To-Do List는 항상 열려있다. To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc - Dollar와 Franc 클래스의 상위 클래스인 Money 클래스
  • 42. 42 By Example System implementation › Money 클래스 작성.
  • 43. 43 By Example System implementation › Dollar 클래스 변경.
  • 44. 44 By Example System implementation › Franc 클래스 변경.
  • 45. 45 By Example System implementation › 테스트 성공 › 이번 사이클에서는 Dollar와 Franc에 대폭 변화가 있었다. › 기존 테스트들이 Dollar와 Franc의 기능을 검증해준다! ›코드 변경에 용기가 샘솟는다!
  • 46. 46 By Example System implementation › 리펙토링. › 중복을 제거하자 1. 생성자 중복 2. 멤버변수 중복 3. times(int) 중복
  • 47. 47 By Example System implementation › Money: 변경이 없다.
  • 48. 48 By Example System implementation › Dollar, Franc: 부모클래스가 제공하는 Method를 이용한다. › 테스트 통과 확인!
  • 49. 49 By Example System implementation › To-Do List 갱신 › Dollar와 Franc의 amount가 같더라도 둘의 가치는 다르다. › Dollar와 Franc 클래스를 비교하는 기능이 필요하다. To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc - Dollar와 Franc 클래스의 상위 클래스인 Money 클래스 - Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
  • 50. 50 By Example System implementation › 테스트 코드 작성 › 컴파일 에러 › equal(Money*)함수가 존재하지 않는다.
  • 51. 51 By Example System implementation › Money: equal(Money*)함수 구현
  • 52. 52 By Example System implementation › 테스트 실패 › 환율에 대한 고려가 전혀 없다.
  • 53. 53 By Example System implementation › 테스트를 통과하려면? (전략수립) 1. Dollar와 Franc에서 각각의 통화가 무엇인지 기억한다. 2. 객체간 비교시, 각 개체의 통화정보를 기준으로 USD로 변 경한 후 비교를 수행한다. 3. 환율정보를 갖고 있는 ‘무언가’가 필요하다. 4. ‘무언가’의 이름으로는 Bank가 적절할 것 같다.
  • 54. 54 By Example System implementation › 다시 테스트 코드 작성 › 컴파일 에러 › Bank 클래스가 존재하지 않는다 › equal(Bank, Money*)함수의 입력형태가 이전과 다르다
  • 55. 55 By Example System implementation › Bank Class 작성1 › 각 화폐는 addRate시, 자신이 갖고있는 currency 식별자를 입력할 것이다.
  • 57. 57 By Example System implementation › Money Class: 화폐 식별자 currency 추가
  • 58. 58 By Example System implementation › Money Class: equal(Bank, Money*) 변경 › Bank에서 얻은 환율정보로 모든 화폐를 USD로 변경한다.
  • 59. 59 By Example System implementation › Dollar Class, Franc Class 작성 › 각 화폐 생성시 자신의 식별자가 setting된다.
  • 60. 60 By Example System implementation › 또 다시 테스트 실패 › 테스트 케이스에서 환율에 대한 정보를 입력하지 않았다. › bank.addRate(“USD”, 1.0); //추가 › bank.addRate(“CHF”, 1.0); //추가
  • 61. 61 By Example System implementation › 테스트가 통과하는 것을 확인
  • 62. 62 By Example System implementation › To-Do List 갱신 › 드디어 서로 다른 통화간의 합이 남았다 To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc - Dollar와 Franc 클래스의 상위 클래스인 Money 클래스 - Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
  • 63. 63 By Example System implementation › 테스트 코드 작성 › 컴파일에러! › Money에 add(Bank, Money*, string)가 추가되어야 한다.
  • 64. 64 By Example System implementation › Money Class: add 함수 작성 › Money에 통화단위를 입력받는 생성자가 필요하다.
  • 65. 65 By Example System implementation › Money Class: 생성자 작성 › 이로써 모든 테스트가 통과했다. › 예외처리, 리펙토링 등은 분량상 생략.
  • 66. 66 By Example System implementation › To-Do List 갱신 To-Do List - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5USD = 10USD - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc - Dollar와 Franc 클래스의 상위 클래스인 Money 클래스 - Dollar와 Franc 클래스의 비교 : Dollar(5) != Franc(5)
  • 67. 67 By Example Does it make a sense? › 머리가 복잡하시죠?
  • 68. 68 By Example Does it make a sense? › 방금 본 것은 잠시 잊으셔도 좋습니다. ›더 쉬운 예제로! ›눈 앞에서 직접!
  • 70. 70 TDD basic strategy Independent test › 각 테스트는 독립성이 보장되어야 한다. › 테스트는 충분히 빨라야한다. Q. 테스트의 독립성을 위해 Test마다 시스템을 재가동 한다면 ? Q. 재빠른 테스트를 위해 한 가지 Test 내에서 두 가지 이상의 기능을 검증한다면? › 잘만 지키면, 설계 응집도는 상승하고 결합도는 낮아진다.
  • 71. 71 TDD basic strategy To-do list › 적는 습관을 들인다! › TO-DO LIST는 카테고리 별로 잘 정리한다! -> 규모, 우선순위 등등 › 머릿속에만 의지하게 되면.. 1. 경험이 축적될수록 TO-DO LIST가 많아진다. 2. LIST가 많을 수록 집중도가 떨어진다. 3. 집중도가 떨어지면 실수가 발생한다.
  • 72. 72 TDD basic strategy Bottom-Up? Top-down? › 간단한 한가지 사례를 나타내는 테스트에서 시작했다면? -> Top-Down 식 구현. › 전체의 작은 한 조각에 해당하는 테스트에서 시작했다면? -> Bottom-UP 식 구현. › 즉, TDD는 상향 또는 하향에 종속된 개념이 아니다. ‘Known-to-unknown’
  • 73. 73 TDD basic strategy Assert first › Test를 작성시 Assert를 제일 먼저 쓰고 시작하라. › 시스템의 주요한 요구사항을 극도로 추상화 시킬 수 있다.
  • 74. 74 Testing pattern Mock object › 서버에 대한 테스트가 필요한데, 클라이언트가 없을 경우, › 원격서버와의 통신중 물리환경에 의해 테스트가 실패될 때, › 테스트 중 상대 객체에 대한 호출내역이 궁금할 때, 모의객체 (Mock Object)로 원하는 상황을 연출가능!
  • 75. 75 Testing pattern Crash test dummy › 에러 상황에 대해 테스트할 때 사용 › 객체 전체를 흉내내지 않는 점을 제외하면 Mock Object와 유 사. › EX) 파일 시스템에 여유공간이 없는 상황을 연출하고 싶을 때.
  • 76. 76 Testing pattern Crash test dummy Private class FullFile extends File { public FullFile(String path) { super(path); } public boolean createNewFile() throws IOException { throw new IOException(); } }
  • 77. 77 Testing pattern Crash test dummy public void testFileSystemError(){ File f = new FullFile(“foo”); try{ saveAs(f); fail(); // 예외처리에 실패하면 테스트가 종료 } catch(IOException e) { // Do Something } }
  • 78. 78 Refactoring Main idea › 중복을 제거한다. › 구체화 -> 추상화시킨다. › 과도한 제어흐름은 단순화 시킨다.
  • 79. 79 Design patterns in junit xunit? › xUnit 은 스몰토크4의 테스트 프레임워크 SUnit 의 구조와 함 수들을 따라한 유닛 테스팅 프레임워크들을 총칭. › 첫 글자는 사용하는 언어에서 따온다. › 즉, JUnit은 자바를 위한 테스트 프레임워크다.
  • 81. 81 Retrospective Through TDD? › 짧은 사이클의 반복으로 설계 방향을 누차 재점검 할 수 있다. 변화가 빨리 도입되는 극한적 상황에서 유리하다. › 커뮤니케이션의 용이해진다. 테스트 코드는 곧 작업에 대한 history이기도 하다. › 한참 뒤에 들이닥치는 변동사항에도 끄떡없다.
  • 82. 82 Retrospective Once again, TDD? › TDD는 테스팅 기술이 아니다. 분석 기술이며, 설계기술이기도 하다. › 또한 개발의 모든 활동을 구조화하는 기술이다. FOR Clean code that works
  • 83. 83 My & your assignment What else? › 실제로 해보기! 많이! › 읽어보기: TDD is dead long live testing by DHH › 시청하기: 유닛테스트의 효용성 by 김포프 › TDD에 대한 ‘나’의 입장 정리해보기.
  • 84. 84 [1] Test Driven Development: By Examples, Kent Beck [2] 테스트 주도 개발 (Test-Driven Development), 박상준 [3] 테스트 자동화와 TDD, 박경훈 [4] JUnit A Cook's Tour [5] Java Reflection API, stackoverflow [6] Design Patterns, Programcreek [7] Extreme Programming, Wikipedia [8] TDD는 죽었다, DHH, 이상욱 역 [9] C++ 유닛테스트, 김포프 references

Editor's Notes

  1. 중요한 것은 TDD를 하는 방법이 아닌 TDD의 철학을 음미하는 것. 사상을 이해하지 않고서는 올바른 사용을 할 수가 없다. 어떻게? How를 통해 Why로 접근해갈 것이다. 배우고, 아는 것을 행하며, 실천함으로 체득하자. 체득은 또 다시 새로운 실천으로 이어질 수 있도록 해야하겠다.
  2. 동사 테스트: 버튼을 몇 개 눌러보고 화면에 나오는 결과를 주시하는 그런 모습이 떠오르지 않는가? 명사 테스트: 자동화된 테스트는 수동 테스트와 달리 ‘소유’할 수 있다.
  3. 시간낭비 돈낭비 삶의 질 하락..
  4. 이런저런 변경이 자연스레 발생하기 때문.
  5. 잘못 건들면 터진다. 리펙토링하자고 버그만드는 경우.
  6. 아까 도입부에서 “테스트 / 주도개발” 중 ‘테스트’에 먼저 접근해 보자고 했다. 아직 한 발 남았다.
  7. 잠시 다른 화제로 전환. 비교를 위해 일반적인 개발 방식인 Architecture Driven Development 방식을 살펴보자. 허나 잘 생각해보면 여기서도 자동화된 테스트코드 작성은 가능하다. 즉 자동화된 테스트는 TDD의 전유물이 아니다.
  8. 스트레스를 많이 받으면 -> 테스트를 뜸하게 하게된다. 테스트가 뜸해지면 -> 에러 생산률이 올라간다. 에러가 많아지면 -> 스트레스가 커진다. 악순환의 반복..
  9. 아까의 다이어그램과 ‘대우’ 관계! 테스트우선 -> 불확실성을 줄이면서 스트레스를 감소시킴 스트레스 감소 -> 테스트 작성에 긍정적 효과
  10. 자 이로써 Test-Driven Development의 이름풀이가 끝났다.
  11. to-do list로부터 적절하게 작은 크기의 일을 골라 테스트를 작성한다. 돌려보면 당연히 실패할 것이다. 아직 구현된게 없으니까. 테스트 실패상태를 TDD에선 주로 Red Bar 라고 한다. (빨간막대) 최대한 빠르고 비열한 방법으로 테스트를 통과시킨다. 비록 떳떳하진 않지만 어쨌건 테스트는 통과한다. 테스트 성공상태를 TDD에선 주로 Green Bar라고 한다. (초록막대) 리펙토링을 통해 “중복을 제거”한다. 단일사고적(Monological) 접근은 TDD의 미덕이다. 위 단계를 통해 “Clean code that works” 에 단일사고적으로 접근한다. 3번에서 “Code that works”를 만들고 5번에서 “Clean code”를 만드는 것.
  12. 악몽과도 같은 상황.. 참고로 테스트에 사용된 Test Framework는 gtest-1.7.0이다.
  13. 생성자 내부에서 아무것도 안한다던지 Times가 상수를 반환한다던지.. 엉망인 코드다. 하지만 지금 목표는 빨리 테스트를 통과시키는 것이니 이는 무시하자.
  14. - USD와 CHF를 더해서 USD로 나타내는 기능 : 10USD + 15CHF = 20USD - 가격과 주를 곱해서 총 합계를 구하는 기능 : 2 * 5Franc = 10Franc
  15. 다시 사이클의 첫 번째 단계로 돌아간다. 헌데, 내부 구조만 변경할 것으므로 별도의 테스트 코드는 필요없을 듯 싶다. 테스트가 유지되므로 step 2도 넘어간다. (추가되는 코드가 없다. 테스트가 실패할 일이 없음) 그럼 Money를 구현할 차례다.
  16. 일단 Franc
  17. 공교롭게도 bank에 USD와 CHF 사이의 환율을 입력해주는 라인이 빠져있다. 테스트 초기화시 입력을 해주기 때문. addRate() 라는 함수로 테스트 시작 전, CHF의 USD기준 환율 정보가 입력되고 있다.
  18. 사실 이번 스텝은 ‘비열한 방법으로 테스트 통과하기’ 이지만, 생각하는 구현에 충분한 확신이 있다면 구현 복잡도를 좀 더 올리는 것도 괜찮다. 단, 확신이 100%에 수렴하지 않으면 추천하지 않는다. 개발 주기를 자칫 루즈하게 만들고 스트레스 상황을 증가시킬 수 있기 때문.
  19. 불행중 다행으로 Bank 내부에 USD기준의 USD환율 정보가 없는 문제 하나만 발생 이번엔 한번에 많은 양의 코드를 작업했는데, 테스트에서 수도없이 런타임 에러가 발생했다면 멘탈붕괴가 왔을 것이다.
  20. 그런데 이거 아무리봐도 실패하는 테스트다. Money에는 저런 형태의 생성자가 없다.
  21. JWTest에 대한 간단한 소개 컴퓨터로는 코딩만. 필기는 칠판이용. -> 시연은 살아있어야 한다. 3. Progress (1) 요구사항 정의. (2)~(5)에 대한 것 (2) fib(0)일때 0인지 확인 (3) fib(1)일때 1인지 확인 (4) fib(int)의 중복제거! (0과 1에 대해) (5) 2이상일땐 fib(num) == fib(num-1) + fib(num-2) 임을 검증 (6) fib()의 입력이 음수일때 예외처리. (테스트코드는 반복문 이용) (7) 오버플로에 대한 대비. 몇 번째 자리수까지 가능해야 하나? : 값이 특정 순서에서 이전값보다 작아지면?! (8) 테스트로부터 유도된 피보나치 완성!
  22. 이렇게 되면 테스트 과정에서의 스트레스가 증가한다. 바람직하지 않음.
  23. 아는 것에서 점차 모르는 곳으로 이동하는 것. 어느정도의 지식과 경험으로 시작하지만, 그 과정에서 점차 새로운 것을 배우게 된다는 것. TDD의 메타포가 지향하는 방향성은 바로 ‘아는 것에서 모르는 것으로’ 다.
  24. 그리고 추상화된 테스트를 점차 구체화 시켜간다.
  25. 테스트 코드 작성에 대한 테크닉 Mock object는 말 그대로 테스트 대상의 상대역에 대한 대역이다. 마치 클라이언트처럼 행동하는 Mock Object 작성 마찬가지로 DB처럼 행동하는 Mock Object 작성 Mock Object 내의 함수가 불러질 때마다 카운트하면 된다. 예전 서버 프로그래밍시 버퍼 오버플로우 테스트를 예로 들자.
  26. 파일 생성을 하면 묻지도 따지지도 않고 그냥 예외를 던진다.
  27. 파일 생성을 하면 묻지도 따지지도 않고 그냥 예외를 던진다.
  28. Junit의 구조를 보면 실제 Framework 상에서, 이제까지 짚어본 TDD의 전략 및 패턴이 어떻게 구현되어있는지 감을 잡을 수 있다.
  29. 앞서 다룬 내용들이 Framework에는 어떻게 담겨있을까? JUnit Architecture: http://junit.sourceforge.net/doc/cookstour/cookstour.htm/ Patterns: http://www.programcreek.com/java-design-patterns-in-stories/