CS(Computer Science)/Software Engineering

테스트 주도 개발 : TDD(Test Driven Development)

환성 2023. 1. 5. 22:43
728x90

일반적인 개발 방식

보통의 개발 방식은 요구사항 분석 -> 설계 -> 개발 -> 테스트 -> 배포 형태의 개발 주기를 갖는데 이러한 방식은 소프트웨어 개발을 느리게 하는 잠재적 위험이 존재한다.

 

소비자의 요구사항이 명확하지 않을 수도 있고 소스코드의 품질이 저하될 수 있기 때문이다. 추가로 테스트 비용의 증가라는 위험성도 가지고 있다.

 

이러한 점 때문에 부분적으로 기능 수정을 하게 되는데 기능 수정을 함으로써 모든 부분을 테스트해야 하므로 전체적인 버그를 검출하기 어려워지는 문제가 발생한다. 

 

TDD 과정

TDD(Test Driven Development)

  • 기존 설계 방법과는 다르게, 테스트케이스를 먼저 작성한 후 실제 코드를 개발하는 리팩토링 절차를 밟아 실행하는 것
  • 반복 테스트를 이용한 소프트웨어 방법론, 작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계에 반복하여 구현한다.
  • 불확실성이 높을 때 피드백과 협력이 중요하기에 피드백과 협력이 이루어진다면 좋은 결과가 나올 수 있기 때문에 사용한다.

 

장점

  • 작업과 동시에 테스트를 진행하면서 실시간으로 오류 파악이 가능하다.
  • 짧은 개발 주기를 통해 고객의 요구사항을 빠르게 수용 가능하다
  • 피드백이 가능하고 진행 상황 파악이 쉽다.
  • 자동화 도구를 이용한 TDD 테스트케이스를 단위 테스트로 사용이 가능하다.

 

단점 

  • 기존 개발 프로세스에 테스트케이스 설계가 추가되므로 생산 비용이 증가한다
  • 테스트의 방향성, 프로젝트 성격에 따른 테스트 프레임워크 선택 등 추가로 고려할 부분이 증가한다.

 

TDD 개발주기

 

TDD 개발주기

  • Red 단계에서는 실패하는 테스트 코드를 작성한다.
  • Green 단계에서는 테스트 코드를 성공 시키기 위한 실제 코드를 작성한다.
  • Blue 단계에서는 중복 코드 제거, 일반화 등 리팩토링을 수행한다.

 

 

TDD Tool

JUnit 

  • 현재 전 세계적으로 가장 널리 사용되는 Java 단위 테스트 프레임워크

XUnit

  •  자바 외에 다른언어들의 단위 테스트를 위한 프레임 워크

 

점수 계산 프로그램을 통한 TDD 예제 진행

중간고사, 기말고사, 과제 점수를 통한 성적을 내는 간단한 프로그램을 만들어봅시다.

점수 총합 90점 이상은 A, 80점 이상은 B, 70점 이상은 C, 60점 이상은 D, 나머지는 F다.

 

TDD 테스트케이스를 먼저 작성한다.

35 + 25 + 25 = 85점이므로 등급이 B가 나와야 한다.

따라서 assertEquals의 인자값을 "B"로 주고, 테스트 결과가 일치하는지 확인하는 과정을 진행한다,

 

public class GradeTest {
    
    @Test
    public void scoreResult() {
        
        Score score = new Score(35, 25, 25); // Score 클래스 생성
        SimpleScoreStrategy scores = new SimpleScoreStrategy();
        
        String resultGrade = scores.computeGrade(score); // 점수 계산
        
        assertEquals("B", resultGrade); // 확인
    }
    
}

현재는 Score 클래스와 computeGrade() 메소드가 구현되지 않은 상태다. (테스트 코드로만 존재)

테스트 코드에 맞춰서 코드 개발을 진행해야 한다.

우선 점수를 저장할 Score 클래스를 생성한다

public class Score {
    
    private int middleScore = 0;
    private int finalScore = 0;
    private int homeworkScore = 0;
    
    public Score(int middleScore, int finalScore, int homeworkScore) {
        this.middleScore = middleScore;
        this.finalScore = finalScore;
        this.homeworkScore = homeworkScore;
    }
    
    public int getMiddleScore(){
        return middleScore;
    }
    
    public int getFinalScore(){
        return finalScore;
    }
    
    public int getHomeworkScore(){
        return homeworkScore;
    }
    
}

이제 점수 계산을 통해 성적을 뿌려줄 computeGrade() 메소드를 가진 클래스를 만든다.

우선 인터페이스를 구현한다.

 

public interface ScoreStrategy {    
    public String computeGrade(Score score);
    
}

 

인터페이스를 가져와 오버라이딩한 클래스를 구현한다

public class SimpleScoreStrategy implements ScoreStrategy {
    
    public String computeGrade(Score score) {
        
        int totalScore = score.getMiddleScore() + score.getFinalScore() + score.getHomeworkScore(); // 점수 총합
        
        String gradeResult = null; // 학점 저장할 String 변수
        
        if(totalScore >= 90) {
            gradeResult = "A";
        } else if(totalScore >= 80) {
            gradeResult = "B";
        } else if(totalScore >= 70) {
            gradeResult = "C";
        } else if(totalScore >= 60) {
            gradeResult = "D";
        } else {
            gradeResult = "F";
        }
        
        return gradeResult;
    }
    
}

 

통과가 가능한 정보를 넣고 실행하면, 에러 없이 제대로 실행되는 모습을 볼 수 있다.

 

 

출처:
https://gyoogle.dev/blog/computer-science/software-engineering/TDD.html

'CS(Computer Science) > Software Engineering' 카테고리의 다른 글

써드 파티(3rd party)  (0) 2023.01.08
데브옵스(DevOps)  (0) 2023.01.07
애자일(Agile)  (0) 2023.01.07
클린 코드, 리팩토링  (0) 2023.01.05