Test Double

  • 테스트 코드를 작성할 때 의존 컴포넌트(DOC, depended-on component)를 사용할 수 없다면, DOC 대신 테스트 더블로 대체할 수 있음

  • 테스트 더블은 실제 DOC와 똑같이 행동하지 않아도 되며, 실제 API와 동일한 API를 제공하기만 하면 됨

  • 테스트 더블은 테스트 목적으로 프로덕션 객체를 대체하는 모든 경우에 대한 일반적인 용어.

Test Double 종류

Dummy

전달되지만 실제로는 사용하지 않는 객체. 일반적으로 매개 변수 목록을 채우기 위해 사용

Fake

실제로 작동하는 구현체지만 일반적으로 프로덕션에는 적합하지 않은 꼼수 사용 (e.g. InMemoryTestDatabase)

Stub
  • 테스트 중에 호출되면 미리 준비된 결과를 제공하는 객체. 보통 테스트를 위해 프로그래밍한 내용이 아니면 응답하지 않음

  • Stub은 "이 객체는 무조건 이 값을 반환한다"와 같이 로직은 없고 원하는 값만 반환한다. 작성하기 쉽지만 불필요한 boilerplate 코드[1]를 줄이기 위해서 Mocking Framework를 이용하는게 편하다.

    // 다 되었다 치고 배열 넘어오는 가짜 데이터
    
    @Mock
    private Service stub; // Mocking Framework에 의해 생성된 Stub 객체
    
    @InjectMock
    private TestObject testObject; // 테스트 객체
    
    @Test
    void stubTest() {
    	ContentManager manager = new ContentManager(stub);
    
    	given(stub.isEmpty()).willReturn(true); // 원하는 값을 반환하도록 설정
    
    	assertTrue(manager.isEmpty());
    }
Spy
  • 자신히 호출된 방법/과정 등의 정보를 기독하는 stub. 보낸 메일의 수를 기록하는 이메일 서비스를 예로 들 수 있음.

  • 실체 객체를 감시하고 싶을 때 사용

  • 내부의 상태가 바뀌었을 때 확인

  • 클리했을 때 내부의 값이 바뀌었는지

  • 한번 클릭했는지, 두번 클릭했는지 확인

Mock
  • 호출했을 때 사전에 정의된 명세대로의 결과를 돌려주도록 미리 프로그래밍된 객체. 예상치 못한 호출이 있을 경우 예외를 던질 수 있으며, 모든 호출이 예상된 것이었는지 확인 가능.

  • Mock은 "어떤 메서드가 호출될 것이다"는 행위에 대한 예상만 가지고 있다. 예상대로 메서드가 호출되지 않을 경우 테스트는 실패한다. 즉 Mock은 객체 사이의 행위(interaction)를 테스트하기 위해 사용한다.

    • 행위를 검증할 수 있는 것

    • 실제 객체처럼 만듦

Note
Mock, Stub 차이점
  • "행위를 테스트(모의 객체 스타일)", "상태 테스트(고전적 스타일)"로 나눠짐

  • 고전적 스타일, 모의 객체 스타일

  • 상태 기반 테스트: 테스트의 목적 객체가 처리한 결과에 대해 판단하는 기법

  • 행위 기반 테스트: 요구 사항이나 설계쩍 관점으로 테스트를 구현하는 것이 목적.

    즉, 테스트하는 객체가 올바른 방향으로 진행하고 있는가에 대한 것으로써 테스트의 성공 여부를 판단.

    이것을 위해 행위를 테스트하는 모의 객체를 황용하여 구현하는 방법을 제시하기 때문에 모의 개ㅑㄱ체 스타일이라고 부른다.

  • 이런 전제를 기본으로 마틴 파울러는 다섯 가지 요소를 통해 각 스타일의 입장차이가 구분된다는 것을 피력한다.

    • Driving TDD(TDD 진행 방식의 차이)

    • Fixture setup(Fixture 얼마나 어떻게 사용되는가?)

    • Test Isolation(단위 테스트 격리에 대한 관점의 차이)

    • Coupling Tests to Implementations(단위 테스트와 구현체의 결합도 관점의 차이)

    • Design Style(설계에 미치는 영향)

Fixture

Test Spy

  • 단위 테스트의 실행 시 필요한 요소로서 많이 사용

  • 때로는 테스트에 대한 성격이나 실행되는 단위 테스트의 그룹화를 일걸을 때도 사용

  • 소프트웨어 테스트에서 반복적이고 동일한 결과를 얻는 테스트를 실행하기 위한 기반이 되는 정적인 상태들과 환경

Learning Test

Stress Test

  • 부하 테스트

  • CPU의 사용률 측정 : sar (싸르)

  • Memory의 사용률 측정 : vmstat (브이엠스테이트)

  • Disk의 사용률 측정 : iostat (아이오스테이트)

$ vmstat # process, 가상메모리, paging, disk, cpu 등의 상태 측정
$ iostat # 각 디스크에 받는 로드 측정, 디스크 입출력, 활용도, queue크기, transaction율, 서비스시간 등 표시
$ psrinfo
$ sar # 주로 CPU 사용량을 측정할 때 많이 이용

Unit Test

  • given

  • when

  • then

TC 짤때 spy(?) when() 모키토 코드는 어디에 넣어야 하나? given? when?

The given part describes the state of the world before you begin the behavior you're specifying in this scenario. You can think of it as the pre-conditions to the test.
The when section is that behavior that you're specifying.
Finally the then section describes the changes you expect due to the specified behavior.

Integration Test

AB Test

User Test

Smoke Test

  • 개발팀 or 검증팀이 진행

  • 프로그램의 주요 기능을 테스트함

  • 빌드, 릴리즈 후 테스트함

Sanity Test

  • 개발팀 or 개발자가 테스트 주체가 되어 주요한 단위/시스템 모듈을 테스트하는 기법

  • 새로운 기능이 추가됐을 때 그 기능에 대해 테스트 해보는 것

  • 새로 추가된 기능, 수정된 버그 테스트

  • 빌드, 릴리즈 전 테스트

Regression Test

  • 회귀 테스트

  • 수정으로 인해 변경되지 않은 소프트웨어 영역에 새로운 결함이 유입되지 않았는지 테스트

  • 기존에 숨어있던 결함이 노출되지 않았는지 확인하기 위해 테스트

  • 이전에 테스트된 프로그램을 다시 테스트해보는 것

  • http://jidum.com/jidums/view.do?jidumId=581

Alpha Testing

Beta Testing

TDD, Test-Driven Development

테스트 주도 개발

Note
BDD, Behaviour-Driven Development

행위 주도 개발

Note
DDD, Domain-Driven Development

도메인 주도 개발

<html>
<head></head>
<body></body>
</html>

용어

UUT, Unit Under Test

테스트중인 단위

CUT, code under test


[1] boilerplate 코드: 꼭 필요하면서 간단한 기능인데 많은 코드를 필요로 하는 코드, 예로 getter/setter, html/head/body 마크업이 있다. [wiki](https://en.wikipedia.org/wiki/Boilerplate_code)

// as-is
class Boilerplate {
	private int var;
	public void setVar(int var) {
		this.var = var;
	}
	public int getVar() {
		return this.var;
	}
}

// to-be: lombok 적용
@Data
class Boilerplate {
	private int var;
}

참고 링크

도구