블랙박스 테스팅 :
소프트웨어의 내부 구조나 동작 원리를 모르는 상태에서, 사용자의 입장에서 동작을 검사하는 방법입니다. 이러한 방식의 테스팅은 다음과 같은 장점과 단점을 가지고 있습니다.
- 장점:누구나 테스트를 수행할 수 있습니다. 개발자뿐만 아니라 디자이너, 베타 테스터, 관리자 등 누구나 소프트웨어의 동작을 검사할 수 있습니다.
- 단점:기능이 증가할수록 테스트의 범위가 증가합니다. 새로운 기능이 추가될 때마다 해당 기능을 테스트해야 하므로 테스트의 양이 계속해서 증가할 수 있습니다.테스트를 수행하는 사람에 따라 테스트 품질이 다를 수 있습니다. 테스트하는 사람의 능력과 경험에 따라 테스트의 정확성과 완전성이 달라질 수 있습니다. 이러한 이유로 QA(Quality Assurance) 직군이 필요한 이유도 있습니다.
개발자 테스트 :
개발자가 작성한 코드를 검증하기 위해 테스트 코드를 작성합니다. 코드의 예상 동작과 실제 동작을 비교하여 테스트를 수행합니다.
장점:
- 빠르고 정확한 테스트가 가능합니다. 테스트 코드를 실행하여 예상한 결과와 실제 결과를 비교함으로써 결함을 빠르게 발견할 수 있습니다.
- 테스트 자동화가 가능합니다. 테스트 코드를 자동으로 실행하여 동작을 검증할 수 있으며, 배포 시 자동화된 테스트가 동작을 검증하는 데 도움이 됩니다.
- 리팩토링이나 기능 추가 시 편리합니다. 테스트 코드가 있으면 코드 변경에 따른 영향을 빠르게 파악하여 수정할 수 있습니다.
단점:
- 개발 시간이 더 오래 걸립니다. 테스트 코드를 작성하는 데에는 추가적인 노력과 시간이 필요합니다.
- 테스트 코드를 유지보수해야 합니다. 코드 변경에 따라 테스트 코드도 함께 수정해야 하므로 유지보수 비용이 증가할 수 있습니다.
단위 테스트 (Unit Test):
개별 모듈 또는 함수 단위로 테스트를 수행합니다. 모듈 내부의 세부 로직과 동작을 검증합니다.
개발 초기 단계부터 개별 모듈을 테스트하며, 빠르게 실행하고 결함을 발견하는 데 유용합니다.
장점:
- 세밀한 부분까지 테스트가 가능합니다. 모듈의 각각의 기능을 개별적으로 확인하여 결함을 찾을 수 있습니다.
- 코드 일관성과 안정성을 높일 수 있습니다. 각 모듈이 독립적으로 동작하면서 예상한 대로 작동하는지 확인할 수 있습니다.
단점:
- 모듈 간의 상호작용을 검증할 수 없습니다. 모듈 간의 연결과 상호작용에서 발생하는 오류를 찾기 어렵습니다.
통합 테스트 (Integration Test):
두 개 이상의 모듈을 연결하여 테스트합니다. 모듈 간의 상호작용과 통합에서 발생하는 오류를 검증합니다.
모듈 간의 상호작용이 복잡하고 중요한 시스템에서 사용되며, 시스템 전체적인 동작을 확인합니다.
장점:
- 모듈 간의 연결에서 발생하는 에러를 검증할 수 있습니다. 여러 모듈이 함께 동작할 때 발생하는 문제를 찾아낼 수 있습니다.
단점:
- 테스트 코드 작성이 복잡하고 어려울 수 있습니다. 여러 모듈을 연결하고 상호작용을 검증해야 하기 때문에 테스트 코드 작성이 복잡해질 수 있습니다.
- 테스트 시나리오의 다양성에 대한 처리가 어렵습니다. 다양한 상황과 조건을 고려하여 테스트를 수행하기 어려울 수 있습니다.
E2E 테스트 (End-to-End Test):
실제 사용자의 관점에서 전체 시스템을 테스트합니다. 사용자의 흐름에 따라 실제 환경에서 애플리케이션이 예상대로 동작하는지 검증합니다.
실제 사용자 경험을 반영하고, 시스템의 완전한 동작을 검증하는데 사용됩니다. 다만, 구축과 유지보수가 복잡하며 시간이 많이 소요될 수 있습니다.
장점:
- 실제 사용자 환경에서 테스트하기 때문에 실제 상황을 재현할 수 있습니다. 다양한 플랫폼, 단말기, 네트워크 등 다양한 환경에서의 동작을 확인할 수 있습니다.
- 사용자의 관점에서 테스트하기 때문에 사용자 경험을 중심으로 평가할 수 있습니다.
단점:
- 다양한 테스트 환경 구성이 어렵습니다. 다양한 단말기, 운영체제, 브라우저 등 다양한 조합에 대한 테스트를 구성하기 어려울 수 있습니다.
- 테스트 시나리오가 복잡해질 수 있습니다. 사용자 흐름에 따라 다양한 시나리오를 작성하고 관리해야 하므로 테스트 코드 작성이 복잡해질 수 있습니다.
단위 테스트 코드 작성 시의 장점과 단점 :
장점:
- 결함을 빨리 찾을 수 있습니다: 단위 테스트 코드는 코드 일부분을 실행하여 오류를 찾아낼 수 있습니다. 따라서 결함을 빨리 찾을 수 있으며 빠르게 수정할 수 있습니다.
- 코드 품질 향상: 단위 테스트 코드는 소프트웨어의 코드 품질을 향상시키는 데 도움이 됩니다. 테스트 코드를 작성하면 코드가 보다 정확하고 일관성 있게 작성됩니다.
- 유지보수성 개선: 단위 테스트 코드는 코드 변경에 대한 영향도를 파악하며, 변경이 필요한 부분을 빠르게 파악하여 수정할 수 있습니다. 이는 유지보수성을 높이는 데에 큰 도움이 됩니다.
- 문서화: 단위 테스트 코드는 코드를 문서화하는 데에도 도움이 됩니다. 각 테스트 케이스는 코드의 사용 예제가 될 수 있으며, 이를 통해 코드 사용 방법을 쉽게 이해할 수 있습니다.
단점:
- 추가 작업이 필요합니다: 단위 테스트 코드를 작성하는 데에는 추가적인 노력이 필요합니다. 코드 자체를 작성하는 것 이외에도 각 코드 조각에 대한 테스트 케이스를 작성해야 합니다.
- 테스트 케이스가 모든 오류를 포착하지 못할 수 있습니다: 모든 상황을 대비한 테스트 케이스를 작성하기 어렵기 때문에, 단위 테스트는 모든 오류를 포착하지 못할 수 있습니다.
- 작성 비용이 높을 수 있습니다: 대규모 프로젝트에서는 수많은 단위 테스트 케이스를 작성해야 하므로, 작성 비용이 높아질 수 있습니다.
- 유지보수 비용이 높을 수 있습니다: 코드 변경 시에는 테스트 케이스도 수정해야 하므로, 유지보수 비용이 높아질 수 있습니다.
TDD(Test-Driven Development)와 BDD(Behavior-Driven Development) :
소프트웨어 개발 방식 중 하나로, 테스트 중심의 개발 프로세스를 강조하지만, 접근법은 약간 다릅니다.
TDD는 코드 수준에서의 테스트 중심 개발이라면, BDD는 시스템의 동작 및 비즈니스 요구사항에 초점을 맞춘 테스트 중심 개발입니다.
TDD (Test-Driven Development) :
TDD는 작은 단위의 테스트를 먼저 작성하고, 이 테스트를 통과할 수 있도록 코드를 작성하는 방식입니다. 이 방식의 목표는 요구사항이 변경되거나 추가되더라도 소프트웨어의 품질을 유지하는 것입니다.
TDD의 일반적인 절차는 다음과 같습니다:
- 먼저 실패하는 단위 테스트를 작성합니다.
- 테스트를 통과할 수 있도록 충분한 코드를 작성합니다.
- 작성된 코드를 리팩토링합니다.
BDD (Behavior-Driven Development) :
BDD는 TDD의 한 종류로 볼 수 있지만, BDD는 시스템의 동작에 중점을 둡니다. BDD는 비개발자(예: 비즈니스 분석가, 이해당사자 등)와 개발자가 협업할 수 있도록 테스트 케이스를 자연어 스타일로 작성하는 것을 강조합니다.
BDD의 주요 절차는 다음과 같습니다:
- 예상되는 행동에 대해 테스트를 작성합니다. 이는 비즈니스 요구사항을 기반으로 하며, 주로 사용자 스토리와 같은 형식을 사용합니다.
- 해당 행동을 구현할 수 있도록 코드를 작성합니다.
- 코드를 리팩토링합니다.
결국, TDD와 BDD 모두 테스트 중심의 개발을 추구하지만, BDD는 시스템의 행동에 중점을 두고 비개발자와의 협업을 강조하며, TDD는 개발자가 테스트를 기반으로 코드를 작성하도록 강조합니다. 이 둘 사이의 선택은 프로젝트의 요구사항, 팀의 선호도, 그리고 소프트웨어의 복잡성 등에 따라 달라질 수 있습니다.
코드를 먼저 작성하고 테스트를 나중에 하는 접근법은 TDD나 BDD와는 반대되는 방향입니다. 이런 방식은 코드의 품질을 보장하기 어렵고, 나중에 문제가 발생했을 때 이를 찾고 수정하는 데 더 많은 시간과 노력이 필요하게 됩니다. 따라서 가능하면 TDD나 BDD와 같은 테스트 중심의 개발 방식을 적용하는 것이 좋습니다.
기능을 먼저 구현하고 그 후에 테스트 코드를 작성하는 접근법을 "테스트-후(Test-Last)" 개발 또는 "전통적인" 개발 방법이라고 부릅니다. 이 방법은 전통적인 소프트웨어 개발 프로세스에서 일반적으로 볼 수 있습니다.
이런 접근법에서는 개발자가 요구사항에 따라 기능을 먼저 개발하고, 그 후에 해당 기능을 검증하는 테스트 케이스를 작성합니다. 이 방식의 단점은 코드가 작성된 후에만 테스트가 가능하다는 것이며, 따라서 버그를 일찍 찾아내는 것이 더 어려울 수 있습니다.
반면에, TDD(Test-Driven Development)나 BDD(Behavior-Driven Development)와 같은 테스트-먼저(Test-First) 접근법에서는 테스트 케이스를 먼저 작성하고, 그 테스트 케이스를 통과하는 코드를 작성합니다. 이 접근법의 장점은 테스트를 통해 요구사항을 명확히 정의하고, 즉시 피드백을 받을 수 있다는 것입니다.
- 프로젝트의 특성: TDD나 BDD는 많은 이점을 제공하지만, 모든 프로젝트에 적합한 것은 아닙니다. 예를 들어, 프로젝트 요구사항이 자주 변경되지 않고, 프로젝트의 복잡성이 낮을 경우, 전통적인 개발 방법을 사용하는 것이 더 효율적일 수 있습니다.
- 팀의 경험과 역량: 팀원들이 TDD나 BDD에 익숙하지 않다면, 이러한 접근법을 도입하는 데 시간과 노력이 필요할 수 있습니다. 이런 경우, 팀의 경험과 역량을 최대한 활용하여 전통적인 개발 방법을 사용하는 것이 더 합리적일 수 있습니다.
- 시간 제약: 테스트 주도 개발은 초기에 투자해야 하는 시간이 더 많습니다. 이런 접근법은 장기적으로는 높은 품질의 코드와 유지 관리의 용이성을 제공하지만, 단기적으로는 개발 시간이 늘어날 수 있습니다. 따라서, 시간 제약이 있는 프로젝트에서는 전통적인 개발 방법을 선택할 수 있습니다.
테스트 코드를 작성하는 가장 대표적인 방법론 : Given - 준비 When - 실행 Then - 검증
이 방법론은 행동 주도 개발(BDD)에서 널리 사용되는 테스트 패턴입니다.
- Given: 테스트의 사전 조건을 설정합니다. 이는 테스트가 진행될 환경이나 상태를 의미합니다.
- When: 테스트의 주체가 특정 행동을 실행하는 단계입니다.
- Then: When 단계에서의 행동이 주어진 사전 조건(Given) 하에서 예상한 결과를 나타내는지 검증하는 단계입니다.
JUnit :
JUnit은 자바에서 가장 널리 사용되는 테스트 프레임워크로, 개발자가 쉽게 단위 테스트를 작성하고 실행할 수 있게 도와줍니다. 테스트 케이스는 서로 독립적으로 작성되어야 하며, 이러한 원칙은 테스트의 견고성과 신뢰성을 보장합니다.
이상적으로, 각 테스트 케이스는 서로 분리되어야 한다. 이를 위해 가짜 객체(Mock object)를 생성하는 것도 좋은 방법이다.
Mock Object :
Mock 객체는 테스트에서 실제 객체의 역할을 대체합니다. Mock 객체를 사용하면 외부 시스템에 의존하지 않고 테스트를 수행할 수 있습니다. 예를 들어, 데이터베이스나 네트워크와 같은 외부 시스템과의 상호작용을 모방할 수 있습니다.
Mock 객체를 만들려면 일반적으로 해당 객체를 구현하는 인터페이스나 클래스를 직접 생성해야 합니다. 이 경우 모든 메소드의 동작을 직접 구현하거나 오버라이드해야 하므로, 복잡한 객체를 mocking할 경우 상당히 번거로울 수 있습니다.
- 실제 객체와 겉만 같은 객체입니다. 동일한 클래스명, 함수명
- 실제 DB 작업은 하지 않습니다.
Mockito :
Mockito는 자바에서 가장 널리 사용되는 mocking 프레임워크 중 하나입니다. Mockito를 사용하면 실제 객체 대신 Mock 객체를 쉽게 생성하고, 행동을 정의하고, 검증할 수 있습니다. 이를 통해 개발자는 시스템의 다른 부분과 독립적으로 특정 부분을 테스트할 수 있습니다.
'Spring' 카테고리의 다른 글
클래스(Class)와 인스턴스(Instance), 클래스 상속 (0) | 2023.06.06 |
---|---|
AOP, Interceptor, Filter (0) | 2023.06.06 |
AOP(Aspect-Oriented Programming) (0) | 2023.05.29 |
Transaction, Primary, Replica (0) | 2023.05.29 |
스프링 프레임워크(Spring Framework), 생성자 주입, Singletone Bean (0) | 2023.05.25 |