기타 지식 및 애로사항

[Test] 테스트의 종류 (단위 테스트, 통합 테스트, 기능 테스트)

prometedor 2024. 5. 20. 17:48

 

현재 회사에서 솔루션 고도화와 관련하여 신규 기능을 개발하는 작업을 수행하고 있다.

 

기본적인 기능 개발을 다 하고 나니, 내가 작성한 코드가 잘 동작하고 있는지, 버그가 없는지 테스트를 해봐야겠다는 생각이 들었다.

 

팀장님께서 말씀 주신 테스트는 일단 단위테스트와 통합테스트 였다.

 

개발을 할 때 먼저 개발 기간을 정하는데, 

순수 개발은 2주 정도로 해서 끝내고 테스트를 2주 정도 하라고 하셨는데, 이 2주 동안의 테스트는 1주 간의 단위 테스트와 1주 간의 통합 테스트로 나누어서 하면 된다고 하셨다.

 

이 말씀을 듣고 단위테스트와 통합테스트에 대해 알아보았는데,

유닛테스트(Unit Test), 통합 테스트(Integration Test), 기능 테스트(Functional Test)

이렇게 세 종류 정도로 나뉘는 것으로 확인할 수 있었다.

 

 

유닛 테스트 ( Unit Test )

유닛 테스트는 단위 테스트라고도 하는데, 이는 코드의 가장 작은 기능적 단위를 테스트하는 프로세스이다.

소프트웨어를 작은 기능적인 단위로 작성한 다음 코드 단위별 단위 테스트를 작성하는 것이 소프트웨서 개발 모범 사례이다.

먼저 단위 테스트를 코드로 작성하고, 그런 다음 소프트웨어 코드를 변경할 때마다 테스트 코드를 자동으로 실행한다.

이렇게 하면 테스트가 실패할 경우 버그나 오류가 있는 코드 영역을 빠르게 분리할 수 있다.

 

단위 테스트는 작고 격리된 애플리케이션 코드 블록(일반적으로는 함수 또는 메서드)의 정확성을 확인하는 코드 블럭이다.

단위 테스트는 개발자의 이론적 논리에 따라 코드 블록이 예상대로 실행되는지 확인하도록 설계된다.

 

논리 검사

시스템이 올바른 계산을 수행하며 정확하고 예상되는 입력이 주어진 코드를 통해 올바른 경로를 따르는가?

코드를 통한 모든 경로가 주어진 입력에 의해 처리되는가?

 

경계 검사

주어진 입력에 대해 시스템은 어떻게 반응하는가?

일반적인 입력, 극단적 경우 또는 잘못된 입력에 어떻게 반응하는가?

ex) 3에서 7사이의 정수 입력이 예상된다고 가정해 보면, 5(일반적인 입력), 3(극단적 경우) 또는 9(잘못된 입력)를 사용할 대 시스템은 어떻게 반응하는가?

 

오류 처리

입력에 오류가 있을 때 시스템은 어떻게 반응하는가?

사용자에게 다른 입력을 요구하는 메시지가 표시되는가?

소프트웨어가 충돌하는가?

 

객체 지향 검사

코드를 실행하여 영구 객체의 상태가 변경되면 객체가 올바르게 업데이트되는가?

 

예를 들어보면, insert 함수, update 함수, delete 함수

이렇게 함수들이 있으면, 각 함수들이 잘 동작하는지  함수 하나하나를 테스트 하는 것이다.

 

이렇게 유닛 테스트는 전체 코드 중 작은 부분을 테스트하는 것이다. (예를 들어, 함수 하나하나 개별로 테스트 코드를 작성하는 것) 

또한, 유닛 테스트는 매우 간단하고 명확하여야 한다.

유닛 테스트를 사용한다면 어떤 함수(메소드)에 변화가 생겼을 때 그 함수가 안전하게 수행되는지를 보장해주고 같은 함수(메소드)를 다른 종류의 테스트에서도 적용하기 쉽게 만들어 준다.

유닛 테스트는 빈번히 일어나는 버그를 막는데도 뛰어난 역할을 한다.

 

단위 테스트에서 테스트 대상 단위의 크기는 엄격하게 정해져 있지 않지만, 일반적으로 클래스 또는 메소드 수준으로 정해진다. 

단위의 크기가 작을수록 단위의 복잡성이 낮아지므로 단위 테스트를 활용하여 동작을 표현하기 더 쉬워진다. 

즉, 테스트 대상 단위의 크기를 작게 설정해서 단위 테스트를 최대한 간단하고 디버깅하기 쉽게 작성해야 한다.

소프트웨어를 개발할 때, 소프트웨어 내부 구조나 구현 방법을 고려하여 개발자 관점에서 테스트한다. 

그러므로 단위 테스트는 소프트웨어 내부 코드에 관련한 지식을 반드시 알고 있어야 하는 화이트박스 테스트이다. 

단위 테스트는 TDD와 함께 할 때 특히 더 강력해진다.

 

TDD ( test-driven development )

여기서 TDD는 테스트 주도 개발(test-driven development)를 의미하고, 이는 소프트웨어 개발 방법론 중의 하나이다.

선 개발 후 테스트 방식이 아닌 선 테스트 후 개발 방식의 프로그래밍 방법이다.

다시 말해 먼저 자동화된 테스트 코드를 작성한 후 테스트를 통과하기 위한 코드를 개발하는 방식의 개발 방식을 말한다.


TDD를 이용한 개발방법

1. 테스트 케이스 작성
만들고 싶은 기능을 점검할 테스트 코드를 작성한다. 이때, 아직 기능 코드를 구현하지 않았으므로 테스트 결과는 실패로 반환된다. 실패하는 테스트를 가장 빠르게 구현하는 방법은 아무 값이나 반환하도록 하는 것이다.

2. 테스트 케이스를 통과하는 코드 작성
테스트 코드를 만족시킬 수 있는 기능을 구현한다. 테스트 통과를 최우선으로 생각하며 작업한다. 즉 단위 테스트를 통과할 수 있을 정도의 최소한의 코드만 작성한다.

3. 작성한 코드 리팩토링
기능의 성능이 향상되며, 재사용성이 좋고, 가독성이 좋은 코드로 기능 코드를 개선한다. 테스트 코드를 통해 다시 기능 코드를 점검한다.

→ 기능 테스트가 완전해질 때까지 2, 3의 과정을 반복한다.

TDD는 기본적으로 위 3단계의 반복으로 진행하며 점진적으로 개발이 진행된다. 필요한 단위 기능에 대한 테스트 코드를 먼저 작성한 후 테스트를 통과하도록 코드를 작성하는 것이다. 

 

 

 

통합 테스트 ( Integration Test )

통합 테스트는 서로 다른 시스템들의 상호작용이 잘 이루어 지는지 테스트하는 것이다.

 

예를 들면, 유닛 테스트에서 데이터베이스에 접근하는 코드는 실제 데이터 베이스와 통신하는 것은 아니지만, 통합 테스트는 실제 통신해야 한다. 통합 테스트는 유닛 테스트만으로 충분하다고 느끼지 못할 때 사용된다.

 

통합 테스팅은 서로 다른 애플리케이션이 얼마나 효율적으로 통합되는지 평가하도록 설계된 소프트웨어 테스팅 의 필수적인 측면입니다.

대부분의 현대 기업은 매일 여러 개의 서로 다른 소프트웨어 모듈에 의존하고 있으며 통합을 통해 이러한 응용 프로그램이 함께 작동하여 효율성을 개선하고 워크플로를 간소화할 수 있습니다.

원활한 통합이 소프트웨어 모듈을 효과적으로 만들기 때문에 통합 테스트가 중요합니다. 각 소프트웨어 모듈이 완전히 다른 프로그래밍 논리를 사용하여 다른 개발자에 의해 프로그래밍되면 별도의 모듈이 처음부터 원활하게 통합될 것이라고 생각할 이유가 없습니다.

통합 테스트를 통해 IT 전문가는 서로 다른 모듈이 얼마나 잘 함께 작동하는지 평가하고 효율성을 높이기 위해 변경 사항을 구현할 수 있다.

 

 

 

기능 테스트 ( Functional Test )

기능 테스트는 어떤 어플리케이션이 제대로 동작하는지 완전한 기능을 테스트하는 것을 의미한다.

 

예를 들어, 어떤 웹 어플리케이션을 기능 테스트한다고 가정해보면 브라우저 자동화 도구를 사용해 특정한 페이지를 클릭한다던가 하는 것이 기능 테스트라 할 수 있다.

유닛 테스트는 수백 가지가 있을 수 있지만 기능 테스트는 그렇지 않다.

기능테스트는 작성하기 매우 어렵고 높은 복잡성을 가지고 있기 때문에 많은 시간이 걸린다. (웹 어플리케이션을 가정하면 기능 테스트는 실제 사용자 상호 작용을 시뮬레이션하므로 페이지 로딩 시간조차도 기능 테스트의 한 요인이 된다)
그러므로 기능 테스트를 매우 세밀하게 나눠서 하면 좋지 않다.

대신 기능 테스트는 사용자와 앱의 상호작용을 테스트하고 싶을 때 유용하다. (예를들어, 게시글 작성과 같이 브라우저에서 앱의 특정 흐름을 수정으로 테스트 하는 경우) 

 

게시글 작성에 대한 기능 테스트라고 하면 유저가 게시글 작성을 마치고 "게시글이 등록이 완료되었습니다"라는 페이지를 올바르게 출력해줄 것을 보장해주어야 한다.

 

 


 

 

지금까지 테스트의 종류에 대해 이론적으로 알아보았다.

아직 직접 테스트를 진행해보지는 않았지만, 앞으로 해당 테스트들을 이용하여 내가 개발한 기능을 검증해보도록 해봐야겠다.