Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
1. 지속적인 테스트
2. 테스트 분류
목차
3. xUnit
1. 지속적인 테스트
4 / 문서의 제목
컴포넌트 A(신뢰도 90%)
컴포넌트 B(신뢰도 90%)
컴포넌트 C(신뢰도 90%)
선형 시스템의 신뢰도
신뢰도 = 0.9 x 0.9 x 0.9 = 0.73
5 / 문서의 제목
신뢰할 수 있는 시스템
100%짜리(또는 그 정도에 가까운) 서비스 수준 계약서를
체결한 소프트웨어 어플리케이션을 만들고자 한다면,
반드시 개별 객체 수준에서 신뢰도를 보장해야만 할겁니다.
단위 테스트(Unit Test)
6 / 문서의 제목
신뢰할 수 있는 시스템
단위 테스트를 통한 객체 수준의 신뢰도 보장
객체가 이용되는 상황을 효과적으로 재현하는 테스트 케이스 구축
테스트를 자주 실행
시스템 내 변경사항 발생 시 언제라도 테스트 실행
지속적인 테스트
7 / 문서의 제목
자동화된 개발자 테스트 돌리기
피드백주기
소프트웨어품질을향상시키고위험을줄이기
| \ \
}]
{[
“‘ Integrate
?/
shift?/
P ㅖㅔ
통합하기
소스 코드컴파일하기
테스트돌리기
검사수행하기
소프트웨어배포하기
데이터베이스통합하기
8 / 문서의 제목
2. 테스트 분류
9 / 문서의 제목
테스트의 분류
단위 테스트
컴포넌트테스트
시스템테스트
• 소프트웨어 시스템 내의 작은 요소의 행동 검증
• 일반적으로 하나의 클래스를 테스트
기능테스트
• 소프트웨어 시스템의 일부를 테스트
•상호작용하는 컴포넌트들간의 행동 검증
• 외부 의존성 요구
완전히 설치된 시스템, DB, 파일 시스템, 네트워크 종점
• 단위 테스트보다 오래 걸림
• 전체 소프트웨어 시스템을 실행
• 완전히 설치된 시스템 요구
• 설치하는 시간이 길고 실행 시간도 김
• 테스트를 위한 설치 작업이 빌드의 일부로 포함
• 어플리케이션의 기능성을 클라이언트 관점에서 테스트
• 인수 테스트
10 / 문서의 제목
테스트의 분류
데이터베이스
서버 연동 시스템
사용자
사용자
사용자
11 / 문서의 제목
단위 테스트
데이터베이스
연동 시스템
사용자
사용자
사용자
서버
사용자
class
class
class
네트워크 케이블을 빼고 데이터베이스를 종료시키고 나서도 돌아
가는 테스트가 진짜 단위 테스트입니다
12 / 문서의 제목
컴포넌트 테스트
사용자
사용자
사용자
서버 연동 시스템
데이터베이스
컴포넌트 수준의 테스트는 API를 통해 코드를 수행하지만, 외부
클라이언트에 노출될 때도 있고, 그렇지 않을 수도 있습니다.
13 / 문서의 제목
시스템 테스트
사용자
사용자
사용자
서버 연동 시스템
데이터베이스
시스템 테스트는 웹 페이지, 웹 서비스 종점, GUI가 처음부터 끝까지
설계된 대로 작동하는지를 검증합니다.
14 / 문서의 제목
기능 테스트
사용자
사용자
사용자
서버 연동 시스템
데이터베이스
어플리케이션의 기능을 클라이언트 관점에서 테스트하는 것이며, 이는 테스트
자체가 클라이언트를 흉내 낸다는 뜻입니다.
15 / 문서의 제목
테스트의 분류
단위 테스트
컴포넌트테스트
시스템테스트
• 소프트웨어 시스템 내의 작은 요소의 행동 검증
• 일반적으로 하나의 클래스를 테스트
기능테스트
• 소프트웨어 시스템의 일부를 테스트
•상호작용하는 컴포넌트들간의 행동 검증
• 외부 의존성 요구
완전히 설치된 시스템, DB, 파일 시스템, 네트워크 종점
• 단위 테스트보다 오래 걸림
• 전체 소프트웨어 시스템을 실행
• 완전히 설치된 시스템 요구
• 설치하는 시간이 길고 실행 시간도 김
• 테스트를 위한 설치 작업이 빌드의 일부로 포함
• 어플리케이션의 기능성을 클라이언트 관점에서 테스트
• 인수 테스트
테스트에 필요한 설치 작업에 따라 테스트 분화
테스트 실행에 소요되는 시간과 직접적인 연관
테스트 범주화는 지속적인 통합 문맥 하에서 매우 중요
Feedback
시간이 덜 걸리는 테스트부터 실행
16 / 문서의 제목
개발자 테스트를 여러 범주로 나누기
Annotation
Test Suite 구성
디렉토리 분류
src/
pom.xml
main/
test/
java/
java/
unit/
component/
system/
project/
17 / 문서의 제목
개발자 테스트를 여러 범주로 나누기
Maven2 Profile 사용
<profiles>
<profile>
<id>junit</id>
<properties>
<deploy.phase>local</deploy.phase>
<settings.runEnv>test</settings.runEnv>
<maven.test.skip>false</maven.test.skip>
<log4j.runEnv>log4j.xml</log4j.runEnv>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
18 / 문서의 제목
3. xUnit
19 / 문서의 제목
JUnit
자바 프로그래밍 언어를 위한 단위 테스팅 프레임워크
By Kent Beck and Erich Gamma
Kent Beck의 SUnit 프레임워크로부터 유래
http://www.junit.org/
xUnit Family
PHPUnit (PHP)
NUnit (C#)
PyUnit (Python)
fUnit (Fortran)
Test::Class, Test::Unit (Perl)
CPPUnit (C++)
JSUnit (JavaScript)
유사 프레임워크
TestNG
Unit
20 / 문서의 제목
JUnit 3.x
이름 짓기 규약
testCreateAccount()testCreateAccDef()testCreateAcctDup()
createAccount()
TestAccount.java Account.java
Unit
21 / 문서의 제목
JUnit 3.x
단정 메소드assertTrue(boolean condition)
assertFalse(boolean condition)
assertEquals(Object expected, Object actual)Uses equals() comparison
Overloaded for all primitive types
assertSame(Object expected, Object actual)
assertNotSame(Object expected, Object actual)Uses == comparison
assertEquals(float expected, float actual, float tolerance)
assertNull(Object o)
assertNotNull(Object o)
fail(String message)
TestCase
MyTestCase
Unit
22 / 문서의 제목
JUnit 3.x
TestCase
MyTestCase
package org.eternity.common.money;
import junit.framework.TestCase;
public class FirstTestCase extends TestCase {
public FirstTestCase(String method) {
super(method);
}
public void testAdd() {
assertEquals(2, 1+1);
}
}
샘 플
Unit
23 / 문서의 제목
JUnit 3.x
public class DatabaseTestCase extends TestCase {
private Connection dbConn;
protected void setUp() {
dbConn = new Connection("oracle", 1521,
"fred", "foobar");
dbConn.connect();
}
protected void tearDown() {
dbConn.disconnect();
dbConn = null;
}
public void testAccountAccess() {
// dbConn 사용// ......
}
public void testEmployeeAccess() {
// dbConn 사용// ......
}
}
Test FixturesetUp()
testAccountAccess()
tearDown
setUp()
testEmployeeAccess()
tearDown()
Unit
24 / 문서의 제목
junit.framework
JUnit 3.x
Test Suite
<<interface>>
Test
TestCaseTestSuite
*
MyTestCase
Unit
25 / 문서의 제목
JUnit 3.x
package org.eternity.common.money;
import junit.framework.Test;import junit.framework.TestCase;import junit.framework.TestSuite;
public class SecondTestCase extends TestCase {public SecondTestCase(String method) {
super(method);}
public void testSubtract() {assertTrue(10-5 > 0);
}
public void testMultiply() {assertEquals(50, 10*5);
}
public void testDivide() {assertEquals(2, 10/5);
}
public static Test suite() {TestSuite suite = new TestSuite();suite.addTest(new SecondTestCase("testMultiply"));suite.addTest(new SecondTestCase("testDivide"));
return suite;}
}
Test Suite
Unit
26 / 문서의 제목
JUnit 3.x
Exception
public void testForException() {
try {
sortMyList(null);
fail("should have thrown an exception!");
} catch(NullPointerException ex) {
assertTrue(true);
}
}
Unit
27 / 문서의 제목
JUnit3에서 JUnit 4로
JUnit4는 Java 5 이상을 요구
junit.framework.TestCase를 상속하지 않는 독립 클래스로 작성
org.junit.*과 org.junit.Assert.*를 importorg.junit.Assert.*에 대해 static importTestCase로부터 상속 받지 않기 때문
명명규칙을따르는메소드대신 Annotation 사용@Test는 testXXX() 메소드대체@Before는 setUp() 메소드대체@After는 tearDown() 메소드대체
@+
Unit
28 / 문서의 제목
JUnit4
public class DatabaseTestCase {
private Connection dbConn;
@Before
protected void connectDB() {
dbConn = new Connection("oracle", 1521,
"fred", "foobar");
dbConn.connect();
}
@After
protected void closeDB() {
dbConn.disconnect();
dbConn = null;
}
@Test
public void checkAccountAccess() {
// dbConn 사용// ......
}
@Test
public void checkEmployeeAccess() {
// dbConn 사용// ......
}
}
Test FixtureconnectDB()
checkAccountAccess()
closeDB
connectDB()
checkEmployeeAccess()
closeDB()
Unit
29 / 문서의 제목
JUnit4
package org.eternity.common.money;
import junit.framework.Test;import junit.framework.TestCase;import junit.framework.TestSuite;
public class SecondTestCase extends TestCase {public SecondTestCase(String method) {
super(method);}
public void testSubtract() {assertTrue(10-5 > 0);
}
public void testMultiply() {assertEquals(50, 10*5);
}
public void testDivide() {assertEquals(2, 10/5);
}
public static Test suite() {TestSuite suite = new TestSuite();suite.addTest(new SecondTestCase("testMultiply"));suite.addTest(new SecondTestCase("testDivide"));
return suite;}
}
Test Suite
Unit
30 / 문서의 제목
JUnit4
package org.eternity.common.money;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({FirstTestCase.class,SecondTestCase.class})
public class SimpleTestSuite{
}
Test Suite
@RunWith, @SuiteClasses
Unit
31 / 문서의 제목
JUnit4
Exception
@Test(expected=NullPointerException.class)
public void checkNullParameterList() {
sortMyList(null);
}
Unit
32 / 문서의 제목
Mock Object
디버깅하기 위해 사용되는 실세계 객체의 대용물
Mock Object가 유용한 경우
진짜 객체가 비결정적인 동작을 할 경우
결과 예측이 어려운 경우
진짜 객체를 준비 설정하기 어려운 경우
진짜 객체자 직접 유발시키기 어려운 동작을 하는 경우
네트워크 에러
진짜 객체가 너무 느린 경우
진짜 객체가 UI를 가지거나, UI 자체인 경우
진짜 객체에게 그것이 어떻게 사용되는지 물어봐야 하는 경우
진짜 객체가 아직 존재하지 않는 경우
Unit
33 / 문서의 제목
Mock Object
Mock Object 구조
객체에 인터페이스 사용
인터페이스를 구현한 제품 코드
인터페이스를 구현한 모의 객체
Interface
MockObject
Unit
TestTarget
RealObject
34 / 문서의 제목
Mock Object
Behavior Verification
테스트 대상 객체가 다른 객체와의 협력 테스트
테스트 대상 객체가 협력 객체의 메소드를 정상적으로 호출하는지 여부 검증
Mock Object는 Behavioral Verification 기법
State Verification
기존의 JUnit 기반의 단위 테스트
대상 객체의 상태 변화 체크
Unit
MockObjectObject
http://martinfowler.com/articles/mocksArentStubs.html
Mocks Aren’t Stubs By Martin Fowler
정상적으로 호출하는지 테스트
35 / 문서의 제목
Mock Object
Mock Object를 실행 시간에 자동 생성
jMock
http://www.jmock.org/
EasyMock
http://www.easymock.org/
MockObject RealObject
Mock Object 자동 생성
Unit
TestCase TestTarget Interface
36 / 문서의 제목
Mock Object Unit
MockObject ArticleScrappable
ScrapableCafeScrapTest CafeScrap
게시물 스크랩Test 대상 객체 네트워크를 통해 게시글 전송
네트워크가 비정상적일 경우?
Dependency Problem
37 / 문서의 제목
Mock Object
jMock
@RunWith(JMock.class)
public class CafeScrapTest {
private Mockery context = new JUnit4Mockery();
private CafeScrap cafeScrap;
private Scrapable scrapable;
@Before
public void prepareCafeSrap() {
cafeScrap = new CafeScrap();
scrapable = context.mock(Scrapable.class);
cafeScrap.setScrappable(scrapable);
}
@Test
public void scrapToBlog() {
final Article article = new Article();
context.checking(new Expectations() {{
one(scrapable).scrap(article, Service.BLOG);
will(throwException(new BlogServerNotAvailableException()));
}});
assertFalse(cafeScrap.sendToBlog(article));
}
}
Expectation 설정
Behavior Verification
Scrapable 인터페이스를 구현한
Mock Object 생성
Unit
38 / 문서의 제목
Mock Object
EasyMock
public class CafeScrapTest {
private CafeScrap cafeScrap;
private Scrapable scrapable;
@Before
public void prepareCafeSrap() {
cafeScrap = new CafeScrap();
scrapable = EasyMock.createMock(Scrapable.class);
cafeScrap.setScrappable(scrapable);
}
@Test
public void scrapToBlog() {
Article article = new Article();
EasyMock.expect(scrapable.scrap(article, Service.BLOG))
.andThrow(new BlogServerNotAvailableException());
EasyMock.replay(scrapable);
assertFalse(cafeScrap.sendToBlog(article));
EasyMock.verify(scrapable);
}
}
Expectation 설정
Behavior Verification
Scrapable 인터페이스를 구현한
Mock Object 생성 후 테스트 객체에연결
행동 재생
행동 검증
Unit
39 / 문서의 제목
Spring Database Test Support
AbstractTransactionalSpringContextTests
org.springframework.test.AbstractTransactionalSpringContextTests
테스트 종료 후 데이터베이스 트랜잭션 롤백
getConfigLocations()스프링 빈 컨텍스트 위치 목록 반환
onSetUpBeforeTransaction()트랜잭션이 시작되기 전 호출
onSetUpInTransaction()트랜잭션이 시작된 후 호출
onTearDownInTransaction()트랜잭션이 롤백 되기 전에 호출
onTearDownAfterTransaction() 트랜잭션이 롤백된 후 호출
Component
40 / 문서의 제목
Spring Database Test Support
public abstract class CafeBaseTransactionalSpringContextTests extends AbstractTransactionalSpringContextTests {
private String[] getCommonConfigLocations() {return new String[] { ConfigLocations.TEST };
}
protected abstract String[] getModuleConfigLocations();
@Overrideprotected String[] getConfigLocations() {
String[] commonConfigs = getCommonConfigLocations();
String[] moduleConfigs = getModuleConfigLocations();
String[] configs = new String[commonConfigs.length + moduleConfigs.length];for (int i = 0; i < commonConfigs.length; i++) {
configs[i] = commonConfigs[i];}
for (int i = 0; i < moduleConfigs.length; i++) {int j = commonConfigs.length + i;configs[j] = moduleConfigs[i];
}
return configs;}
CafeBaseTransactionalSpringContextTests
Component
41 / 문서의 제목
@Override
protected void onSetUpBeforeTransaction() throws Exception {
ContextHolder.setAttribute(
CafeConstants.CONTEXTHOLDER_MULTIPLEDBKEY,
new MultipleDBKeyInfo(getMultipleDBKey(), true));
SqlMapPlugIn plugIn = new SqlMapPlugIn();
plugIn.init(null);
}
/**
* CLUBBBS나 CAFEINFO db를 사용하는 경우에는 무조건 이 메소드를 override해야 한다.
* @return
*/
protected Integer getMultipleDBKey() {
return null;
}
}
Spring Database Test Support
CafeBaseTransactionalSpringContextTests
Component
42 / 문서의 제목
Spring Database Test Support
Custom Test Case
public class TemplateMovieDAOImplTest
extends CafeBaseTransactionalSpringContextTests {
private TemplateMovieDAO templateMovieDAO;
private Integer TEST_CLUBID = 10141287;
@Override
protected String[] getModuleConfigLocations() {
return new String[]{ConfigLocations.DAO_BOARD,
ConfigLocations.TEST_CLUBBBS
};
}
protected Integer getMultipleDBKey() {
return TEST_CLUBID;
}
public void setTemplateMovieDAO(TemplateMovieDAO templateMovieDAO) {
this.templateMovieDAO = templateMovieDAO;
}
public void testSelect() {
// DAO를 사용한 테스트 코드// ......
}
/META-INF/applicationContext-common-dao-board.xml
/META-INF/applicationContext-common-test-clubbbs.xml
Component
43 / 문서의 제목
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="transactionManager"
class="com.naver.cafe.common.transaction.CafeTransactionManager">
<property name="dbKey">
<bean
id="com.naver.cafe.common.dao.DBKeyGenerator.DB_KEY_CLUBBBS"
class="org.springframework.beans.factory.config
.FieldRetrievingFactoryBean" />
</property>
</bean>
</beans>
Spring Database Test Support
Transaction Manager 설정
applicationContext-common-test-clubbbs.xml
clubbbs
conf/datasource/datasource-clubbbs.xml
Component
44 / 문서의 제목
DbUnit
데이터베이스 Component Testing 툴
테스트 간에 데이터베이스를 알려진 상태로 유지하기 위해 사용
테스트 데이터를 자동으로 데이터베이스에 입력
테스트 종료 후 테스트 이전으로 자동 복귀
http://www.dbunit.org/
DbUnit Best Practices
개발자 한 명 당 하나의 데이터베이스 인스턴스 사용
테스트를 정상적으로 설정한 경우 클린업 절차 불필요
하나의 거대한 데이터 셋 대신 여러 개의 작은 데이터 셋 사용
전체 테스트 클래스나 테스트 스위트에 대해 현행화된 데이터를 사용할 것
Component
45 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
초기화
테스트 코드
테스트 코드
테스트 코드
Component
46 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
테스트 코드
테스트 코드
테스트 코드
Component
47 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
테스트 코드
테스트 코드
테스트 코드
실행
데이터 변경
Component
48 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
테스트 코드
테스트 코드
테스트 코드
데이터베이스
복구
Component
49 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
초기화
테스트 코드
테스트 코드
테스트 코드
Component
50 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
테스트 코드
테스트 코드
테스트 코드
Component
51 / 문서의 제목
DbUnit
테스트 라이프 사이클
테스트 데이터
데이터베이스
테스트 코드
테스트 코드
테스트 코드
데이터 변경
Component
52 / 문서의 제목
DbUnit
Cafe 프로젝트용 DbUnit 커스터마이징
bridge 프로젝트의 com.naver.cafe.unit 패키지
다중 DB 지원
카페 DB별 테스트 데이터 초기화 기능 지원
전체 테이블이 아닌 결과 XML에 명시된 데이터만 검증 가능
,초기 데이터 PK를 사용하여 테스트 데이터 제거
MyTestCase
AbstractDependencyInjectionSpringContextTests
CafeTestCase
Component
53 / 문서의 제목
DbUnit
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<CLT_ARTICLE clubid="14446632" articleid="158" menuid="2" subject="제목"
content="테스트용 게시물" writerid="baejjae93" writernickname="baejjae93"
writedt="2008-02-14" refarticleid="14446632" replylistorder="“
readcount="0" commentcount="0" refarticlecount="0" lastcommentdate="[null]"
type="[null]" openyn="Y" replyyn="Y" scrapyn="Y"
attachimageyn="[null]" attachfileyn="[null]" attachpollyn="[null]"
attachmovie="0" scrapcount="0" scrapedyn="[null]" accesslevel="0"
personacon="0" font="" leveragecode="39" searchopen="1" rclick="0"
hastag="0" blockyn="0" modifydt="[null]" spamscore="0"
gdid="99999999_99999999999999999999999" headid="[null]“
blockstatus="[null]" ccl="0" autosourcing="0" templatecode="[null]"/>
<CFT_LEVERAGE_ARTICLE clubid="14446632" articleid="158" leveragecode="39"
leveragepk="[null]" categoryname="[null]" srcurl="[null]"
srcurlhtml="[null]" commentcount="[null]" status="L"
modifydate="[null]" adddate="2008-02-14" userip="172.0.0.1"/>
<CFT_LEVERAGE_THEME clubid="14446632" articleid="158" leveragecode="39"
theme="내 책"/>
</dataset>
테스트 데이터
Component
54 / 문서의 제목
DbUnit
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<CFT_LEVERAGE_ARTICLE TEST_CASE_INDEX="1"
clubid="14446632" articleid="158" leveragecode="39"
leveragepk="120" categoryname="categoryresult"
srcurl="http://dev.book.naver.com/bookdb/book_detail.php?bid=2925556"
srcurlhtml="[null]" commentcount="[null]" status="O"
userip="172.0.0.1"/>
<CFT_LEVERAGE_ARTICLE TEST_CASE_INDEX="2"
clubid="14446632" articleid="158" leveragecode="39“
leveragepk="[null]" categoryname=""
srcurlhtml="[null]" commentcount="[null]" status="L"
userip="172.0.0.1"/>
<CFT_LEVERAGE_ARTICLE TEST_CASE_INDEX="3"
clubid="14446632" articleid="158" leveragecode="39“
leveragepk="" categoryname=""
srcurlhtml="[null]" commentcount="0" status="R"
userip="172.0.0.1"/>
<CFT_LEVERAGE_THEME clubid="14446632" articleid="158" leveragecode="39"
theme="내 책"/>
</dataset>
결과 데이터
Component
55 / 문서의 제목
public class ApplyOperationIntegrationTest extends CafeTestCase {
@Override
protected String[] getCafeConfigLocations() {
return new String [] {
"/META-INF/applicationContext-bridge-bo.xml",
......
"/META-INF/applicationContext-bridge-leverage.xml"
};
}
@Override
protected Integer getClubId() {
return 14446632;
}
@Override
protected void afterSetUp() throws Exception {
loadDataSet(DBKeyGenerator.DB_KEY_CLUB,
"ApplyOperationIntegrationTest-club-setup.xml");
loadDataSet(DBKeyGenerator.DB_KEY_CLUBBBS,
"ApplyOperationIntegrationTest-clubbbs-setup.xml");
}
DbUnit
Custom Test Case
어플리케이션 컨텍스트 로드
데이터베이스 선택을 위해 오버라이딩
테스트 데이터 로드
Component
56 / 문서의 제목
public void testApplySuccessOnNormalQueue() throws Exception {
HttpClientInvokerStub httpClientInvokerStub = new HttpClientInvokerStub("1",
FailureCause.NO_FAILURE.name(), "120",
"http://dev.book.naver.com/bookdb/book_detail.php?bid=2925556",
"categoryresult");
((LeverageRequestSenderImpl)getBean("leverageRequestSenderTarget"))
.setHttpClientInvoker(httpClientInvokerStub);
LeverageRequest leverageRequest = LeverageRequestBuilder.apply(getClubId(),
Leveraged.before(getArticleId(), LeverageEnum.BOOK.getCode()));
assertTrue(cafeToVerticalProducerBO.sendDirectly(leverageRequest));
verify(DBKeyGenerator.DB_KEY_CLUBBBS,
"ApplyOperationIntegrationTest-clubbbs-result.xml", 1);
}
DbUnit
Custom Test Case
결과 테스트 데이터를 사용하여
데이터 베이스 상태 검증
Component
57 / 문서의 제목
HTTPUnit
웹 어플리케이션 System Testing Tool
웹어플리케이션용테스트스크립트 구현
JUnit 기반프레임웍
http://httpunit.sourceforge.net/
System
58 / 문서의 제목
HTTPUnit
public class CaclHttpTestCase {
@Test
public void calc() throws Exception {
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest(
"http://127.0.0.1:8080/calc.action?added=10&addend=20");
WebResponse response = conversation.getResponse(request);
assertEquals(30,
Integer.parseInt(response.getElementWithID("result").getText()));
}
HTTPUnit Test Case
System
59 / 문서의 제목
@Test
public void calcUsingForm() throws Exception {
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest(
"http://127.0.0.1:8080/calcView.action");
WebResponse response = conversation.getResponse(request);
WebForm form = response.getFormWithName("calc");
form.setParameter("addend", "100");
form.setParameter("added", "20");
response = form.submit();
assertEquals(120,
Integer.parseInt(response.getElementWithID("result").getText()));
}
}
HTTPUnit
HTTPUnit Test Case
System
60 / 문서의 제목
JWebUnit
웹 어플리케이션 System Testing Tool
웹어플리케이션용테스트스크립트 구현
HTTPUnit 기반
JUnit 기반프레임웍
특징
웹 애플리케이션검색에쓰이는고급 API 제공
링크를통한네비게이션
폼 엔트리와제출
테이블내용
assertion 집합포함
http://httpunit.sourceforge.net/
System
61 / 문서의 제목
JWebUnit
public class CaclHttpTestCase {
private WebTester webTester;
@Before
public void initTestContext() {
webTester = new WebTester();
webTester.getTestContext().setBaseUrl("http://127.0.0.1:8080/");
}
@Test
public void calc() throws Exception {
webTester.beginAt("/calc.action?added=10&addend=20");
webTester.assertElementPresent("result");
webTester.assertTextInElement("result", "30");
}
JWebUnit Test Case
System
62 / 문서의 제목
JWebUnit
@Test
public void calcUsingForm() throws Exception {
webTester.beginAt("/calcView.action");
webTester.setWorkingForm("calc");
webTester.setTextField("addend", "100");
webTester.setTextField("added", "20");
webTester.submit();
webTester.assertElementPresent("result");
webTester.assertTextInElement("result", "120");
}
}
JWebUnit Test Case
System
63 / 문서의 제목
Selenium
웹 어플리케이션을 위한 Acceptance Testing 툴
테스트를 HTML 테이블로 작성
http://selenium.openqa.org/
Selenium IDE
FireFox 플러그인
Test Case Record & Replay 기능제공
Selenium-RC(Remote Control)
프로그래밍언어를사용하여 Acceptance Test 작성및실행가능
Server
브라우저를자동으로실행하고웹요청을처리하는 Proxy
Client
프로그램작성을위한클라이언트라이브러리
Functional
64 / 문서의 제목
Selenium
Selenium IDE
Functional
65 / 문서의 제목
Selenium
Selenium IDE
Functional
66 / 문서의 제목
Selenium
Selenium-RC
Functional
67 / 문서의 제목
Selenium
Selenium-RC와 JUnit 통합
Selenium IDE의 Test Case Export 기능을 사용하여 생성
public class CalcAcceptTestCase extends SeleneseTestCase {
public void setUp() throws Exception {
setUp("http://localhost:8080/", "*iexplore");
}
public void testCalc() throws Exception {
selenium.open("/calc.action?added=10&addend=20");
assertTrue(selenium.isTextPresent("30"));
assertEquals("30", selenium.getText("result"));
}
public void testCalcView() throws Exception {
selenium.open("/calcView.action");
selenium.type("added", "100");
selenium.type("addend", "20");
selenium.click("//input[@value='계산']");
assertEquals("120", selenium.getText("result"));
}
}
Functional
Thank you.
Question.