SlideShare ist ein Scribd-Unternehmen logo
1 von 58
Downloaden Sie, um offline zu lesen
xUnit 테스트 패턴,[object Object],10장,[object Object],결과 검증,[object Object],최기원,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],테스트 코드 작성 노하우,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
상태 검증,[object Object],SUT의 기대 결과 값이 발생했는지 검증하는 '일반적인' 방법,[object Object],3가지 방법,[object Object],내장 단언문을 사용하는 방법,[object Object],델타 단언문을 사용하는 방법,[object Object],외부 결과 검증 방법,[object Object]
내장 단언문 사용 하는 방법,[object Object],assertTrue(aBooleanExpression),[object Object],결과 지정 단언문,[object Object],assertEquals(expected, actual),[object Object],동등 단언문,[object Object],assertEquals(expected, actual, tolerance),[object Object],퍼지 동등 단언문,[object Object]
델타 단언문,[object Object],1. 관련 테이블/클래스에 대한 일종의 '스냅샷'을 테스트 시작할 때 저장한다.,[object Object],2. 테스트가 끝나면 생성된 객체/로우 집합에서 아까의 '스냅샷'을 제거한 후 남은 것들을 기대 결과 값과 비교,[object Object]
외부 결과 검증,[object Object],예상 결과와 실제 결과를 파일로 저장한 후 외부 파일 비교 프로그램으로 차이를 확인하는 것,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
동작 검증,[object Object],SUT의 동작을 검증 하는 방법,[object Object],2가지 방법,[object Object],절차형 동작 검증,[object Object],기대 동작 명세,[object Object]
절차형 동작 검증,[object Object],SUT가 실행될 때 원하는 동작을 잡아낸 후 나중에 쓸 데이터를 저장해둔다. 나중에 테스트에서는 SUT의 출력 값을 해당 기대 결과 값과 하나하나 비교한다.,[object Object]
public void testRemoveFlightLogging_recordingTestStub() throw Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnUnregFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 테스트 대역 설치,[object Object],AuditLogSpy logSpy = new AuditLogSpy();,[object Object],	facade.setAuditLog(logSpy);,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	//검증,[object Object],assertEquals("number of calls", 1, ,[object Object],			logSpy.getNumberofCalls());,[object Object],	assertEquals("action code", Helper.REMOVE_FLIGHT_ACTION_CODE, ,[object Object],			logSpy.getActionCode());,[object Object],	assertEquals("date", helper.getTodayDateWithoutTime(), ,[object Object],			logSpy.getDate());,[object Object],	assertEquals("user", Helper.TEST_USER_NAME, ,[object Object],			logSpy.getUser());,[object Object],	assertEquals("detail", expectedFlightDto.getFlightNumber(), ,[object Object],			logSpy.getDetail());,[object Object],},[object Object]
public void testRemoveFlightLogging_recordingTestStub() throw Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnUnregFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 테스트 대역 설치,[object Object],AuditLogSpy logSpy = new AuditLogSpy();,[object Object],	facade.setAuditLog(logSpy);,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	//검증,[object Object],assertEquals("number of calls", 1, ,[object Object],			logSpy.getNumberofCalls());,[object Object],	assertEquals("action code", Helper.REMOVE_FLIGHT_ACTION_CODE, ,[object Object],			logSpy.getActionCode());,[object Object],	assertEquals("date", helper.getTodayDateWithoutTime(), ,[object Object],			logSpy.getDate());,[object Object],	assertEquals("user", Helper.TEST_USER_NAME, ,[object Object],			logSpy.getUser());,[object Object],	assertEquals("detail", expectedFlightDto.getFlightNumber(), ,[object Object],			logSpy.getDetail());,[object Object],},[object Object]
public void testRemoveFlightLogging_recordingTestStub() throw Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnUnregFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 테스트 대역 설치,[object Object],AuditLogSpy logSpy = new AuditLogSpy();,[object Object],	facade.setAuditLog(logSpy);,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	//검증,[object Object],assertEquals("number of calls", 1, ,[object Object],			logSpy.getNumberofCalls());,[object Object],	assertEquals("action code", Helper.REMOVE_FLIGHT_ACTION_CODE, ,[object Object],			logSpy.getActionCode());,[object Object],	assertEquals("date", helper.getTodayDateWithoutTime(), ,[object Object],			logSpy.getDate());,[object Object],	assertEquals("user", Helper.TEST_USER_NAME, ,[object Object],			logSpy.getUser());,[object Object],	assertEquals("detail", expectedFlightDto.getFlightNumber(), ,[object Object],			logSpy.getDetail());,[object Object],},[object Object]
public void testRemoveFlightLogging_recordingTestStub() throw Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnUnregFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 테스트 대역 설치,[object Object],AuditLogSpy logSpy = new AuditLogSpy();,[object Object],	facade.setAuditLog(logSpy);,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	//검증,[object Object],assertEquals("number of calls", 1, ,[object Object],			logSpy.getNumberofCalls());,[object Object],	assertEquals("action code", Helper.REMOVE_FLIGHT_ACTION_CODE, ,[object Object],			logSpy.getActionCode());,[object Object],	assertEquals("date", helper.getTodayDateWithoutTime(), ,[object Object],			logSpy.getDate());,[object Object],	assertEquals("user", Helper.TEST_USER_NAME, ,[object Object],			logSpy.getUser());,[object Object],	assertEquals("detail", expectedFlightDto.getFlightNumber(), ,[object Object],			logSpy.getDetail());,[object Object],},[object Object]
기대 동작 명세,[object Object],상태를 검증하기 위해 기대 객체를 생성해 SUT가 리턴하는 실제 객체와 비교 한다.,[object Object]
public void testRemoveFlight_JMock() throws Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnonRegFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 모의 객체 설정,[object Object],Mock mockLog = mock(AuditLog.class);,[object Object],	mockLog.expects(once()).method("logMessage"),[object Object],			.with(eq(Helper.getTodaysDateWithoutTime()),,[object Object],				eq(Helper.TEST_USER_NAME),,[object Object],				eq(Helper.REMOVE_FLIGHT_ACTION_CODE),,[object Object],				eq(expectedFlightDto.getFlightNumber()));,[object Object],	// 모의 객체 설치,[object Object],facade.setAuditLog((AuditLog)mockLog.proxy());,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	// 검증,[object Object],// verify() 메소드는 JMock에 의해 자동으로 호출된다.,[object Object],},[object Object]
public void testRemoveFlight_JMock() throws Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnonRegFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 모의 객체 설정,[object Object],Mock mockLog = mock(AuditLog.class);,[object Object],	mockLog.expects(once()).method("logMessage"),[object Object],			.with(eq(Helper.getTodaysDateWithoutTime()),,[object Object],				eq(Helper.TEST_USER_NAME),,[object Object],				eq(Helper.REMOVE_FLIGHT_ACTION_CODE),,[object Object],				eq(expectedFlightDto.getFlightNumber()));,[object Object],	// 모의 객체 설치,[object Object],facade.setAuditLog((AuditLog)mockLog.proxy());,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	// 검증,[object Object],// verify() 메소드는 JMock에 의해 자동으로 호출된다.,[object Object],},[object Object]
public void testRemoveFlight_JMock() throws Exception {,[object Object],	// 픽스쳐 설치,[object Object],FlightDto expectedFlightDto = createAnonRegFlight();,[object Object],	FlightManagementFacade facade = new FlightManagementFacadeImpl();,[object Object],	// 모의 객체 설정,[object Object],Mock mockLog = mock(AuditLog.class);,[object Object],	mockLog.expects(once()).method("logMessage"),[object Object],			.with(eq(Helper.getTodaysDateWithoutTime()),,[object Object],				eq(Helper.TEST_USER_NAME),,[object Object],				eq(Helper.REMOVE_FLIGHT_ACTION_CODE),,[object Object],				eq(expectedFlightDto.getFlightNumber()));,[object Object],	// 모의 객체 설치,[object Object],facade.setAuditLog((AuditLog)mockLog.proxy());,[object Object],	// 실행,[object Object],facade.removeFlight(expectedFlightDto.getFlightNumber());,[object Object],	// 검증,[object Object],// verify() 메소드는 JMock에 의해 자동으로 호출된다.,[object Object],},[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
테스트 코드가 중복이 되면,[object Object],생기는 문제점,[object Object],깨지기 쉬운 테스트,[object Object],깨지기 쉬운 픽스쳐,[object Object],높은 테스트 유지 비용,[object Object],테스트의 의도가 애매해짐,[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
같은 객체의 다른 필드 값을 여러 개 검증할때, 전체적으로 한 줄에 서로 비교할 수 있는 동등 단언문을 사용하는 것,[object Object]
public void testInvoice_addLineItem7() {,[object Object],	LineItem expItem = new LineItem(inv, product, QUANTITY);,[object Object],	// 실행,[object Object],inv.addItemQuantity(product, QUANTITY);,[object Object],	// 검증,[object Object],List lineItems = inv.getLineItems();,[object Object],	LineItem actual = (LineItem)lineItems.get(0);,[object Object],	assertEquals(expItem.getInv(), actual.getInv());,[object Object],	assertEquals(expItem.getProd(), actual.getProd)());,[object Object],	assertEquals(expItem.getQuantity(), actual.getQuantity());,[object Object],},[object Object]
public void testInvoice_addLineItem8() {,[object Object],	LineItem expItem = new LineItem(inv, product, QUANTITY);,[object Object],	// 실행,[object Object],inv.addItemQuantity(product, QUANTITY);,[object Object],	// 검증,[object Object],List lineItems = inv.getLineItems();,[object Object],	LineItem actual = (LineItem)lineItems.get(0);,[object Object],	assertEquals("Item", expItem, actual);,[object Object],},[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
static void assertLineItemsEqual(String msg, ,[object Object],                                                     LineItem exp, ,[object Object],                                                     LineItem act) {,[object Object],	assertEquals(msg+" Inv", exp.getInv(), act.getInv());,[object Object],	assertEquals(msg+" Prod", exp.getProd(), act.getProd());,[object Object],	assertEquals(msg+" Quan", exp.getQuantity(), act.getQuantity());,[object Object],},[object Object]
public void testInvoice_addLineItem8() {,[object Object],	LineItem expItem = new LineItem(inv, product, QUANTITY);,[object Object],	// 실행,[object Object],inv.addItemQuantity(product, QUANTITY);,[object Object],	// 검증,[object Object],List lineItems = inv.getLineItems();,[object Object],	LineItem actual = (LineItem)lineItems.get(0);,[object Object],	 assertLineItemsEqual ("Item", expItem, actual);,[object Object],},[object Object]
맞춤 단언문을 만드는 요령,[object Object],먼저 비어있는 단언 메소드를 호출하게 테스트 작성후 맞춤 단언문이 파악되면 적당한 로직을 채운다,[object Object]
맞춤 단언문의 장점,[object Object],결과 검증 절차를 알기 쉬운 이름으로 숨긴다.,[object Object],의도가 눈에 잘 들어온다.,[object Object],단언문 로직도 맞춤 단언문 테스트를 작성해 단위 테스트 할 수 있다.,[object Object],맞춤 단언문이 필요할때,[object Object],모든 필드를 비교하고 싶지 않을때,[object Object],동등 대신 동일만 비교하고 싶을때,[object Object],테스트용 동등을 원할때,[object Object],생성자가 없어 기대 객체의 인스턴스를 생성할 수 없을때,[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
void assertInvoiceContainsOnlyThisLineItem(Invoice inv, ,[object Object],                                                                        LineItem expItem) {,[object Object],	List lineItems = inv.getLineItems();,[object Object],	assertEquals("number of items", lineItems.size(), 1);,[object Object],	LineItem actual = (LineItem)lineItems.get(0);,[object Object],	assertLineItemsEqual("", expItem, actual);,[object Object],},[object Object]
검증 메소드와 맞춤 단언문 차이,[object Object],맞춤 단언문은 단언만 하는 데 반해 검증 메소드는 SUT와 상호작용도 한다.,[object Object],맞춤 단언문의 시그니처는 일반적인 동등 단언문 시그니처,[object Object],검증 메소드에서는 SUT에 넘겨줄 추가 인자가 필요해서 형태가 자유롭다.,[object Object],본질적으로 검증 메소드는 맞춤 단언문과 인자를 받는 테스트의 중간 형태,[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
픽스처 설치 로직이 똑같고 데이터만 다를 경우 공통의 픽스처 설치, SUT 실행 , 결과 검증 부분만을 뽑아서 만든다.,[object Object],픽스처 설치, SUT 실행, 기대 결과에 필요한 데이터가 포함돼 있다.,[object Object]
def tset_extref,[object Object],	sourceXml = "<extref id='abc' />",[object Object],	expectedHtml = "<a href='abc.html'>abc</a>",[object Object],	generateAndVerifyHtml(sourceXml,expectedHtml,"<extref>"),[object Object],end,[object Object],def test_testterm_normal,[object Object],	sourceXml = "<testterm id='abc'/>",[object Object],	expectedHtml = "<a href='abc.html'>abc</a>",[object Object],	generateAndVerifyHtml(sourceXml,expectedHtml,"<testterm>"),[object Object],end,[object Object],def test_testterm_plural,[object Object],	sourceXml = "<testterm id='abc'/>",[object Object],	expectedHtml = "<a href='abc.html'>abcs</a>",[object Object],	generateAndVerifyHtml(sourceXml,expectedHtml,"<plural>"),[object Object],end,[object Object]
코드 중복을 줄이는 방법,[object Object],기대 객체 사용,[object Object],맞춤 단언문 사용,[object Object],결과를 설명하는 검증 메소드 사용,[object Object],인자를 받는 테스트,[object Object],데이터 주도 테스트,[object Object]
데이터 주도 테스트,[object Object],테스트 케이스는 일반적이며 프레임워크가 직접 실행할 수 있다.,[object Object],실행될 때는 테스트 데이터 파일에서 인자를 읽어온다.,[object Object],인자를 받는 테스트는 테스트용 데이터를 테스트 메소드에서 받는 반면에 데이터 주도 테스트는 자체가 테스트 메소드이고 파일에서 테스트용 데이터를 직접 읽어 들인다.,[object Object]
Data File,[object Object],ID, Action, SourceXml, ExpectedHtml,[object Object],Extref,crossref,<extref id='abc'/>,<a href='abc.html'>abc</a>,[object Object],TTerm,crossref,<testterm id='abc'/>,<a href='abc.html'>abc</a>,[object Object],TTerms,crossref,<testterms id='abc'/>,<a href='abc.html'>abcs</a>,[object Object],def executeDataDrivenTest filename,[object Object],	dataFile = File.open(filename),[object Object],	dataFile.each_line do | line |,[object Object],		desc, action, part2 = line.split(","),[object Object],		sourceXml, expectedHtml, leftOver = part2.split(","),[object Object],		if "crossref"==action.strip,[object Object],			generateAndVerifyHtml sourceXml, expectedHtml, desc,[object Object],		else # 새 '동사'들은 위에 elseif 형태로 추가할 수 있다.,[object Object],			report_error("unknown action" + action.strip),[object Object],		end,[object Object],	end,[object Object],end,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
테스트 내에 조건문이 있으면 ,[object Object],같은 테스트가 상황에 따라 다르게 실행될 수 있다는 점에서 나쁘다.,[object Object],신뢰가 떨어진다.,[object Object]
조건문을 넣는 이유,[object Object],테스트 도중 이미 잘못된 부분을 찾았다면 나머지 단언문은 실행해봐야 별 도움이 안 되니까 아예 실행하고 싶지 않다.,[object Object],코드가 읽기 어려워진다.,[object Object],기대 결과 값과 비교하는 실제 결과에 대해 다양한 상황을 허용해야 한다.,[object Object],코드가 읽기 어려워진다.,[object Object],하나의 테스트 메소드를 여러 상황에서 재사용하고 싶다.,[object Object],절대 하지마,[object Object]
if문 제거하기,[object Object],보호 단언문을 쓴다.테스트 내 조건문 로직이 없어도 테스트 에러를 낼 수 있는 곳에 단언문이 걸리게 할 수 있다.,[object Object]
List lineItems = invoice.getLineItems();,[object Object],if (lineItems.size() == 1) {,[object Object],	LineItem expected = new LineItem(invoice, product, 5, ,[object Object],                  new BigDecimal("30"), ,[object Object],                  new BigDecimal("69.96"));,[object Object],	LineItem actItem = (LineItem) lineItems.get(0);	,[object Object],	assertEquals("invoice", expected, actItem);,[object Object],} else {,[object Object],	fail("invoice should have exactly one line item");,[object Object],},[object Object]
List lineItems = invoice.getLineItems();,[object Object],assertEquals("number of items", lineItems.size(), 1);,[object Object],LineItem expected = new LineItem(invoice, product, 5, ,[object Object],                       new BigDecimal("30"), ,[object Object],                       new BigDecimal("69.96"));,[object Object],LineItem actItem = (LineItem) lineItems.get(0);,[object Object],assertEquals("invoice", expected, actItem);,[object Object]
반복문 제거하기,[object Object],테스트 메소드에 반복문이 들어가면 다음과 같은 문제가 생긴다.,[object Object],테스트할 수 없는 테스트 코드가 추가되는 셈이 된다.,[object Object],애매한 테스트가 되기 쉽다.,[object Object],복잡하다. 테스트를 안쓰게 된다.,[object Object],해결법,[object Object],테스트 유틸리티 메소드에 로직을 옮겨놓고 의도가 잘 드러나게 이름을 정하면 된다.,[object Object]
10장에서 이야기 하는 것,[object Object],테스트 결과 검증 방법,[object Object],상태 검증,[object Object],동작 검증,[object Object],테스트 코드 작성 노하우,[object Object],테스트 코드 중복 줄이기,[object Object],테스트 내 조건문 로직 피하기,[object Object],이해하기 쉬운 테스트를 작성하기,[object Object]
이해하기 쉬운 테스트 작성 요령,[object Object],거꾸로 작업,[object Object],밖에서 안으로 작업,[object Object],테스트 주도 개발로 테스트 유틸리티 메소드 작성,[object Object],재사용 가능한 검증 로직을 둘 위치,[object Object]
이해하기 쉬운 테스트 작성 요령,[object Object],거꾸로 작업,[object Object],밖에서 안으로 작업,[object Object],테스트 주도 개발로 테스트 유틸리티 메소드 작성,[object Object],재사용 가능한 검증 로직을 둘 위치,[object Object]
함수의 가장 마지막 줄을 먼저 작성해본다.,[object Object],테스트를 먼저 작성해 본다.,[object Object],단언문들을 먼저 작성한다.,[object Object],변수를 먼저 사용하고, 나중에 선언한다.,[object Object]
이해하기 쉬운 테스트 작성 요령,[object Object],거꾸로 작업,[object Object],밖에서 안으로 작업,[object Object],테스트 주도 개발로 테스트 유틸리티 메소드 작성,[object Object],재사용 가능한 검증 로직을 둘 위치,[object Object]
일정한 추상수준을 유지하는 것을 의미,[object Object],테스트 유틸리티 메소드를 호출하는 방식으로 코딩을 함으로써 테스트 메소드를 작성하는 동안에는 SUT의 요구 사항에만 집중하게 한다.,[object Object],어떤 객체나 결과가 필요한지만 작성해둔다.,[object Object],정의하지 않은 채로 먼저 사용하는 유틸리티 메소드는 테스트 자동 로직이 들어갈 장소 역할을 하게 된다.,[object Object],테스트 유틸리티 메소드를 나중에 구현한다.,[object Object]
이해하기 쉬운 테스트 작성 요령,[object Object],거꾸로 작업,[object Object],밖에서 안으로 작업,[object Object],테스트 주도 개발로 테스트 유틸리티 메소드 작성,[object Object],재사용 가능한 검증 로직을 둘 위치,[object Object]
테스트 유틸리티 메소드를 구현할 시점,[object Object],테스트 유틸리티 메소드를 사용하는 테스트 메소드 작성이 끝났을때,[object Object],테스트 유틸리티 메소드를 작성할때 테스트 유틸리티용 테스트를 작성한다.,[object Object]
이해하기 쉬운 테스트 작성 요령,[object Object],거꾸로 작업,[object Object],밖에서 안으로 작업,[object Object],테스트 주도 개발로 테스트 유틸리티 메소드 작성,[object Object],재사용 가능한 검증 로직을 둘 위치,[object Object]
재사용 가능한 테스트 로직은 어디에 둬야 할까?,[object Object],테스트 케이스 클래스 안,[object Object],테스트케이스 상위클래스,[object Object],테스트 도우미 안,[object Object]
끝,[object Object]

Weitere ähnliche Inhalte

Was ist angesagt?

C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기Heo Seungwook
 
Python Unittest
Python UnittestPython Unittest
Python Unittest명규 최
 
Droid knights android test @Droid Knights 2018
Droid knights android test @Droid Knights 2018Droid knights android test @Droid Knights 2018
Droid knights android test @Droid Knights 2018KyungHo Jung
 
Effective unit testing ch3. 테스트더블
Effective unit testing   ch3. 테스트더블Effective unit testing   ch3. 테스트더블
Effective unit testing ch3. 테스트더블YongEun Choi
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기OnGameServer
 
[고급과정] 코드 테스트와 커버리지 교육(실습위주)
[고급과정] 코드 테스트와 커버리지 교육(실습위주)[고급과정] 코드 테스트와 커버리지 교육(실습위주)
[고급과정] 코드 테스트와 커버리지 교육(실습위주)SangIn Choung
 
Agile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowAgile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowRyan Park
 
Check style 기초가이드
Check style 기초가이드Check style 기초가이드
Check style 기초가이드rupert kim
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장tedypicker
 
아해2019 SpringAOP 문겸
아해2019 SpringAOP 문겸아해2019 SpringAOP 문겸
아해2019 SpringAOP 문겸MoonGyeom1
 
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드 Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드 SangIn Choung
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018Kenneth Ceyer
 
xUnitTestPattern/chapter7
xUnitTestPattern/chapter7xUnitTestPattern/chapter7
xUnitTestPattern/chapter7종빈 오
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental systemJaehoon Oh
 
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로Oracle Korea
 
Deview 2019 눈발자국
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국hanbeom Park
 

Was ist angesagt? (20)

C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기
 
Python Unittest
Python UnittestPython Unittest
Python Unittest
 
Droid knights android test @Droid Knights 2018
Droid knights android test @Droid Knights 2018Droid knights android test @Droid Knights 2018
Droid knights android test @Droid Knights 2018
 
Effective unit testing ch3. 테스트더블
Effective unit testing   ch3. 테스트더블Effective unit testing   ch3. 테스트더블
Effective unit testing ch3. 테스트더블
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기
 
[고급과정] 코드 테스트와 커버리지 교육(실습위주)
[고급과정] 코드 테스트와 커버리지 교육(실습위주)[고급과정] 코드 테스트와 커버리지 교육(실습위주)
[고급과정] 코드 테스트와 커버리지 교육(실습위주)
 
Agile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowAgile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And How
 
Check style 기초가이드
Check style 기초가이드Check style 기초가이드
Check style 기초가이드
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장
 
아해2019 SpringAOP 문겸
아해2019 SpringAOP 문겸아해2019 SpringAOP 문겸
아해2019 SpringAOP 문겸
 
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드 Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드
Postman과 Newman을 이용한 RestAPI 테스트 자동화 가이드
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
 
xUnitTestPattern/chapter7
xUnitTestPattern/chapter7xUnitTestPattern/chapter7
xUnitTestPattern/chapter7
 
Android unit testing
Android unit testingAndroid unit testing
Android unit testing
 
6 function
6 function6 function
6 function
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
Javascript기초
Javascript기초Javascript기초
Javascript기초
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental system
 
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
 
Deview 2019 눈발자국
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국
 

Ähnlich wie 10장 결과 검증

테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례SangIn Choung
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴Suan Lee
 
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅NAVER D2
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509영석 조
 
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기OKKY
 
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성Lee Sang-Ho
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
Naver api for android
Naver api for androidNaver api for android
Naver api for androidSangon Lee
 
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드SangIn Choung
 
Android UI Test (Espresso/Kakao)
Android UI Test (Espresso/Kakao)Android UI Test (Espresso/Kakao)
Android UI Test (Espresso/Kakao)MDLicht
 
TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDSuwon Chae
 
프로그램은 왜 실패 하는가
프로그램은 왜 실패 하는가프로그램은 왜 실패 하는가
프로그램은 왜 실패 하는가홍준 김
 
Spring test mvc 발표자료
Spring test mvc 발표자료Spring test mvc 발표자료
Spring test mvc 발표자료수홍 이
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven DevelopmentChangHyeon Bae
 
Xunittestpatternchapter11
Xunittestpatternchapter11Xunittestpatternchapter11
Xunittestpatternchapter11duaa83
 
Backend Master | 3.2.1 Test - JUnit
Backend Master | 3.2.1 Test - JUnitBackend Master | 3.2.1 Test - JUnit
Backend Master | 3.2.1 Test - JUnitKyunghun Jeon
 
Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Jaehoon Oh
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례SangIn Choung
 

Ähnlich wie 10장 결과 검증 (20)

테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴
 
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
 
JUnit & AssertJ
JUnit & AssertJJUnit & AssertJ
JUnit & AssertJ
 
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성
[방송통신대 컴퓨터과학과] C++ 프로그래밍 과제물 작성
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
Naver api for android
Naver api for androidNaver api for android
Naver api for android
 
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
katalon studio 툴을 이용한 GUI 테스트 자동화 가이드
 
Android UI Test (Espresso/Kakao)
Android UI Test (Espresso/Kakao)Android UI Test (Espresso/Kakao)
Android UI Test (Espresso/Kakao)
 
TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDD
 
프로그램은 왜 실패 하는가
프로그램은 왜 실패 하는가프로그램은 왜 실패 하는가
프로그램은 왜 실패 하는가
 
Spring test mvc 발표자료
Spring test mvc 발표자료Spring test mvc 발표자료
Spring test mvc 발표자료
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
Xunittestpatternchapter11
Xunittestpatternchapter11Xunittestpatternchapter11
Xunittestpatternchapter11
 
Cygnus unit test
Cygnus unit testCygnus unit test
Cygnus unit test
 
Backend Master | 3.2.1 Test - JUnit
Backend Master | 3.2.1 Test - JUnitBackend Master | 3.2.1 Test - JUnit
Backend Master | 3.2.1 Test - JUnit
 
Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례
 

Mehr von dagri82

Ddd 14장
Ddd 14장Ddd 14장
Ddd 14장dagri82
 
D.D.D. 14장
D.D.D. 14장D.D.D. 14장
D.D.D. 14장dagri82
 
Mongo db 2장
Mongo db  2장Mongo db  2장
Mongo db 2장dagri82
 
It 개발자가쓴 통쾌한 인간관리 이야기
It 개발자가쓴 통쾌한 인간관리 이야기It 개발자가쓴 통쾌한 인간관리 이야기
It 개발자가쓴 통쾌한 인간관리 이야기dagri82
 
클로저
클로저클로저
클로저dagri82
 
보난자
보난자보난자
보난자dagri82
 
데브루키 스터디 발표
데브루키 스터디 발표데브루키 스터디 발표
데브루키 스터디 발표dagri82
 
데브루키 스터디 발표
데브루키 스터디 발표데브루키 스터디 발표
데브루키 스터디 발표dagri82
 
holubonpatternschapter41
holubonpatternschapter41holubonpatternschapter41
holubonpatternschapter41dagri82
 
holubonpatternschapter41
holubonpatternschapter41holubonpatternschapter41
holubonpatternschapter41dagri82
 

Mehr von dagri82 (10)

Ddd 14장
Ddd 14장Ddd 14장
Ddd 14장
 
D.D.D. 14장
D.D.D. 14장D.D.D. 14장
D.D.D. 14장
 
Mongo db 2장
Mongo db  2장Mongo db  2장
Mongo db 2장
 
It 개발자가쓴 통쾌한 인간관리 이야기
It 개발자가쓴 통쾌한 인간관리 이야기It 개발자가쓴 통쾌한 인간관리 이야기
It 개발자가쓴 통쾌한 인간관리 이야기
 
클로저
클로저클로저
클로저
 
보난자
보난자보난자
보난자
 
데브루키 스터디 발표
데브루키 스터디 발표데브루키 스터디 발표
데브루키 스터디 발표
 
데브루키 스터디 발표
데브루키 스터디 발표데브루키 스터디 발표
데브루키 스터디 발표
 
holubonpatternschapter41
holubonpatternschapter41holubonpatternschapter41
holubonpatternschapter41
 
holubonpatternschapter41
holubonpatternschapter41holubonpatternschapter41
holubonpatternschapter41
 

10장 결과 검증

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.