[Java] JUnit 사용하기

Java 2014. 9. 12. 09:39

http://cafe.naver.com/fillmyjavacareer/113

http://blog.naver.com/ellay06/120170104099

 

'Java' 카테고리의 다른 글

[Java] J Unit 이란?  (0) 2014.09.11
[Java] Virtual 함수( 가상함수)  (0) 2014.09.04
[Thread Pool] ThreadPoolExecutor  (0) 2012.09.06
Bing Translator API를 이용한 번역 - JAVA  (0) 2012.07.21
Java ::: cmd 명령어 실행법  (0) 2012.06.28
블로그 이미지

kuku_dass

,

[Java] J Unit 이란?

Java 2014. 9. 11. 20:30

JUNIT

자바 프로그래밍시 Unit테스트를 쉽게 해주는 프레임 워크, 테스트 툴입니다.

 

여기서 유닛테스트(Unit Test)란 프로그래밍중 소스 코드의 특정 모듈이 의도대로 정확히 작동되는지 검증하는 절차라고 하는데 , 쉽게 말해서 한번에 컴파일해서 확인하려면 오래걸리니까( 간단한 프로그래밍이 아닌 복잡하고 몇만줄 이상의 코드일시) 각 부분만 확인이 가능한 테스트입니다.

또한 구현의 완성이 안되있더라도 내가 확인하고 싶은 기능의 완성된 모습을 직접 확인 할 때도 사용할 수 있습니다. 이렇게 각 테스트 케이스(테스트를 하려는 대상)가 서로 분리되야 하기 때문에, 확인을 위한 가짜 객체를 생성하기도 합니다.  

 

특정 모듈을 테스트하는 이유는 전체적인 환경에서 해당 로직의 문제를 테스트하는것 보다 해당 로직의 문제를 직접 테스트하는 것이 더욱 직관적이고 확실하기 때문입니다. 만약 대형프로젝트 같은 경우를 생각해보자면, 예상 실행 속도보다 느리게 나올 경우가 있을 것입니다. 그럴경우 전체적으로 소스를 보고 어떤 로직 떄문에 예상 속도가 안나오는지 확인 하기가 어렵습니다. (가능하다면 .. 할말 없네요 ㅋㅋ) 그렇기에 전체적이 아닌 특정 모듈의 각 로직을 하나씩 보면서 확인 할 수 있는 유닛테스트를 하는 것입니다.

 

예를 들어볼까요?

첫번쨰로, 제가 만든 각종 연산하는 프로그램이 있습니다. 문제는 이상은 없는것 같은데 결과가 이상합니다.  그래서 테스트를 시작합니다. (거기엔 각종 비트연산자, 산술연산자, 증감연산자 등등 많다는 가정하예요!!)  

덧셈부분이 잘못 됬다고 치고, 일단 차례대로 메소드들은 테스트 할 것입니다. 그런데 잘못된 덧셈을 하기 전 각각의 메소드 들을 모두 테스트 해야하고 잘못된 선택으로 취소가 됬다면 설상가상 다시 처음부터 테스트를 해야합니다. 

두번째, 디비와 연동된 클래스입니다. 임시적으로 테스트를 위해 DB 접속을 위한 암호를 넣고 실수로 그 사실을 잊어버려 테스트 후 남겨뒀다고 하면, 이 정보는 심각한 보안상 문제를 일으킬수 있습니다.

그렇기 때문에!! 유닛테스트를 합니다  

 

그런데 자꾸, 테스트 한다는데 도대체 어떻게 테스트를 하는걸까요?

다시 말해서 어떻게 우리가 원하는 대로 동작 하는지 어떻게 알 수 있을까요? 

 

답은 기대값과 결과값의 비교입니다.

쉽죠? 기대값과 결과값의 비교.. 당연한 말이죠.

우리가 A를 생각했는데 해당 답변이 A로 나왔다면 정말 좋은것일테고 B로 나왔다면 무엇인가 잘못 된거겠죠. 만약 a로 나왔다면 그런데로 비슷하게 나왔다고 할 수 있겠죠?

이렇게 기대값과 결과값을 비교함으로써 프로그래머 또는 프로그램을 요구한 회사, 사용자는 이 결과를 보고 수정할 수도 그대로 진행 할 수도 있게됩니다.

 

-Methods 정리-

 

/*

assertEquals(A, B)

 A와 B가 일치하는지를 조사

 A  , B 에는 Object, int, float, long, char,boolean 등의 모든 자 료형이 들어갈 수 있다. 단 A, B의 타입은 언제나 같아야만 한다. 

/*

assertTrue(X)

 X가 참인지를 조사한다. 

 X는 boolean형태의 값이어야 한다.

/*

assertFalse(X)

 X가 거짓인지를 조사한다. assertTrue와 정 반대의 메소드

 X는 boolean형태의 값이어야 한다

/*

 

 

assertNotNull(Object X)

 X가 Null이 아닌지를 조사한다.

 만약 Null이라면 assertionFailedError가 발생한다.

/*

 assertNull(Object X)

 X가 Null인지를 조사한다. 

 만약 Null이 아니라면 assertionFailedError가 발생한다.

/*

assertSame (Object A, Object B)

 A와 B가 같은 객체인지를 조사한다.

 

 

이제 다시 JUNIT으로 돌아가서..

JUNIT을 하는 이유를 앞서 설명한 내용을 토대로 정리해서 말하자면~

학교에서하는 System.out.println("Hello World"); 이런 간단한 프로젝트가 아닌 장기적인, 거대한 프로젝트라면 개발 진행 중 프로그램에 대한 테스트가 필요합니다. 그럴때 보이지 않고 숨겨진 단위 테스트를 끌어내어 정형화 시켜 단위 테스트를 용이하게 해주는데 그게 바로 JUNIT입니다.

 

한줄정리 !!

JUNIT 은 자바 프로그래밍시 UNIT테스트를 쉽게 해주는 프레임워크 입니다.

 

출처 : http://blog.naver.com/ellay06/120169650178

'Java' 카테고리의 다른 글

[Java] JUnit 사용하기  (0) 2014.09.12
[Java] Virtual 함수( 가상함수)  (0) 2014.09.04
[Thread Pool] ThreadPoolExecutor  (0) 2012.09.06
Bing Translator API를 이용한 번역 - JAVA  (0) 2012.07.21
Java ::: cmd 명령어 실행법  (0) 2012.06.28
블로그 이미지

kuku_dass

,

출처 : http://blog.naver.com/ruo1022/110172566177

 

가상함수를 왜써요?

Up Casting

하위 클래스(자식, 부모보다 큰 타입) 에 상위 클래스(부모, 자식보다 작은 타입) 를 캐스팅 하는 것.

원칙적으론 불가능 하지만 상속관계에서는 가능. 다만 부모 포인터로는 자식의 기능(함수)를 사용할 수 없다.

ex)

CParent * m_parent  = new  CChild;

 

이 과정에서 자식 클래스의 함수를 호출하기위해 virtual 가상함수로 오버라이딩 해야 부모가 자식클래스의 함수에 접근 가능하다 .

 

cf) Down Casting

상위 클래스(부모, 자식보다 작은 타입) 에 하위 클래스(자식, 부모보다 큰 타입)를 캐스팅 하는 것.

원칙적으로 가능함. 보통 Up Casting 을 되돌려서 부모에겐 없고 자식에게만 있는 함수를 쓰기위해 부모타입 포인터를

자식타입으로 바꿀 때 사용함.

ex)

CParent * m_pParent  = new  CChild;

(CChild *)m_pParent -> OnlyChildFuntion();

가상함수의 정의방식

부모에서 virtual 을 한번만 정의하면 해당 함수는 상속과정 내내 virtual 이지만 명시적 표현, 가독성을 위해서 자식에서 정의할때도

되도록 virtual 함수는 virtual 키워드를 붙여주는게 좋다.

 

가상함수의 호출방식

만약 부모로 부터 virtual 함수가 계속 상속되었지만 해당 함수가 최하위 단계에 정의가 안되어있다면,

virtual 함수는 내려갈 수 있는 최대까지 내려가서 호출됨.

 

가상함수 테이블이란?

virtual 함수가 정의된 클래스 인스턴스(메모리할당) 시 가상함수 포인터 배열이 클래스 최전방 메모리 영역에 잡힌다.

즉 가상함수 테이블의 크기는 가상함수 갯수에 비례한다.

그리고 클래스는 이 가상함수 포인터 배열을 가리키는 포인터(4byte) 가  추가적으로 잡힌다.

 

여기에 가상함수들의 주소들이 등록되며, 각 클래스단위로 그 가상함수 테이블을 공유함.

부모 클래스 포인터 타입에 자식포인터를 집어넣으면 실제 저장된 데이터인 자식클래스의 가상함수테이블을 찾아간다.

 

순수 가상함수

순수 가상함수를 가지고 있는 함수는 추상 클래스이며 인스턴스(메모리 할당)을 받을 수 없는 객체이다.

ex) virtual  void  OutPut(void) = 0;

 

사용용도

1. 자식 클래스에게 상속만 제공하는 인터페이스 용도 클래스

2. 순수 가상함수를 이용할 경우, 순수가상함수는 일단 테이블에서 제외 되므로(정의가 안되어있으므로)

   자식클래스의 함수로 접근하는 속도면에서도 빠르다.

 

가상함수의 함수호출속도

inline 함수(매크로와 비슷한 함수)

static 함수(정적 함수)

Data 영역에 잡히는 함수

지역함수

순수가상함수(부모영역에서 호출이 없이 건너뛰므로 바로 자식쪽 호출)

가상함수(가장 느리지만 편의성이 쩐다.)

 

가상함수의 호출 속도가 느린 이유는, 실제 호출된 함수를 찾으려면 해당 클래스의 가상함수 테이블을

찾아야 하는데, 이 찾는 과정이 클래스명 문자열 비교과정이라는 것이다.

최악의 경우 상속계층 바닥까지 찾아가서 호출된 실제 클래스를 찾는 경우가 발생한다는 것.

이렇게 찾은 클래스의 가상함수 테이블을 참조하여 또 다시 함수를 찾고, 이 함수를 호출한다.

 


 

 

순수가상함수의 상속

부모가 순수가상함수를 가지고 있으면 자식도 순수가상함수를 물려받음.

따라서 사용하려는 시점의 자식클래스는 순수가상함수를 가상함수로 오버라이딩해서

사용하면 됨

 

가상소멸자

UpCasting 시에 소멸자 호출시 부모포인터로 소멸자를 접근하게 되면 클래스 자체는 메모리 해제되나

자식 영역의 소멸자를 호출하지 못하여 해제하지 못하는 메모리가 생겨난다.

따라서 가상 소멸자를 통해서 자식부터 쭉 소멸자 호출이 되도록 한다.

 

가상 함수의 동적 바인딩

컴파일 시 링커 구간에서 함수가 어디로 쓸지 연결되는 과정

가상함수를 쓰게되면 컴파일 중에 어떤 함수를 쓸지 알수없게 됨.

컴파일 시점에 함수 호출지점이 결정되는 것 - 함수의 정적 바인딩

파일 실행 후에 함수 호출지점이 결정되는 것 - 함수의 동적 바인딩

 

 

결론적으로 가상함수를 왜쓰냐

 개인적인 의견을 적어보자면, 굉장히 편리하다는 것이다. 어떤점이?

일단 부모포인터 타입으로 일괄적으로 함수에 접근이 가능하다.

이말은 일일이 다운캐스팅 하여 자식클래스의 함수를 호출하지 않아도 된다는 것이다.

이것만 해도 엄청나게 지저분해 질 수 있는 코드량을 획기적으로 줄일 수 있다.

 

 특정 객체타입을 관리하기 편리하다.

가령 게임상에서 존재하는 모든 객체들을 GameObject 라는 클래스를 상속받아서 구현했다면,

해당 객체들을 최상위 부모타입인 GameObject* 타입으로 관리가 가능하다.

공통적으로 사용할 기능들을 가상함수로 정의하고, 호출하면 각 객체별로 자신만의 기능을 수행 할테니

이 얼마나 편리한가.

 

'Java' 카테고리의 다른 글

[Java] JUnit 사용하기  (0) 2014.09.12
[Java] J Unit 이란?  (0) 2014.09.11
[Thread Pool] ThreadPoolExecutor  (0) 2012.09.06
Bing Translator API를 이용한 번역 - JAVA  (0) 2012.07.21
Java ::: cmd 명령어 실행법  (0) 2012.06.28
블로그 이미지

kuku_dass

,

ThreadPoolExecutor 를 사용한 샘플코드이다.


import java.util.concurrent.ArrayBlockingQueue;

import java.util.concurrent.RejectedExecutionException;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;


public class MyThreadPoolExecutor {

int corePoolSize = 1; // 스레드 풀은 실행할 작업이 없어도 corePoolSize 를 유지한다.

int maxPoolSize = 10;// xaximumPoolsize 는 동시에 얼마나 많은 개수의 스레드가 동작할 수 있는지를 제한하는 최대값.

long keepAliveTime = 10;

// keepAliveTime 는 스레드 유지 시간으로 스레드가 keepAliveTime 이상 대기하고 있으면

// 해당 스레드는 제거 될 수 있음. 풀의 스레드 개수가 corePoolSize 를 넘어서면 제거될 수 있음.

int queueSize = 10;

ThreadPoolExecutor threadPool = null;

final ArrayBlockingQueue<Runnable> queue = 

new ArrayBlockingQueue<Runnable>(queueSize);

public MyThreadPoolExecutor(){

threadPool = new ThreadPoolExecutor(corePoolSize,maxPoolSize,

keepAliveTime, TimeUnit.SECONDS, queue);

threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

  • ABORT : AbortPolicy 적용. rejection-policy가 정의되지 않았을 경우 기본 적용되는 Policy로 Exception을 throw한다.(default이다. 스레드를 호출한 곳에서 직접 예외처리를 해줘야한다.)

  • CALLER_RUNS : CallerRunsPolicy 적용. 해당 Application이 과부하 상태일 경우 TaskExecutor에 의해서가 아닌 Thread에서 직접 Task를 실행시킬 수 있게 한다.

  • DISCARD : DiscardPolicy 적용. 모든 Task가 반드시 실행되어야 한다라는 제약점이 없는 경우 적용 가능한 Policy로써 해당 Application이 과부하 상태일 경우 현재 Task의 실행을 Skip한다.

  • DISCARD_OLDEST : DiscardOldestPolicy 적용. 모든 Task가 반드시 실행되어야 한다라는 제약점이 없는 경우 적용 가능한 Policy로써 해당 Application이 과부하 상태일 경우 Queue의 Head에 있는 Task의 실행을 Skip한다.


}//end of constructor().

public void runTask(Runnable task){

try{

threadPool.execute(task);

}catch(RejectedExecutionException e){

return;

}

}

public void shutDown(){

threadPool.shutdown();

}

}//end of MyThreadPoolExecutor().

'Java' 카테고리의 다른 글

[Java] JUnit 사용하기  (0) 2014.09.12
[Java] J Unit 이란?  (0) 2014.09.11
[Java] Virtual 함수( 가상함수)  (0) 2014.09.04
Bing Translator API를 이용한 번역 - JAVA  (0) 2012.07.21
Java ::: cmd 명령어 실행법  (0) 2012.06.28
블로그 이미지

kuku_dass

,

boatmeme-microsoft-translator-java-api-v0.6.1-3-ga08e7c6.zip   : 관련 소스 코드 전체

microsoft-translator-java-api-0.6.1-jar-with-dependencies.jar         : 번역 부분 소스 코드


번역 API 를 이용한 안드로이드 번역 어플리케이션 개발을 위해 공부중에

구글 번역 API는 유료화 문제로 서비스를 이용할 수 없음을 발견.


그 대안으로 Microsoft Bing Translator API를 발견하였으나.. 한글 자료가 많지 않음.


결국 아래의 자바 소스코드를 찾음.


http://code.google.com/p/microsoft-translator-java-api/

'Java' 카테고리의 다른 글

[Java] JUnit 사용하기  (0) 2014.09.12
[Java] J Unit 이란?  (0) 2014.09.11
[Java] Virtual 함수( 가상함수)  (0) 2014.09.04
[Thread Pool] ThreadPoolExecutor  (0) 2012.09.06
Java ::: cmd 명령어 실행법  (0) 2012.06.28
블로그 이미지

kuku_dass

,

 


::: JAVA의 Runtime 클래스 exec()를 활용.

 

package org;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test
{
  public static void main(String[] args)
  {
    Runtime rt = Runtime.getRuntime();
    Process p;
    try {
      p = rt.exec("cmd /c chcp 437 & " + "ping 192.168.0.28");
      InputStream in = p.getInputStream();
      InputStreamReader isr = new InputStreamReader(in);
      System.out.println(isr.getEncoding());
      BufferedReader br = new BufferedReader(isr);
      String line;
      while ((line = br.readLine()) != null) {
        System.out.println(line);
      }
      in.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

##  참고

   

    :::  java.io.IOException: Cannot run program "chcp": CreateProcess error=2, ??d?? Æ???; ?; ¼? ¾ø 발생시

    --  권한 문제입니다. 명령어 앞에 "cmd /c " 를 삽입하면 간단히 해결 가능합니다.

 

 

    :::  명령어 동시에 여러개 실행시키기.

    --  프롬프트창(cmd.exe) 혹은  java .. exec();  둘다 무관하게

         명령어를 동시에 실행 시키고자 한다면 '명령어 & 명령어' 를 사용합니다.

         자세한 내용은 소스를 참조 바랍니다.








  [출처] Java ::: cmd 명령어 실행법|작성자 뽕이  http://bg_ellder.blog.me/121044097

'Java' 카테고리의 다른 글

[Java] JUnit 사용하기  (0) 2014.09.12
[Java] J Unit 이란?  (0) 2014.09.11
[Java] Virtual 함수( 가상함수)  (0) 2014.09.04
[Thread Pool] ThreadPoolExecutor  (0) 2012.09.06
Bing Translator API를 이용한 번역 - JAVA  (0) 2012.07.21
블로그 이미지

kuku_dass

,