프로그램은 로직에 의해서 돌아간다.
과거와 달리 모던사회에 이르러서 TDD 테스트 주도 개발이라는
프로그램 개발방법도 존재한다. 프로그램의 단위를 작은 조각으로 분리하여
테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여
구현한다 이다. (말은 좋다)
사실 유닛테스트는 기술이라기보다 방법론에 가깝다.
하지만 이것을 관통하는 관례가 있는데.. 그것은 바로 OOP이다.
객체지향 프로그래밍인데 이것을 기본으로 처리한후 이를 테스트 하기위함 이다.
한 메서드 안에서 200라인 넘어가는 방식으로 프로그래밍을 해왔었던 사람은
유닛테스트를 이해하기 힘들다. 왜? 이코드가 반복이 되니까 따로 빠져야되는지
왜? 불필요한 클래스가 추가되서 로직을 망치는지..?
이런 마인드가 있는 사람이 유닛테스트를 바라본다면 그건 그냥 테스트 프로젝트의
지나지 않는다.
사실 OOP 즉 프로그램을 철저하게 모듈화한 프로그램을 지향하는것이 습관적으로
몸에 베어있는 상태에서 클린코드를 지향하는 방향으로 설계가 되었을때
비로소 이 유닛테스트는 효과가 있다. 그렇지만 유닛테스트는 그래픽적인 요소와
거리가 멀다. 단순히 레이블이나 색상을 변경을 확인하고자 혹은 그래픽적으로
훌륭한 UI를 설계하고자 유닛테스트를 하지는 않는다.
다만 프로그램이 논리의 작은 단위로 구성되는것을 철저히 기본으로 하였을때
이때는 이논리적인 단위를 테스트하는 단위테스트가 위력을 발휘할수 있다.
이러한 관점에서 테스트할때 유의해야 되는 부분이 있다.
일반적으로 다른 클래스에 의존성이 있는 클래스의 메소드를 테스트를 할때
테스트가 곤란한 지경에 이른다. 이 함수를 테스트를 하기 위해서 StartUp 부터
파일로드 하고 DB연결 한다음에 설정값 가져오고 어쩌고 해서 질의를 했는데
그결과에따라서 내로직이 변경되는걸 UI에 반영되는데 이결과를 보기위해서 앞에꺼를
다시 전부 코딩해야하느냐?? 이런 문제가 가장크게 직면할것이다.
이것을 해결할수 있게 만드는 것이 유닛테스트를 할수있게 만드는 클래스의 설계이다.
이설계의 핵심은 바로 의존성이 있는 클래스를 인터페이스화 하여 생성자에서
전달받을수 있게 처리가 되고 이 인터페이스가 하는 행동이 메서드 시그니처에
들어가 있으니까. 이 인터페이스를 만족하는 어떤 오브젝트도 올수 있음으로
테스트용 더미 오브젝트가 생성이 가능해진다.
그리고 추가적인 해결방법은 바로 클래스의 메서드를 작성할때 하나의 메서드는
하나의 기능만을 하도록 설계하는 함수중심의 설계 바로 그것이다.
예를들어 함수가 리스트에 추가하고 해당리스트를 파일에 저장하는 일은 한다고
했을때 리스트에 추가하는 메서드와 파일에 저장하는 메서드 2개로 분리한다.
이런 방법으로 인해서 논리의 단위를 테스트하는 유닛테스트라는 것이 만들어지고
활용될수 있는 근간이 되는것이다.
결론: 유닛테스트를 하기위해서 OOP기반으로 설계를 해야만한다.
유닛테스트는 로직을 테스트하기 위함이다.
유닛테스트를 하기 위해 클래스를 설계할때 의존성 주입을 받을수 있는
클래스로 설계하고 메서드는 하나의 작업만을 할수 있도록 설계한다.
C# 생태계에서 자주사용하는 유닛테스트는 XUnit이다.
댓글 없음:
댓글 쓰기