Skip to content

Commit d0901e2

Browse files
committed
9. 단위테스트
1 parent 32236f5 commit d0901e2

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed

9. 단위테스트/README.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# 단위테스트
2+
3+
## TDD 법칙 세 가지
4+
1. 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
5+
2. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
6+
3. 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
7+
8+
## 깨끗한 테스트 코드 유지하기
9+
#### 테스트 코드는 실제 코드 못지 않게 중요하다. 유명무실한, 오히려 방해가 되는 테스트코드를 작성하고 싶지않으면 깨끗한 테스트코드를 유지하자.
10+
11+
### 테스트는 유연성, 유지보수성, 재사용성을 제공한다.
12+
#### 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목은 단위테스트 !
13+
14+
### 깨끗한 테스트 코드
15+
#### 깨끗한 테스트 코드를만들려면? 세 가지가 필요하다. 가독성, 가독성, 가독성
16+
ex1)
17+
```
18+
public void testGetPageHieratchyAsXml() throws Exception {
19+
crawler.addPage(root, pathParser.parse("PageOne"));
20+
crawler.addPage(root, pathParser.parse("PageOne.ChildOne"));
21+
crawler.addPage(root, pathParser.parse("PageTwo"));
22+
23+
request.setResource("root");
24+
request.addInput("type", "pages");
25+
Reponder responder = new SerializedPageResponder();
26+
SimpleResponse = response =
27+
(SimpleResponse) responder.makeResponse (
28+
new FitNessContext(root), request);
29+
String xml = response.getContent();
30+
31+
assertEquals("text/xml", response.getContentType());
32+
assertSubString("<name>PageOne</name>", xml);
33+
assertSubString("<name>PageOne.ChildOne</name>", xml);
34+
assertSubString("<name>PageTwo</name>", xml);
35+
}
36+
```
37+
38+
ex2)
39+
```
40+
public void testGetPageHierarchyAsXml() throws Exception {
41+
makePages("PageOne", "PageOne.ChildOne", "PageTwo");
42+
43+
submitRequest("root", "type:pages");
44+
45+
assertResponseIsXML();
46+
assertResponseContains(
47+
"<name>PageOne</name>", "<name>ChildOne</name>", "<name>PageTwo</name>"
48+
);
49+
50+
}
51+
```
52+
#### 테스트 코드는 본론에 돌입해 진짜 필요한 자료 유형과 함수만을 사용한다.
53+
54+
### 도메인에 특화된 테스트 언어
55+
#### 위의 ex2)는 도메인에 특화된 언어, 계속해서 리펙토링을 통해 API들을 생성해나가야한다.
56+
57+
### 이중 표준
58+
#### 단순, 간결, 표현력이 풍부해야하지만, 효율적일 필요는 없다.
59+
ex1)
60+
```
61+
@Test
62+
public void turnOnLoTempAlarmAtThreashold() throws Exception {
63+
hw.setTemp(WAY_TOO_COLD);
64+
controller.tic();
65+
assertTrue(hw.heaterState());
66+
assertTrue(hw.blowerState());
67+
assertFalse(hw.coolerState());
68+
assertFalse(hw.hiTempAlarm());
69+
assertTrue(hw.loTempAlarm());
70+
}
71+
```
72+
73+
ex2)
74+
```
75+
@Test
76+
public void turnOnLoTempAlarmAtThreshold() throws Exception {
77+
wayTooCold();
78+
assertEquals("HBchL", hw.getState());
79+
}
80+
```
81+
82+
## 테스트당 assert 하나
83+
ex1)
84+
```
85+
public void testGetPageHierarchyAsXml() throws Exception {
86+
makePages("PageOne", "PageOne.ChildOne", "PageTwo");
87+
88+
submitRequest("root", "type:pages");
89+
90+
assertResponseIsXML(); //출력이 XML이다.
91+
assertResponseContains(
92+
"<name>PageOne</name>", "<name>ChildOne</name>", "<name>PageTwo</name>"
93+
); // 특정 문자열을 포함한다.
94+
}
95+
```
96+
97+
ex2)
98+
```
99+
public void testGetPageHierarchyAsXml() throws Exception {
100+
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
101+
whenRequestIsIssued("root", "type:pages");
102+
103+
then ResponseShouldBeXML();
104+
}
105+
106+
public void testGetPageHierarchyHasRightTags() throws Exception {
107+
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
108+
109+
whenRequestIsIssued("root", "type:pages");
110+
thenResponseShouldContain(
111+
"<name>PageOne</name>", "<name>ChildOne</name>", "<name>PageTwo</name>"
112+
)
113+
}
114+
```
115+
116+
-> 중복된 코드가 많아짐.
117+
이 책의 저자는 이 규칙을 무조건적으로 따르지는 않아도 된다고 생각함. 다만, 가능하면 assert는 적게..
118+
119+
### 테스트 당 개념 하나
120+
ex) 메소드를 테스트하는 장황한 코드
121+
```
122+
public void testAddMonths() {
123+
SerialDate d1 = SerialDate.createInstance(31, 5, 2004);
124+
125+
SerialDate d2 = SerialDate.addMonths(1, d1);
126+
assertEquals(30, d2.getDayOfMonth());
127+
assertEquals(6, d2.getMonth());
128+
assertEquals(2004, d2.getYYYY());
129+
130+
SerialDate d3 = SerialDate.addMonths(2, d1);
131+
assertEquals(31, d3.getDayOfMonth());
132+
assertEquals(7, d3.getMonth());
133+
assertEquals(2004, d3.getYYYY());
134+
135+
SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
136+
assertEquals(30, d4.getDayOfMonth());
137+
assertEquals(7, d4.getMonth());
138+
assertEquals(2004, d4.getYYYY());
139+
}
140+
```
141+
142+
-> 이 테스트코드의 문제는 테스트케이스가 여러개가 있는것이 아니다. 문제는 한 테스트코드에서 여러가지의 개념을 테스트한다는 사실이다.
143+
144+
145+
## F.I.R.S.T.
146+
### 깨끗한 테스트의 다섯가지 규칙
147+
148+
### 빠르게(Fast)
149+
#### 테스트는 빨라야한다. 빨라서 자주 돌릴 수 있어야한다.
150+
151+
### 독립적으로(Indepentent)
152+
#### 테스트는 서로 의존하면 안된다. 만약 테스트가 서로 의존하고 있다면, 한 테스트의 오류를 찾기위해 다른 테스트도 뒤져야한다. 원인 찾기가 너무 힘들어진다.
153+
154+
### 반복가능하게(Repeatable)
155+
#### 테스트는 어떤 환경에서도 반복 가능해야 한다. 실제 환경, QA 환경, 심지어 네트워크가 안되는 환경에서도 테스트가 가능해야한다.
156+
157+
### 자가검증하는(Self-Validating)
158+
#### 테스트의 결과는 Bool이다. 로그따위를 써서는 안된다.
159+
160+
### 적시에(Timely)
161+
#### 테스트는 적시에 작성해야한다. 단위테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다. 만일 반대의 순서로 작성을 하게된다면, 테스트코드를 작성하면서 이코드는 테스트코드를 작성하기 힘들구나 라고 생각하는 상황이 올 수 있다. 최악의 경우 테스트가 불가능 할 수 있다.
162+
163+
164+
165+

0 commit comments

Comments
 (0)