85
Working with Code Kookmin University Graduate School of Busuness IT e-Government System Development 석사과정 1학기 안재열

Working with code

Embed Size (px)

Citation preview

Working with Code

Kookmin UniversityGraduate School of Busuness IT

e-Government System Development석사과정 1학기 안재열

Contents

Identifying

“bed smell”Refactoring

13가지소개 및 코드확인

4가지소개 및 코드확인

테스팅종류

Testing Debugging

+ Extending the Software for a New Project

테스팅종류UnitTestxUnitTDD 소개 및 코드

디버깅종류UnitTestIDE사용확인 – 2가지

Four central activities for Coding

Identifying

“bed smell”Refactoring

Testing Debugging

Four central activities for Coding

Identifying

“bed smell”Refactoring

Coding/

Debugging

Testing DebuggingRefactoringTesting

Four central activities for Coding

QUA

Software

ALITY

Bad Smells

What is the Bad Smells?

-> A bad smell is a segment of code that doesn’t readclearly and concisely.

코드가 명확하지 않고 간결하지도 않다.

Bad Smells

What is the Bad Smells?

Kinds of Bad Smells in the code

1) Poorly Named 9) Lazy Class

2) Duplicate Code 10) Speculative Generality

3) Long Method 11) Temporary Fields

4) Large Class 12) Inappropriate Intimacy4) Large Class 12) Inappropriate Intimacy

5) Too Many/Few comments 13) Incomplete Class

6) Data Clump 14) Refused Bequest

7) Parallel Inheritance Hierarchies 15) Feature Envy

8) Primitive Obsession

Bad Smells

1) Poorly Named

-> Variable, method or Class name does not clearlyrepresent its purpose in the code

<?php

class A{public $li1;

class A{public $li1;public function s(){$abcd = $this->li1 * 10;return $abcd;

}}?>

Bad Smells

2) Duplicate Code

-> the same sequence of expression orinstruction appears in several places.

<?php

class SumMyScore{public $math1, $math2;

public function Scoring3(){$result = $this->math1 * 10;$result + 100;return $result;

}public function Scoring1(){$result = $this->math1 * 10;$result + 1;return $result;}

public function Scoring2(){$result = $this->math1 * 10;$result + 10;return $result;}

}

public function Scoring3(){$result = $this->math1 * 10;$result + 600;return $result;

}

}#class end?>

Bad Smells

3) Long Method

-> A method contains a lot of codethat accomplishes several sub-task

<?php

class MyBestWay{public $startpoint, $endpoint;

public function finding(){public function finding(){$result = $this->math1 + $this->math2 ;$result = $result / 2;$result splice($result);

….+ 최단거리알고리즘 + sort + …return $result;}

} #class end?>

Bad Smells

4) Large Class

-> A class has an unusually and diverse collection of instance variablesor methods.

<?php

class Vehicle{public $size, $color, $weight, $cost;public $engine; #자동차, 비행기, 오토바이public $Wings; #비행기

범위가 너무 커서 인스턴스 변수와 메소드의

public $Wings; #비행기public $feed, age; #말

….public function flying(){}public function jumpStart(){}public function kickStart(){}public function eatting(){}

……

} #class end?>

턴스 변수와 메소드의개수가 엄청나게 커진다.

따라서 중복코드의 문제 또한 발생 할 수가있다.

Bad Smells

5) Too many or few Comments

-> Too many comments can hide bad code.Too few comments can make code difficult to read.

<?php

class Vehicle{public $size, $color, $weight, $cost;public $engine; #자동차, 비행기, 오토바이public $Wings; #비행기public $feed, $age; #말public $feed, $age; #말

….# flying() 메소드를 사용하실경우에는 vehicle클래스를 사용한 인스턴스들 중 하늘을 나는 경우#에 한하여 사용하실 수 있습니다. kicKStart() 메소드의 경우에는 멤버변수 $engine을 사용하게#되며 두 바퀴가 달린 이륜차에 한하여 이용하실 수 있습니다. eatting()메소드의 경우에는 말과#같은 생물에 한해 사용하실수 있으며, 메소드에서 사용되는 멤버변수로는 $feed, $age가 있습#니다.

public function flying(){}public function jumpStart(){}public function kickStart(){}public function eatting(){}

……} #class end

?>

Bad Smells

5) Too many or few Comments

-> Too many comments can hide bad code.Too few comments can make code difficult to read.

<?php

class Vehicle{public $size, $color, $weight, $cost;public $engine;public $engine;public $Wings;public $feed, $age;

public function flying(){}public function jumpStart(){}public function kickStart(){}public function eatting(){}

……} #class end

?>

321

Bad Smells

5) Data Clumps

-> The same three or four variables appear together in several differentplace.

Class A Class B Class C

Bad Smells

6) Feature Envy

-> A method requires lots of information from a different class

class First{public static $temp;public function __construct(){$this->temp = new Second();

class Second{public $maxSize = 10;public $minSize = 2;public function maxCal($value){$this->temp = new Second();

}public function maxCal($value){return $temp->maxCal($value);}

public function minCal($value){$result = $value * $temp->minSize;return $result;}}

public function maxCal($value){$result = $value * $this->maxSize;return $result;

}}

Bad Smells

7) 기본타입에 대한 강박관념 Primitive Obsession

->the code is reluctant to use classes instead of primitive data types.OOP에서 클래스 사용보다, 기본타입을 우선 고려 할 경우의 문제.

$Students = array();array_push($Student, “Tom”); //namearray_push($Student, 20); //agearray_push($Student, “Male”);//Genderarray_push($Student, “Swimming”); //hobby 배열내의 요소가

.

.

.

array_push($Student, “Swimming”); //hobbyarray_push($Student, true);//자취여부array_push($Student, 7);//좋아하는 숫자

$Students2 = array();array_push($Student, “Emily”); //namearray_push($Student, 24); //agearray_push($Student, “Female”);//Genderarray_push($Student, false); //자취여부array_push($Student, 24);//좋아하는 숫자....

배열내의 요소가많아 질 수록

코딩 시 헷갈릴 수있다.

Bad Smells

8) Lazy Class

->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.

Person TelephoneNumber

->리팩토링 이후 기능이 축소되거나 쓸모 없어진 클래스

Person

name

getTelephoneNumber()

TelephoneNumber

areaCodenumber

getTelephoneNumber()

사용1회

사용1회

총 2회

Bad Smells

8) Lazy Class

class Person{private $_name; //이름private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체)

public function getName(){return $this->_name;

}

//전화번호가져오기 -> 전화객체에서public function getTelephoneNumber(){return $this->_officeTelephoneNumber->getTelephoneNumber();

}//전화객체가져오기 ->전화객체에서funcion getOfficeTelephone(){return $this->_officeTelephoneNumber;}

}

Bad Smells

8) Lazy Class

class TelephoneNumber{private $_number; // 개인고유번호private $_areaCode; // 지역번호//전화번호 가져오기 ; 지역번호 + 개인고유번호public function getTelephoneNumber(){return “(“.$this->_areaCode.”) ”. $this->_number

}public function getAreaCode(){return $this->_areaCode;return $this->_areaCode;

}

public function setAreaCode($arg){$this->_areaCode = $arg;

}public function getNumber(){return $this->_number;

}

public function setNumber($arg){$this->_number = $arg;

}}

Bad Smells

8) Lazy Class

->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.

-> 추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class!

Person

name

getTelephoneNumber()

TelephoneNumber

areaCodenumber

getTelephoneNumber()

Bad Smells

9) 추측성 일반화 (Speculative Generality)

->일어날 가능성이 거의 없는 일까지 다 대비한 필요없는 코드들은 제거하라. 모든 기능들과 절차들은 제대로 이용되었을 때 쓸모가 있다.

Class Test

만약을 위한 멤버변수 1만약을 위한 멤버변수 2만약을 위한 멤버변수 3만약을 위한 멤버변수 4만약을 위한 멤버변수 4……만약을 위한 멤버변수 100

만약을 위한 메소드 1만약을 위한 메소드 2만약을 위한 메소드 3….If 만약을 위한 분기문 1If 만약을 위한 분기문 2If 만약을 위한 분기문 3……

Bad Smells

10) 임시 필드 (Temporary Field)

->때로는 어떤 객체 안의 인스턴스 변수가 특정 상황에서만 세팅되는 경우가 있다. 보통은 객체의 모든 변수가 값을 가지고 있을 거라고 기대하기 때문에 이런 코드는 이해하기 어렵다.

Student

$Name //학생이름$AGE // 학생나이$AGE // 학생나이$height // 학생키$temp // 평균 낼 때 사용되는 임시변수$temp2 // function4와 5, 8에서 사용되는 임시변수….

Function 1(){}Function 2(){}Function 평균(){}Function 4(){}……

Bad Smells

11) 지나친 관여(Inappropriate Intimacy)

-> 간혹 클래스끼리 관계가 지나치게 밀접한 나머지 서로의 private 를 알아내느라 시간을 낭비하게 되는 경우가 있다.

A

Private $a

B extends C

Private $b

C

Private $c =new D().getD();

Protected getC()Private $a

Public getA()

Private $b= new C().getC()

Public getB()

Protected getC()

D

Private $d = 1

Protected getD()

Protected1. 같은 package 내의 모든 클래스에서 접근가능2. 다른 패키지의 클래스라도 해당클래스 상속시 접근가능

Bad Smells

12) 불완전한 클래스 (Incomplete Class)

-> One that doesn’t do everything you need.

Sort

MemberQuick Sort?

Membervariables.

BubbleSelectInsertionMerge...

Quick Sort?오름차순?

Bad Smells

13) 방치된 상속물 (Refused Bequest)

-> 서브클래스는 메소드와 데이터를 그 부모 클래스로부터 상속 받는다.그러나 만약 서브클래스가 그들에게 주어진 것을 원치 않는다거나,필요하지 않는 경우.

Parents

function a

SonA

function a //상속

function b

GrandSonAA

function a //상속

function b//상속

function c

GrandSonAB

SonB

function a //상속

function b

GrandSonBA

Fun!

Fun!

Fun!

Fun!

Software Metrics

- 소프트웨어의 Quality를 평가 할 수 있는 방법 4가지

• Pakages, classes, instance variables, methods, paramethers, lines

• 적당하고 자연스럽게 적을수록 좋다.

Count (수량)

• 메소드 안에서의 분기문 및 제어문의 수량. //

• 많을수록 복잡하다. 한 메소드안에는 10개 미만으로 유지하는게 좋다.

Clarity (명확성)

• 하나의 단위 내에서, 한 기능을 수행하기 위해 각 구성 요소들이 가까이 있는 경우

• 모듈은 응집도를 높이기 위한 방안 중 하나.

• OOP는 정적인데이터와 동작을 함께 묶어 객체를 정의함으로써 높은 응집도를 얻음

• 4장에서 LCOM 의 값이 0에 가까울 수록 응집도가 높음

Cohension (응집도)

• 코드기반의 패키지(모듈,클래스,함수,라이브러리등)이 얼마나 독립적으로 움직일 수 있는가?

Coupling (결합도)

Refactoring

Refactoring

1. 메소드 정리

2. 객체나 클래스 사이의 이동

3. 데이터의 재구성

4. 조건문을 이해하기 쉽게 단순화4. 조건문을 이해하기 쉽게 단순화

5. 메소드 호출 단순화

6. 상속관계 재구성

Refactoring

How to do ?

1) Renaming 7) Simplifying conditionals

2) Extracting a method 8) Removing Useless Code

3) Extracting a methods 9) Removing Violations to Layering Principles

4) Reorganizing a class 10) Merging Similar Functions /Modules4) Reorganizing a class 10) Merging Similar Functions /Modules

5) Unifying data clumps 11) Separating Model, View, Controller Code

6) Removing a parameter

Refactoring - Renaming

네이밍 관례와 표준

파스칼 표기법

"PascalCase"

"쌍봉낙타" 표기법

첫 단어를 대문자로 시작하는 카멜 표기법첫 단어를 대문자로 시작하는 카멜 표기법

예시:

BackgroundColor, TypeName, PowerPoint

Refactoring - Renaming

네이밍 관례와 표준

카멜 표기법"camelCase""단봉낙타" 표기법

첫글자는 소문자,단어와 단어 만나면 첫 글자 -> 대문자단어와 단어 만나면 첫 글자 -> 대문자띄어쓰기 대신 대문자로 단어를 구분하는표기 방식

예시:backgroundColor, typeName, iPhone

Refactoring - Renaming

네이밍 관례와 표준

헝가리안 표기법

-. 헝가리안 개발자가 창시-. 변수명 맨 앞에 자료형을 명시함

예시:예시:-. iNum, iCnt, dAmount //

int ,int, double

언더바 표기법(Underbar Notation), Snake Notaion-. 단어와 단어 사이에 언더바-. user_name

Refactoring - Renaming

네이밍 관례와 표준

1.1. 클래스 명에는 파스칼 표기법을 사용한다.

public class HelloWorld{...}

1.일반적으로 클래스이름은 명사명사들의 조합혹은 형용사형용사 ++ 명사로명사로지정한다.}

1.2. 함수(Method) 명에는 카멜 표기법을 사용한다.

void sayHello(string name){...}

지정한다.

2. 메소드는 동사동사 ++ 명사명사의의 형태로 지정하는 것이 일반적이다.

Refactoring - Renaming

네이밍 관례와 표준

올바른 클래스명의 예

class LoginAction;

class HTTPRequest; : 축약어는 모두 대문자로 사용(HTTP는 범용적으로 사용되는 축약어)

abstract class AbstractUserInformation;

잘못된 클래스명의 예

class GSL; : 정확하게 약어의 뜻을 유추할 수 없음

class my_action; : 클래스 명이 소문자로 시작되어 클래스 명 식별이 쉽지 않고,

밑줄을 사용하여 자바 API와 일관성이 떨어짐

class 사용자; : 한글을 클래스 명으로 사용할 경우 일부 OS에서 클래스를 읽을 수 없음

class DoIt; : 클래스는 하나의 엔티티(entity)를 뜻하므로, 어떠한 행동을 기술하는

동사를 사용할 경우, 클래스의 정확한 용도를 유추하기가 어려움

Refactoring - Renaming

올바른 메소드명의 예

Customer getCustomer();void drawCircle(int x, int y, int radius);boolean isLive()//boolean의 경우 is를 주로 앞에 붙인다.

클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어를 사용하지 않는 것을 원칙으로 하며, 부득이하게 사용해야 할 경우 축약어는모두 대문자로 지정한다. 예) HTTP, ID

HTTPHeader getHTTPHeader();void setMessageID(MessageID msgID);

Refactoring - Renaming

네이밍 관례와 표준

1.3. 변수와 함수 파라미터에는 카멜 표기법을 사용한다.

int totalCount = 0;void SayHello(string name){{string fullMessage = "Hello " + name;...}

Refactoring - Renaming

네이밍 관례와 표준

1.4. 인터페이스에는 접두사 "I"가 포함된 파스칼 표기법을 따른다.

예 : IEntity

1.5. 변수명에 헝가리안 표기법을 사용하지 않는다.

이전에는 많은 프로그래머들이 변수명에 데이터 타입에 해당하는 접두사를 첨가하였다. 즉, 멤버변수에는 아래와 같이 m_ 을 접두사로 사용하는 것과 같은 헝가리안표기법을 사용했었다.

string m_sName;int nAge;

Refactoring - Renaming

네이밍 관례와 표준

1.6. 변수에 모든 의미를 충분히 담아라(약어를 사용하지 말것).

- 좋은 예string addressint salary

- 나쁜 예string namstring addrstring addrint sal

1.7. "i, n, s,..."와 같이 한 글자로 된 이름을 사용하지 말것.

i, n, s 보다는 index, temp 와 같은 이름을 사용한다.

한 가지 예외가 있다면 루프에서 반복을 의미하는 변수를 허용하는 경우이다.for ( int i = 0; i < count; i++ ){...}

Refactoring - 10) Merging Similar Functions

8) Lazy Class

->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.

->추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class!

Person

name

getTelephoneNumber()

TelephoneNumber

areaCodenumber

getTelephoneNumber()

Refactoring - 10) Merging Similar Functions

8) Lazy Class

class Person{private $_name; //이름private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체)

public function getName(){return $this->_name;

}

//전화번호가져오기 -> 전화객체에서public function getTelephoneNumber(){return $this->_officeTelephoneNumber->getTelephoneNumber();

}//전화객체가져오기 ->전화객체에서funcion getOfficeTelephone(){return $this->_officeTelephoneNumber;}

}

Refactoring - 10) Merging Similar Functions

8) Lazy Class

class TelephoneNumber{private $_number; // 개인고유번호private $_areaCode; // 지역번호//전화번호 가져오기 ; 지역번호 + 개인고유번호public function getTelephoneNumber(){return “(“.$this->_areaCode.”) ”. $this->_number

}public function getAreaCode(){return $this->_areaCode;return $this->_areaCode;

}

public function setAreaCode($arg){$this->_areaCode = $arg;

}public function getNumber(){return $this->_number;

}

public function setNumber($arg){$this->_number = $arg;

}}

Refactoring - 10) Merging Similar Functions

class Person{ //논리적 개념의 범위가 더욱 큰 Person으로 변경private $_number; // 개인고유번호private $_areaCode; // 지역번호private $_name; //이름, 원래 Person의 것

//전화번호 가져오기 ; 지역번호 + 개인고유번호public function getTelephoneNumber(){return “(“.$this->_areaCode.”) ”. $this->_number}

public function getAreaCode(){return $this->_areaCode;}

public function setAreaCode($arg){$this->_areaCode = $arg;}

public function getNumber(){return $this->_number;}

public function setNumber($arg){$this->_number = $arg;}

public function getName(){ //원래 Person의 것return $this->_name;

}}

Refactoring - 2) Extracting a method

Motive :메서드가 너무 길거나, 코드에 주석을 달아야만 의도를 이해할 수 있을 때 필요하다.( Bed Smell - Long Method, Too Many comments)

Why?

-> 1. 메서드가 적절히 잘게 쪼개져 있으면 다른 메서드에서 쉽게 사용 할 수 있다.

2. 재정의하기 쉽다2. 재정의하기 쉽다

Refactoring - 2) Extracting a method

How to?

-> 1. 목적에 부합하는 이름의 새 메서드를 생성한다.이때 메서드명은 원리가 아니라 기능을 나타내는 이름이어야 한다.

2. 기존 메서드에서 빼낸 코드를 새로 생성한 메서드로 복사한다.

3. 추출한 코드에서 기존 메서드의 모든 지역변수 참조를 찾는다.그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다.그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다.

4. 추출한 코드내에서만 사용되는 임시변수가 있다면,이를 새로생성한 매서드 안에 임시변수로 선언한다.

.

.

.

Refactoring - 2) Extracting a method

Enumeration컬렉션인 Vector, Hash의 elements 를 열거하는인터페이스

import java.util.Vectorimport java.util.Enumeration

public class Test{public static void main(String[]args){

Vector vt = new Vector();vt.add("one");vt.add(2);vt.add("셋");Enumeration et = vt.elements();while(et.hasMoreElements()){System.out.print(et.nextElement()+" ");}

}}

결과 :one 2 셋

Refactoring - 2) Extracting a method

Order

-Double amount //외상값 합-Date

+getAmount(); //

HostPrint

+ printOwing(){}+getAmount(); //+getDate();

Refactoring - 2) Extracting a methodOrder

-Double amount //외상값 합-Date

+getAmount(); //+getDate();

HostPrint

-String _name

+ printOwing(){}

void printOwing() {Enumeration e = _orders.elements();double outstanding = 0.0;

//배너 출력System.out.println (“****************”);System.out.println (“*****고객외상*****”);System.out.println (“*****고객외상*****”);System.out.println (“****************”);

//외상액 계산while (e.hasMoreElements()){Order each = (Order) e.nextElement(); //elements 추출outstanding += each.getAmount(); // elements였던 Order객체의 외상값합계추출}

//세부내역 출력System.out.println (“고객명 : ”+_name);System.out.println (“외상액 : ”+outstanding);

}

Refactoring - 2) Extracting a method

void printOwing() {Enumeration e = _orders.elements();double outstanding = 0.0;

printBanner();

//외상액 계산while (e.hasMoreElements()){Order each = (Order) e.nextElement();outstanding += each.getAmount();}

//세부내역 출력System.out.println (“고객명 : ”+_name);System.out.println (“외상액 : ”+outstanding);

}

void printBanner(){//배너 출력System.out.println (“****************”);System.out.println (“*****고객외상*****”);System.out.println (“****************”);

}

Refactoring - 2) Extracting a method

void printOwing() {Enumeration e = _orders.elements();double outstanding = 0.0;printBanner();printDetails(outstanding);

//외상액 계산while (e.hasMoreElements()){Order each = (Order) e.nextElement();outstanding += each.getAmount();}

}}void printBanner(){//배너 출력System.out.println (“****************”);System.out.println (“*****고객외상*****”);System.out.println (“****************”);

}void printDetails(double outstanding){//세부내역 출력System.out.println (“고객명 : ”+_name);System.out.println (“외상액 : ”+outstanding);

}

Refactoring - 2) Extracting a method

void printOwing() {

double outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다.printBanner();printDetails(outstanding);}}void printBanner(){//배너 출력System.out.println (“****************”);System.out.println (“*****고객외상*****”);System.out.println (“****************”);

}void printDetails(double outstanding){//세부내역 출력//세부내역 출력System.out.println (“고객명 : ”+_name);System.out.println (“외상액 : ”+outstanding);

}

double getOutstanding(){//외상액 계산Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경while (e.hasMoreElements()){Order each = (Order) e.nextElement();result += each.getAmount();

}return result;}

Refactoring - 2) Extracting a method

void printOwing(double previousAmount) {

double outstanding = previousAmount * 1.2;outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다.printBanner();printDetails(outstanding);}}void printBanner(){//배너 출력System.out.println (“****************”);System.out.println (“*****고객외상*****”);System.out.println (“****************”);

}void printDetails(double outstanding){}void printDetails(double outstanding){//세부내역 출력System.out.println (“고객명 : ”+_name);System.out.println (“외상액 : ”+outstanding);

}

double getOutstanding(){//외상액 계산Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경while (e.hasMoreElements()){Order each = (Order) e.nextElement();result += each.getAmount();

}return result;}

Refactoring - 9) Removing Violations to Layering Principles

View

Controller

Model

Controller

Refactoring - 9) Removing Violations to Layering Principles

editshift.php

Refactoring - 9) Removing Violations to Layering Principles

dbPersons.php

PHP는 Dynamic Typing이 가능하다. 따라서 변수의 타입지정은값 할당 뒤 일어난다. -> 응용가능.(※내부 logic은 유사하다는 전제.)

Refactoring - 9) Removing Violations to Layering Principles

dbPersons.php

Parameter 2개인 함수는없어서 새로 만듬

Testing

Identifying

“bed smell”Refactoring

Testing Debugging

Testing – 결함 발견시기와 비용

비용

제가원한소프트웨어가

아니네요.

요구사항분석 설계 개발 운영

고객테스팅이가장어렵다.(인수테스트

Acceptance Test)

Testing – 종류

• 보통 단위테스트 혹은 Unit Test라고 부른다.

• 모듈이나 객체, 프로그램과 같이 개별적으로 테스트가 가능한 단위에 대해서 테스트

• 우리나라 SI 거의 안 함

Component Test (컴포넌트 테스트)

• 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다.

Integration Test (통합테스트)

• 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다.

• UI와 서버 부분을 묶거나, 기능 사이에 연결관계를 테스트한다.

• 개발된 시스템이 제대로 동작하는지 확인.

System Test (시스템테스트)

• 고객이 원하는 대로 만들었는지 확인

Acceptance Test (인수테스트)

Testing – 종류

• 보통 단위테스트 혹은 Unit Test라고 부른다.

• 모듈이나 객체, 프로그램과 같이 개별적으로

테스트가 가능한 단위에 대해서 테스트

• 우리나라 SI 거의 안 함. – 착각함.

Component Test

(컴포넌트 테스트)

서비스 개발자는 jsp에서의 문제인지, class에서의 문제인지 확인가능

화면테스트 AddMovie.jsp AddManager.class

테스터는 전체의 과정을 알기 힘들다.

STUB

DRIVER

Testing – Unit test

Stub, driver =단위마다 테스트 코드(함수,메소드 작성)

(※DB의 경우 CRUD에 맞춰서)

개별 메소드마다 실행된다.개별 메소드마다 실행된다.예) Echo 기능의 메소드일경우 echo 실행.※만약 10000개 존재?->1만라인 실행 및 1만번 수행

Testing – Unit testUnitTestCase

….

generate_new_shift()assertEqual()assertTrue()assertFalse()…

테스트 메소드를모아놓은 클래스를 만든 후

상속시킨다.

Class TestSuite

Testing – Test suite

A test suite is a collection of “unit tests”

Class 1

메소드A

C

testA

Class 2

C

B

testC

testB

Testing – xUnit

Unit test를 위한 Framework.

xUnits Languages

JUnit, TestNG Java

NUnit,csUnit,MbUnit,MSTest

.NET

Test::Unit Ruby

CUnit CCUnit C

CppUnit C++

PHPUnit PHP

PyUnit Python

DbUnit Database

utPLSQL PL/SQL

leUnit JavaScript,DHTML

Testing – PhpUnit

Testing – UnitTest Cheak list

Test Driven Development - TDD

What? –Test the program before you write it. – Kent Beck프로그램 작성하기 전에 테스트 먼저 하라!

디자인 개발 테스트

기존 개발 절차

TestScript

개발개발 리팩토링

TDD 개발 절차

Test Driven Development - TDD

What?

TestScript

개발개발 리팩토링

1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다

2. 그다음 실제 서버에서 수행되는 코드를 작성하는데, 먼저 만든 테스트스크립트

를 수행하면 PASS 하도록 코딩한다.

3. 코드작성을 마치고, 그 코드의 가독성, 유지보수성을 높이기 위해 리팩토링한다.

Test Driven Development - TDD

Test Script – 명시적인 코드로 개발 종료조건을 정해 놓은 것

class Calculator{

public function $sum($a, $b){return 0;

}}

class TestScript {

$testObject;

$test = new Calulator();$ts = new TestScript($test);$ts->test();

------결과--------$testObject;

public function __constant($obj){$this->testObject = $obj;}

public function test(){echo ($testObject->sum(10,20) == 30);echo ($testObject->sum(1,2) == 3);echo ($testObject->sum(-10,20) == 10);echo ($testObject->sum(0,0) == 0);

}

}

------결과--------

falsefalsefalsetrue

Test Driven Development - TDD

Test Driven Development - TDD

What?

- 코딩 할 시간도 없는데 무슨 테스트코드를 작성하고 있어?

Debugging

Identifying

“bed smell”Refactoring

Testing Debugging

Debugging

재현가능성확보

단서의확보

개발지식이 충분하다면,단계별로 정확하게 진행이 가능하다.

하지만, 개발지식이 부족 할 경우무작위로 코드를 고쳐보고이전상태로 돌려보는 상황이 나타난다.

최악의 경우 검색으로 힌트를 얻어,소거법으로 하나하나 연관 없는 부분을

단서의분석

가설의수립

가설의검증

소거법으로 하나하나 연관 없는 부분을제거하기도 한다.

Debugging

원초적인 방법으로는

1. Console에 print.

2. Log.debug()와 같이 로거의 메소드를 호출하여

소스에 흔적이 남을 수 있다.

3. IDE tool을 이용하기

- Eclipse, VisualStudio 등등

Debugging –IDE 이클립스

Debugging

Debugging – IDE Visual Studio

Debugging – IDE Visual Studio

중단점에서멈춤

Debugging – IDE Visual Studio

Extending the Software for a New Project

New Use Case

요구사항 뭐지?

User Interface

그래서 뭐필요? ->스케치

Classes& Modules

기존에 있나?

냄새는?

Database

이미 정보가 있나?

테이블 더 필요?

CRUD Availability?

Security

보안정책에 위배?

User Help

사용자를 위한 안내는 어떻게 ?

Team Discussion

기술적으로 잘 될까?

빼먹은건 없을까?

레퍼런스

감사합니다.감사합니다.