SlideShare a Scribd company logo
Cygnus Unit Test
전략개발팀 박성재
Agenda
• Test?
• TDD
• Database Test
• Service Tier Test
• Web Tier Test
• Test Coverage
인수 테스트
스트레스 / 부하 테스트
기능 테스트
통합 테스트
테스트 종류
유닛 테스트
테스트 종류
• 유닛 테스트 - 작성이 쉽다 , 로직의 버그와 디자인
문제 ( 단일 책임 원칙 , 하드 코딩 ) 를 찾는다
• 통합 테스트 – 객체 간 , 서비스 간 , 서브 시스템
간 상호 작용 테스트
• 기능 테스트 – 공개된 api 의 가장 바깥 부분 테스
트 , 유스케이스 단위 테스트
• 스트레스 테스트 – jMeter 등의 전용 도구 이용
• 인수 테스트 – 개발자가 아닌 고객 혹은 QA 에서 진
행
Mockito
Tapestry Test
Test 관련 Tools
Spring Test
유닛 테스트
“ 유닛 테스트 (unit test) 는 소스 코드가
의도된 대로 정확히 작동하는지 검증하
는 절차다 . 즉 , 모든 클래스와 메소드
에 대한 테스트 케이스를 작성하는 절차
를 말한다 .”
wikipedia.org
Why Unit Test
• 디버깅은 많은 시간을 소비하고 싶지 않
아
• 새로운 기능 추가나 리팩토링 후 기존
기능들이 잘 동작하는지 확신하고 싶어
• 테스트 코드를 읽고 class 의 동작을 명
확하게 이해할 수 있지
• 유닛 테스트를 통해 프로젝트 헬스와 코
드 퀄리티를 측정할 수 있거든
Why not Unit Test
• 난 절대 실수 하지 않아
• 기능이 너무 단순해
• 테스트 코드까지 만들 시간이 없어
• 테스트 하는 방법을 몰라 ㅠㅠ
유닛 테스트 특징
• Isolated
– 타이어 테스트 할 때 자동차까지 만들지 말자
• Repeatable
– 모든 개발자에서 테스트 가능
– 환경에 영향 받지 않게
• Fast
– 시간은 돈이다 .
– 쉽고 빠르게 테스트 코드를 만들 수 있어야 한다
• Self-Documenting
– 테스트 코드는 단순해서 이해하기 쉬워야 한다
– 테스트 코드를 설명하는 문서가 필요 없어야 한다
First Unit Test
Public class Calculator {
public double add(double number1, double number2) {
return number1 + number2;
}
}
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculatorTest {  1.public class
@Test  2.unit test
public void test() {
Calculator calc = new Calculator();
double result = calc.add(10, 20);  3. 대상메소드콜
assertEquals(30, result, 0);  4. 결과 확인
}
}
First Unit Test 실행
Test Driven
Development(TDD)
“ 좋은 코드는 테스트하기 쉽다 . 그 반대
도 마찬가지다 .”
Cygnus Tier Flow
CreateServer
ServerServic
e
ServerDao
saveServer(server)
saveServer(server)
doSomething(server)
session.save(server)
ViewServer
ServerServic
e
ServerDao
getServerById(id)
getServerById(id)
session.get(Server.class, id
http://.../viewserver/{id}
Server
Web Tier :
Service Tier :
Dao Tier :
Persistent Tier :
Database Test 어려움
• Isolated
– DB 는 외부에 있다
• Repeatable
– Test 할 때마다 DB 가 변경된다
• Fast
– DB 접속은 상대적으로 느리다
– DB 접속 코드는 복잡하고 어렵다
• 초기 데이터 입력
• 평가 코드 작성
Database Test 전략
• Embedded DB(H2, HSQL) 사용
– Fast
– 개발자 별로 독립적 실행 가능
• DbUnit 사용
– 테스트 코드 작성 용이
– 쉬운 초기 데이터 셋팅
– 쉬운 평가 방법 제공
Database Test 대상
• 클래스와 테이블간 맵핑 오류
– DB 예약어 사용 예 )user, index, unique,
max
– 제품 DB 변경 시 활용
• 테이블 릴레이션
– one-to-many 등에서 이상한 forign 키 관계
가 없는지 ?
– Cascade 가 잘 동작하는지 ?
• 조회 쿼리
– 단일 객체 반환을 원하는데 복수 객체가 리턴
되지 않는지 ?
Database Test Code
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/META-INF/spring/test-applicationContext.xml")
@Transactional
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class
,
TransactionDbUnitTestExecutionListener.class,
DbUnitTestExecutionListener.class })
public class ServerDaoTest {
@Test
@DatabaseSetup("testServer.xml") 1. 초기 데이터
@ExpectedDatabase(value="empty.xml", 2. 기대 데이터 검증
assertionMode=DatabaseAssertionMode.NON_STRICT)
public void testDeleteServer() {
Server server = serverDao.getById(1);
serverDao.delete(server); 3. 테스트 대상
serverDao.flush(); 4. ORM 캐시 비우기
assertThat(serverDao.findAll().size(), is(0)); 5. delete 검증
}
Service 계층 Test 어려움
• Isolated
– 다른 서비스 / 계층 (DAO) 이 연관되어 있다
– 다른 시스템 (Agent, Mail Server, REST)
과 연관되어 있다
• Repeatable
– Test 할 때마다 모든 환경을 구축하기 어렵
다
• Fast
– 테스트 코드 작성시 많은 노력이 필요하다
Service 계층 Test 전략
• Stub 객체 작성
– Stub 이란 실제 대상과 유사하게 동작하는
객체 (Agent 시뮬레이터 )
– 동작 방식을 stub 객체에 코딩한다
– Stub 제작의 어려움이 남아 있다
• Mock 객체 이용
– Mock 이란 실제 객체와 유사한 동작을 하지
만 시키는
Service 계층 Test 전략
• Mock 객체 이용
– Mock 이란 실제 객체를 흉내내는 객체
– 동작 방식은 외부에서 알려준다 .
– Mock Framework 활용한 손쉬운 작성
• Mockito, EasyMock, Jmock
Service 계층 Test 코드
@Service
public class ServerServiceImpl implements ServerService {
@Autowired
ServerDao serverDao;
@Transactional
public Server discoveryServer(String ipAddress) {
Server server = serverDao.findServerByIpAddress(ipAddress);
if(server != null) {
throw new ServerDuplicatedException("Duplicated ipAddres=" + ipAddress);
}
Server newServer = new Server();
newServer.setIpAddress(ipAddress);
serverDao.save(newServer);
return newServer;
}
Service 계층 Test 코드
@RunWith(MockitoJUnitRunner.class)  1. mockito 러너 사용
public class ServerServiceTest {
@InjectMocks  2. mock 주입
ServerService serverService = new ServerServiceImpl();
@Mock  3. mock 객체 생성
ServerDao serverDao;
@Test
public void testDiscoveryServer() {
String ipAddress = "127.0.0.1";
//stub 4. mock 동작 정의
when(serverDao.findServerByIpAddress(ipAddress)).thenReturn(null);
//run
Server server=serverService.discoveryServer(ipAddress);  5. 대상 메소드 실행
//assert
assertThat(server.getIpAddress(), equalTo(ipAddress));  6. 메소드 리턴 결과 판
정
verify(serverDao).findServerByIpAddress(ipAddress);  7. mock 호출 여부 확인
verify(serverDao).save(server);  8. mock 호출 여부 확인
}
Service 계층 Test 코드
@Test(expected=ServerDuplicatedException.class)  1. 예외 기대 및 판정
public void testDiscoveryServerDuplicated() {
String ipAddress = "127.0.0.1";
Server existServer = new Server();
when(serverDao.findServerByIpAddress(ipAddress)).thenReturn(existServer);  2.
mock 동작
Server server = serverService.discoveryServer(ipAddress);  3. 테스트 메
소드 실행
}
Web 계층 test 어려움
• 컴파일 타임에 문법 오류를 잡을 수 없다
– template 파일 , javascript 등
• 페이지 / 컴포넌트간 링크가 잘 동작하는 테
스트기 어렵다
• 국제화나 validate 등의 리소스 버그를 테
스트 하기 어렵다
• Isolate
– 서비스 계층이 구현되지 않은 경우 테스트가
어렵다
• Fast
– 웹 어플리케이션 기동 후 육안 검사에 의존
Web 계층 테스트 전략
• 서비스 계층을 mock 객체로 활용
• Tapestry Test framework 활용
– PageTester.renderPage()
– PageTester.clickLink()
• Selenium 테스트 도입
Web 계층 테스트 코드
public class ViewServerTest {
PageTester tester;
@Before  1. test setUp
public void setUp() {
String appPackage = "com.nkia.cygnus.management.server";
String appName = "development";
tester = new PageTester(appPackage, appName, "src/main/webapp",
TestAppModule.class);
}
@Test
public void testExistServer() {
ServerService serverService = tester.getService(ServerService.class);  2.
MockServerServic
when(serverService.getServerById(1)).thenReturn(newServer());  3. Mock 동
작 정의
Document doc = tester.renderPage("server/ViewServer/1");  4. 대상 페이지 렌더링
assertThat(doc.toString(),
containsString("View Server - testserver123456"));  4. 정상 여부
판정
Web 계층 테스트 코드
// link test
@Test
public void testDeleteNotExistServer() {
ServerService serverService = tester.getService(ServerService.class);  1. Mock
객체
when(serverService.findServersAll()).thenReturn(newServerList());  2. Mock 동
작 정의
when(serverService.getServerById(1)).thenReturn(null);
Document doc = tester.renderPage("server/ServerPage");  3. page rendering
Element delete = doc.getElementById("delete");  4. link 객체 얻기
assertThat(delete, notNullValue());  5. link 존재 검증
Document linkDoc = tester.clickLink(delete);  5. link 클릭
assertThat(linkDoc.toString(),
containsString("Server not found. id = 1"));  5. link 동작
검증
}
Test 커버리지 보고서
• 소스의 단위 테스트 커버리지 측정
• Cobertura 활용
• 테스트 커버리지 기준을 만들고 일정 수준
이 되어야 만 릴리즈 할 수 있는 정책 가능
– http://cms.nkia.net:8088/projects/cygnus/cygnu
• 클래스 복잡도 측정 - McCabe's
cyclomatic complexity) 
– http://blog.wisedog.net/110

More Related Content

What's hot

지속적인 통합
지속적인 통합지속적인 통합
지속적인 통합
중선 곽
 
Springmvc
SpringmvcSpringmvc
Springmvc
HyungKuIm
 
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
Ji-Woong Choi
 
okspring3x
okspring3xokspring3x
okspring3x
Kenu, GwangNam Heo
 
Spring boot 5장 cli
Spring boot 5장 cliSpring boot 5장 cli
Spring boot 5장 cli
Choonghyun Yang
 
[오픈소스컨설팅]Spring 3.1 Core
[오픈소스컨설팅]Spring 3.1 Core [오픈소스컨설팅]Spring 3.1 Core
[오픈소스컨설팅]Spring 3.1 Core
Ji-Woong Choi
 
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build LifecycleBackend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
Kyunghun Jeon
 
Spring boot 공작소(1-4장)
Spring boot 공작소(1-4장)Spring boot 공작소(1-4장)
Spring boot 공작소(1-4장)
Choonghyun Yang
 
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
ymtech
 
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
중선 곽
 
bamboo 로 PHP 프로젝트 지속적인 배포
bamboo 로 PHP 프로젝트 지속적인 배포bamboo 로 PHP 프로젝트 지속적인 배포
bamboo 로 PHP 프로젝트 지속적인 배포
KwangSeob Jeong
 
Tomcat monitoring using_javamelody
Tomcat monitoring using_javamelodyTomcat monitoring using_javamelody
Tomcat monitoring using_javamelody
중선 곽
 
오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5
Taegon Kim
 
iOS9 소개
iOS9 소개iOS9 소개
iOS9 소개
Jae Sung Park
 
Spring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodeSpring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCode
dpTablo
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙
Hong Hyo Sang
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
DK Lee
 
Universal Rendering
Universal RenderingUniversal Rendering
Universal Rendering
Taegon Kim
 
우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈
용근 권
 
Spring boot-summary(part2-part3)
Spring boot-summary(part2-part3)Spring boot-summary(part2-part3)
Spring boot-summary(part2-part3)
Jaesup Kwak
 

What's hot (20)

지속적인 통합
지속적인 통합지속적인 통합
지속적인 통합
 
Springmvc
SpringmvcSpringmvc
Springmvc
 
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
[오픈소스컨설팅]Gradle Basic - How to use Gradle in Java Project
 
okspring3x
okspring3xokspring3x
okspring3x
 
Spring boot 5장 cli
Spring boot 5장 cliSpring boot 5장 cli
Spring boot 5장 cli
 
[오픈소스컨설팅]Spring 3.1 Core
[오픈소스컨설팅]Spring 3.1 Core [오픈소스컨설팅]Spring 3.1 Core
[오픈소스컨설팅]Spring 3.1 Core
 
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build LifecycleBackend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
Backend Master | 3.1.4 Build - Java build tool - Maven/Gradle Build Lifecycle
 
Spring boot 공작소(1-4장)
Spring boot 공작소(1-4장)Spring boot 공작소(1-4장)
Spring boot 공작소(1-4장)
 
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
20170310 tech day-1st-maven을 이용한 프로그램 빌드-박준홍
 
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
오픈소스 프레임워크 기반 웹 서비스 설계 (Example)
 
bamboo 로 PHP 프로젝트 지속적인 배포
bamboo 로 PHP 프로젝트 지속적인 배포bamboo 로 PHP 프로젝트 지속적인 배포
bamboo 로 PHP 프로젝트 지속적인 배포
 
Tomcat monitoring using_javamelody
Tomcat monitoring using_javamelodyTomcat monitoring using_javamelody
Tomcat monitoring using_javamelody
 
오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5
 
iOS9 소개
iOS9 소개iOS9 소개
iOS9 소개
 
Spring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodeSpring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCode
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
 
Universal Rendering
Universal RenderingUniversal Rendering
Universal Rendering
 
우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈
 
Spring boot-summary(part2-part3)
Spring boot-summary(part2-part3)Spring boot-summary(part2-part3)
Spring boot-summary(part2-part3)
 

Similar to Cygnus unit test

Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
beom kyun choi
 
아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a
Choonghyun Yang
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
Wonchang Song
 
Tdd
TddTdd
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
SangIn Choung
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
영석 조
 
X unittestpattern 1장_아꿈사
X unittestpattern 1장_아꿈사X unittestpattern 1장_아꿈사
X unittestpattern 1장_아꿈사효원 강
 
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
asfasf4
 
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
SangIn Choung
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Javajigi Jaesung
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
ChangHyeon Bae
 
01.개발환경 교육교재
01.개발환경 교육교재01.개발환경 교육교재
01.개발환경 교육교재
Hankyo
 
구글테스트
구글테스트구글테스트
구글테스트
진화 손
 
Android unit testing
Android unit testingAndroid unit testing
Android unit testing
Hyeoungkyu Chang
 
효율적인 개발 프로세스를 위한 지속적 통합
효율적인 개발 프로세스를 위한 지속적 통합효율적인 개발 프로세스를 위한 지속적 통합
효율적인 개발 프로세스를 위한 지속적 통합
홍렬 임
 
ParameterizedTest 와 ContextCaching.pptx
ParameterizedTest 와 ContextCaching.pptxParameterizedTest 와 ContextCaching.pptx
ParameterizedTest 와 ContextCaching.pptx
junu6
 
Spring test mvc 발표자료
Spring test mvc 발표자료Spring test mvc 발표자료
Spring test mvc 발표자료수홍 이
 
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
DK Lee
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례
SangIn Choung
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Daum DNA
 

Similar to Cygnus unit test (20)

Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
Tdd
TddTdd
Tdd
 
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
 
X unittestpattern 1장_아꿈사
X unittestpattern 1장_아꿈사X unittestpattern 1장_아꿈사
X unittestpattern 1장_아꿈사
 
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
回国去哪买毕业证办迪肯大学毕业证Deakin毕业证书【Q微202-661-4433】 Deakin售澳洲毕业证原版新毕业证书出售各国毕业证买澳洲毕业证的价...
 
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
[기본과정] 코드 테스트와 커버리지 기본 교육(개념)
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
01.개발환경 교육교재
01.개발환경 교육교재01.개발환경 교육교재
01.개발환경 교육교재
 
구글테스트
구글테스트구글테스트
구글테스트
 
Android unit testing
Android unit testingAndroid unit testing
Android unit testing
 
효율적인 개발 프로세스를 위한 지속적 통합
효율적인 개발 프로세스를 위한 지속적 통합효율적인 개발 프로세스를 위한 지속적 통합
효율적인 개발 프로세스를 위한 지속적 통합
 
ParameterizedTest 와 ContextCaching.pptx
ParameterizedTest 와 ContextCaching.pptxParameterizedTest 와 ContextCaching.pptx
ParameterizedTest 와 ContextCaching.pptx
 
Spring test mvc 발표자료
Spring test mvc 발표자료Spring test mvc 발표자료
Spring test mvc 발표자료
 
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
 

Cygnus unit test

  • 2. Agenda • Test? • TDD • Database Test • Service Tier Test • Web Tier Test • Test Coverage
  • 3. 인수 테스트 스트레스 / 부하 테스트 기능 테스트 통합 테스트 테스트 종류 유닛 테스트
  • 4. 테스트 종류 • 유닛 테스트 - 작성이 쉽다 , 로직의 버그와 디자인 문제 ( 단일 책임 원칙 , 하드 코딩 ) 를 찾는다 • 통합 테스트 – 객체 간 , 서비스 간 , 서브 시스템 간 상호 작용 테스트 • 기능 테스트 – 공개된 api 의 가장 바깥 부분 테스 트 , 유스케이스 단위 테스트 • 스트레스 테스트 – jMeter 등의 전용 도구 이용 • 인수 테스트 – 개발자가 아닌 고객 혹은 QA 에서 진 행
  • 6. 유닛 테스트 “ 유닛 테스트 (unit test) 는 소스 코드가 의도된 대로 정확히 작동하는지 검증하 는 절차다 . 즉 , 모든 클래스와 메소드 에 대한 테스트 케이스를 작성하는 절차 를 말한다 .” wikipedia.org
  • 7. Why Unit Test • 디버깅은 많은 시간을 소비하고 싶지 않 아 • 새로운 기능 추가나 리팩토링 후 기존 기능들이 잘 동작하는지 확신하고 싶어 • 테스트 코드를 읽고 class 의 동작을 명 확하게 이해할 수 있지 • 유닛 테스트를 통해 프로젝트 헬스와 코 드 퀄리티를 측정할 수 있거든
  • 8.
  • 9. Why not Unit Test • 난 절대 실수 하지 않아 • 기능이 너무 단순해 • 테스트 코드까지 만들 시간이 없어 • 테스트 하는 방법을 몰라 ㅠㅠ
  • 10. 유닛 테스트 특징 • Isolated – 타이어 테스트 할 때 자동차까지 만들지 말자 • Repeatable – 모든 개발자에서 테스트 가능 – 환경에 영향 받지 않게 • Fast – 시간은 돈이다 . – 쉽고 빠르게 테스트 코드를 만들 수 있어야 한다 • Self-Documenting – 테스트 코드는 단순해서 이해하기 쉬워야 한다 – 테스트 코드를 설명하는 문서가 필요 없어야 한다
  • 11. First Unit Test Public class Calculator { public double add(double number1, double number2) { return number1 + number2; } } import static org.junit.Assert.*; import org.junit.Test; public class CalculatorTest {  1.public class @Test  2.unit test public void test() { Calculator calc = new Calculator(); double result = calc.add(10, 20);  3. 대상메소드콜 assertEquals(30, result, 0);  4. 결과 확인 } }
  • 12. First Unit Test 실행
  • 13. Test Driven Development(TDD) “ 좋은 코드는 테스트하기 쉽다 . 그 반대 도 마찬가지다 .”
  • 14.
  • 15.
  • 16.
  • 17.
  • 19. Database Test 어려움 • Isolated – DB 는 외부에 있다 • Repeatable – Test 할 때마다 DB 가 변경된다 • Fast – DB 접속은 상대적으로 느리다 – DB 접속 코드는 복잡하고 어렵다 • 초기 데이터 입력 • 평가 코드 작성
  • 20. Database Test 전략 • Embedded DB(H2, HSQL) 사용 – Fast – 개발자 별로 독립적 실행 가능 • DbUnit 사용 – 테스트 코드 작성 용이 – 쉬운 초기 데이터 셋팅 – 쉬운 평가 방법 제공
  • 21. Database Test 대상 • 클래스와 테이블간 맵핑 오류 – DB 예약어 사용 예 )user, index, unique, max – 제품 DB 변경 시 활용 • 테이블 릴레이션 – one-to-many 등에서 이상한 forign 키 관계 가 없는지 ? – Cascade 가 잘 동작하는지 ? • 조회 쿼리 – 단일 객체 반환을 원하는데 복수 객체가 리턴 되지 않는지 ?
  • 22. Database Test Code @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/META-INF/spring/test-applicationContext.xml") @Transactional @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class , TransactionDbUnitTestExecutionListener.class, DbUnitTestExecutionListener.class }) public class ServerDaoTest { @Test @DatabaseSetup("testServer.xml") 1. 초기 데이터 @ExpectedDatabase(value="empty.xml", 2. 기대 데이터 검증 assertionMode=DatabaseAssertionMode.NON_STRICT) public void testDeleteServer() { Server server = serverDao.getById(1); serverDao.delete(server); 3. 테스트 대상 serverDao.flush(); 4. ORM 캐시 비우기 assertThat(serverDao.findAll().size(), is(0)); 5. delete 검증 }
  • 23. Service 계층 Test 어려움 • Isolated – 다른 서비스 / 계층 (DAO) 이 연관되어 있다 – 다른 시스템 (Agent, Mail Server, REST) 과 연관되어 있다 • Repeatable – Test 할 때마다 모든 환경을 구축하기 어렵 다 • Fast – 테스트 코드 작성시 많은 노력이 필요하다
  • 24. Service 계층 Test 전략 • Stub 객체 작성 – Stub 이란 실제 대상과 유사하게 동작하는 객체 (Agent 시뮬레이터 ) – 동작 방식을 stub 객체에 코딩한다 – Stub 제작의 어려움이 남아 있다 • Mock 객체 이용 – Mock 이란 실제 객체와 유사한 동작을 하지 만 시키는
  • 25. Service 계층 Test 전략 • Mock 객체 이용 – Mock 이란 실제 객체를 흉내내는 객체 – 동작 방식은 외부에서 알려준다 . – Mock Framework 활용한 손쉬운 작성 • Mockito, EasyMock, Jmock
  • 26. Service 계층 Test 코드 @Service public class ServerServiceImpl implements ServerService { @Autowired ServerDao serverDao; @Transactional public Server discoveryServer(String ipAddress) { Server server = serverDao.findServerByIpAddress(ipAddress); if(server != null) { throw new ServerDuplicatedException("Duplicated ipAddres=" + ipAddress); } Server newServer = new Server(); newServer.setIpAddress(ipAddress); serverDao.save(newServer); return newServer; }
  • 27. Service 계층 Test 코드 @RunWith(MockitoJUnitRunner.class)  1. mockito 러너 사용 public class ServerServiceTest { @InjectMocks  2. mock 주입 ServerService serverService = new ServerServiceImpl(); @Mock  3. mock 객체 생성 ServerDao serverDao; @Test public void testDiscoveryServer() { String ipAddress = "127.0.0.1"; //stub 4. mock 동작 정의 when(serverDao.findServerByIpAddress(ipAddress)).thenReturn(null); //run Server server=serverService.discoveryServer(ipAddress);  5. 대상 메소드 실행 //assert assertThat(server.getIpAddress(), equalTo(ipAddress));  6. 메소드 리턴 결과 판 정 verify(serverDao).findServerByIpAddress(ipAddress);  7. mock 호출 여부 확인 verify(serverDao).save(server);  8. mock 호출 여부 확인 }
  • 28. Service 계층 Test 코드 @Test(expected=ServerDuplicatedException.class)  1. 예외 기대 및 판정 public void testDiscoveryServerDuplicated() { String ipAddress = "127.0.0.1"; Server existServer = new Server(); when(serverDao.findServerByIpAddress(ipAddress)).thenReturn(existServer);  2. mock 동작 Server server = serverService.discoveryServer(ipAddress);  3. 테스트 메 소드 실행 }
  • 29. Web 계층 test 어려움 • 컴파일 타임에 문법 오류를 잡을 수 없다 – template 파일 , javascript 등 • 페이지 / 컴포넌트간 링크가 잘 동작하는 테 스트기 어렵다 • 국제화나 validate 등의 리소스 버그를 테 스트 하기 어렵다 • Isolate – 서비스 계층이 구현되지 않은 경우 테스트가 어렵다 • Fast – 웹 어플리케이션 기동 후 육안 검사에 의존
  • 30. Web 계층 테스트 전략 • 서비스 계층을 mock 객체로 활용 • Tapestry Test framework 활용 – PageTester.renderPage() – PageTester.clickLink() • Selenium 테스트 도입
  • 31. Web 계층 테스트 코드 public class ViewServerTest { PageTester tester; @Before  1. test setUp public void setUp() { String appPackage = "com.nkia.cygnus.management.server"; String appName = "development"; tester = new PageTester(appPackage, appName, "src/main/webapp", TestAppModule.class); } @Test public void testExistServer() { ServerService serverService = tester.getService(ServerService.class);  2. MockServerServic when(serverService.getServerById(1)).thenReturn(newServer());  3. Mock 동 작 정의 Document doc = tester.renderPage("server/ViewServer/1");  4. 대상 페이지 렌더링 assertThat(doc.toString(), containsString("View Server - testserver123456"));  4. 정상 여부 판정
  • 32. Web 계층 테스트 코드 // link test @Test public void testDeleteNotExistServer() { ServerService serverService = tester.getService(ServerService.class);  1. Mock 객체 when(serverService.findServersAll()).thenReturn(newServerList());  2. Mock 동 작 정의 when(serverService.getServerById(1)).thenReturn(null); Document doc = tester.renderPage("server/ServerPage");  3. page rendering Element delete = doc.getElementById("delete");  4. link 객체 얻기 assertThat(delete, notNullValue());  5. link 존재 검증 Document linkDoc = tester.clickLink(delete);  5. link 클릭 assertThat(linkDoc.toString(), containsString("Server not found. id = 1"));  5. link 동작 검증 }
  • 33. Test 커버리지 보고서 • 소스의 단위 테스트 커버리지 측정 • Cobertura 활용 • 테스트 커버리지 기준을 만들고 일정 수준 이 되어야 만 릴리즈 할 수 있는 정책 가능 – http://cms.nkia.net:8088/projects/cygnus/cygnu • 클래스 복잡도 측정 - McCabe's cyclomatic complexity)  – http://blog.wisedog.net/110