본문 바로가기
[개발] Test

[TDD 연습] 계산기 만들기

by Devsong26 2024. 6. 30.

정수형을 가지고 계산기를 만들어 보겠습니다.

 

1. 덧셈

테스트를 먼저 작성합니다.

@Test
public void 정수형_두_개로_덧셈을_한다_1(){
    int result = new Calculator().add(3, 4);

    assertEquals(7, result);
}

@Test
public void 정수형_두_개로_덧셈을_한다_2(){
    int result = new Calculator().add(8, 4);

    assertEquals(12, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public int add(int a, int b) {
    return a + b;
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 7로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

2. 뺄셈

테스트를 먼저 작성합니다.

@Test
public void 정수형_두_개로_뺄셈을_한다_1(){
    int result = new Calculator().subtract(10, 4);

    assertEquals(6, result);
}

@Test
public void 정수형_두_개로_뺄셈을_한다_2(){
    int result = new Calculator().subtract(10, 14);

    assertEquals(-4, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public int subtract(int a, int b) {
	return a - b;
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 6으로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

3. 곱셈

테스트를 먼저 작성합니다.

@Test
public void 정수형_두_개로_곱셈을_한다_1(){
    int result = new Calculator().multiply(0, 10);

    assertEquals(0, result);
}

@Test
public void 정수형_두_개로_곱셈을_한다_2(){
    int result = new Calculator().multiply(10, 12);

    assertEquals(120, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public int multiply(int a, int b) {
    return a * b;
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 0으로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

4. 나눗셈

테스트를 먼저 작성합니다.

@Test
public void 정수형_두_개로_나눗셈을_한다_1(){
    int result = new Calculator().divide(10, 2);

    assertEquals(5, result);
}

@Test
public void 정수형_두_개로_나눗셈을_한다_2(){
    int result = new Calculator().divide(3, 3);

    assertEquals(1, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public int divide(int a, int b) {
    return a / b;
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 5로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

나눗셈은 제수가 0이 될 경우 진행이 불가능하기 때문에 예외 테스트를 진행합니다.

아래 코드를 수행하면 결과를 반환하지 않고 ArithmeticException.class가 반환되므로 예외 체크를 해줘야 합니다.

@Test
public void 제수가_0인_나눗셈을_한다(){
    assertThrows(
        ArithmeticException.class,
        () -> new Calculator().divide(10, 0)
    );
}

 

 


 

실수형으로 계산기를 구현해 보겠습니다.

 

1. 덧셈

테스트를 먼저 작성합니다.

@Test
public void 실수형_두_개로_덧셈을_한다_1(){
    double result = new Calculator().add(1.5d, 2.6d);

    assertEquals(4.1d, result);
}

@Test
public void 실수형_두_개로_덧셈을_한다_2(){
    double result = new Calculator().add(3.3d, 4.44d);

    assertEquals(7.74d, result);
}

 

정수형에서 사용했던 add 메서드는 int 타입의 파라미터를 받기 때문에 double 형을 받는 add 메서드를 오버로딩합니다.

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public double add(double a, double b){
    return a + b;
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 4.1d로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

실수형의 연산은 부동소수점 문제가 있어 사칙연산 연산자로 계산하면 안 됩니다.

아래는 테스트 코드와 그 결과입니다.

 

@Test
public void 실수형_두_개로_덧셈을_한다_3(){
    double result = new Calculator().add(3.30000000000123d, 4.40000000000123d);

    assertEquals(7.70000000000246d, result);
}

 

결과

 

따라서 소스 코드를 BigDecimal 클래스를 이용하여 연산합니다.

아래는 리팩터링한 코드입니다.

 

public double add(double a, double b){
    final BigDecimal bdA = new BigDecimal(String.valueOf(a));
    final BigDecimal bdB = new BigDecimal(String.valueOf(b));

    return bdA.add(bdB).doubleValue();
}

 

String.valueOf로 파라미터를 래핑한 이유는 double 변수가 부동소수점 표현이기 때문에 근사값을 표시하기 때문입니다.

 

 

2. 뺄셈

테스트를 먼저 작성합니다.

@Test
public void 실수형_두_개로_뺄셈을_한다_1(){
    double result = new Calculator().subtract(1.5d, 2.6d);

    assertEquals(-1.1d, result);
}

@Test
public void 실수형_두_개로_뺄셈을_한다_2(){
    double result = new Calculator().subtract(2.5d, 2.6d);

    assertEquals(-0.1d, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public double subtract(double a, double b){
    final BigDecimal bdA = new BigDecimal(String.valueOf(a));
    final BigDecimal bdB = new BigDecimal(String.valueOf(b));

    return bdA.subtract(bdB).doubleValue();
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 -1.1d로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

3. 곱셈

테스트를 먼저 작성합니다.

@Test
public void 실수형_두_개로_곱셈을_한다_1(){
    double result = new Calculator().multiply(1.0d, 7.0d);

    assertEquals(7.0d, result);
}

@Test
public void 실수형_두_개로_곱셈을_한다_2(){
    double result = new Calculator().multiply(1.01d, 7.0d);

    assertEquals(7.07d, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public double multiply(double a, double b){
    final BigDecimal bdA = new BigDecimal(String.valueOf(a));
    final BigDecimal bdB = new BigDecimal(String.valueOf(b));

    return bdA.multiply(bdB).doubleValue();
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 7.0d로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

4. 나눗셈

테스트를 먼저 작성했습니다.

@Test
public void 실수형_두_개로_나눗셈을_한다_1(){
    double result = new Calculator().divide(77.0d, 7.0d);

    assertEquals(11.0d, result);
}

@Test
public void 실수형_두_개로_나눗셈을_한다_2(){
    double result = new Calculator().divide(77.777d, 7.0d);

    assertEquals(11.111d, result);
}

 

개발 순서는 _1 작성 -> 소스 코드 작성 -> 테스트 성공 -> _2 작성 -> 테스트 실패 -> 소스 코드 리팩터링 -> 테스트 성공 입니다. 완성된 소스 코드는 아래와 같습니다.

 

public double divide(double a, double b){
    final BigDecimal bdA = new BigDecimal(String.valueOf(a));
    final BigDecimal bdB = new BigDecimal(String.valueOf(b));

    return bdA.divide(bdB).doubleValue();
}

 

최초의 소스 코드 반환값은 테스트 _1 을 통과시키기 위해서 11.0d로 정했습니다.

테스트 _2를 통과시키기 위해 소스를 리팩터링 했습니다.

 

나눗셈의 경우 제수가 0이면 예외가 발생합니다. 

아래는 그 테스트입니다.

 

@Test
public void 실수형_두_개로_나눗셈을_한다_3(){
    assertThrows(
        ArithmeticException.class,
        () -> new Calculator().divide(77.777d, 0d)
    );
}

'[개발] Test' 카테고리의 다른 글

@EnableAspectJAutoProxy를 사용하여 AOP 테스트하기  (0) 2024.08.06
테스트 컨테이너  (0) 2024.07.21
하니스(Harness)  (0) 2024.06.29
블랙박스 테스트  (0) 2023.12.31
화이트박스 테스트  (0) 2023.12.31