개요
- 개발 테스팅(Development testing)
- 테스트 주도 개발(Test-driven development)
- 출시 테스트(Release testing)
- 사용자 테스트(User testing)
테스팅(testing)이란?
소프트웨어가 사람들에 의해 사용되기 전에 프로그램 결함들을 발견하고 프로그램이 무엇을 하는지를 보기 위한 과정이다
확인 그리고 결함 테스팅(Validation and defect testing)
- Validation testing
프로그램이 제대로 동작하는 지를 확인하기 위해 테스트 케이스를 만들고 테스트한다
- Defect testing
소프트웨어의 동작에 문제가 있거나 설계(Specification)에 맞지 않는 결함을 발견하는 것
위에 Fig.1 과 같이 비정상적인 인풋(Anomalous Behavior)을 넣으면 출력 결함의 존재(Presence of Defects)를 알 수 있다
Verification and Validation(V&V)
- Verification
우리가 제품을 제대로 만들고 있는지? (Are we building the product right?)
Verification의 목적은 소프트웨어가 명시된 기능 및 비기능 요구사항을 충족하는지 확인하는 것이다
- Validation
우리가 알맞은 제품을 만들었는지?(Are we building the product right?)
Validation의 목적은 소프트웨어가 고객의 기대에 부합하는지 확인하는 것입니다
V & V 신뢰(confidence)
- 소프트웨어 목적(Software purpose) - 신뢰(Confidence)를 결정하는 것은 소프트웨어가 목적에 맞는 동작을 하는지(기능, 신뢰성, 성능)
- 사용자 기대(User expectations) - 사용자는 처음에 적은 기대를 가지고 소프트웨어를 마주하는데, 이것을 만족시킬 수 있어야 한다
- 마케팅 환경(Marketing environment) - 제품을 일찍 시장에 내놓는 것이 프로그램의 결함을 찾는 것보다 더 중요할 수 있다
Inspections and testing(점검 그리고 테스트)
- 소프트웨어 점검(Software inspections)
오류나 결함을 발견할 목적으로 소스 코드를 읽는 사람들이 포함된다
Inspection은 시스템 실행(execution)을 요구하지 않기 때문에 구현전에 사용할 수 있다
시스템의 모든 표현을 적용할 수 있다(ex 요구사항, 설계, 구성 데이터, 테스트 데이터 등)
이러한 것들은 프로그램 오류를 발견하는 데 효과적인 기술인 것으로 나타났다
- 장점
- 테스팅을 하는 동안 에러는 또 다른 에러를 숨길 수 있는 반면, 점검은 정적 과정(static)이므로, 에러 간의 상호작용을 고려할 필요가 없다
- 불완전한 버전의 시스템은 추가 비용 없이 점검할 수 있다. 프로그램이 불완전한 경우 사용 가능한 부분을 테스트할 수 있는 특수한 테스트를 개발해야 한다
- 점검은 프로그램의 결합을 찾는 것뿐 아니라 표준 준수, 휴대성 및 유지보수성과 같은 프로그램의 광범위한 품질 속성도 고려할 수 있다
테스팅 단계(Stages of testing)
- 개발 테스팅(Development testing) - 개발 중에 버그나 결함을 발견하기 위해 사용되는 테스트
- 출시 테스팅(Release testing) - 출시 전에 별도의 테스트 팀이 완전한 버전의 시스템에서 테스트하는 것
- 사용자 테스팅(User testing) - 사용자 혹은 시스템의 잠재적인 사용자가 그들의 환경에서 테스트하는 것
개발 테스팅(Development testing)
시스템을 개발하는 데 수행되는 모든 테스팅 활동을 포함한다
- 유닛 테스팅(Unit testing) - 각각의 프로그램 유닛 혹은 객체 클래스가 테스트된다. 유닛 테스팅은 객체 혹은 메서드의 기능에 초점을 맞춰서 테스트해야 한다
- 구성요소 테스팅(Component testing) - 함수들이 다른 함수를 호출하거나 클래스가 다른 클래스의 메서드를 호출하는 것 같이 이러한 구성요소들이 상호작용을 잘하는지 테스트한다
- 시스템 테스팅(System testing) - 구성요소들이 모여져 있는 소프트웨어 최종단계에서 테스트한다
유닛 테스팅(Unit testing)
말 그대로 유닛 하나하나를 테스팅하는 것
여기서 유닛이란
객체 내부의 각각의 메서드(Method)나 기능(Function)을 말한다
객체 클래스와 몇몇의 속성(attributes) 그리고 메서드(Methods)
Java나 파이썬 같은 객체지향 언어를 공부해봤다면 쉽게 이해할 수 있다
객체 클래스 테스팅(Object class testing)
클래스가 가지고 있는 메서드들이 잘 동작하는지 확인하는 테스트
가능한 모든 상태에서 개체를 실행해본다
- 옆에 WeatherStation 클래스는 identifier이라는 한 개의 속성을 가지고 있다 그럼 우리는 이 속성이 알맞게 설정되었는지만 확인해보면 된다
- reportWeather(), reportStatus()과 같이 객체와 관련된 모든 메서드에 대한 테스트를 확인한다
- 메서드를 분리해서 테스트하는 것이 이상적이지만, 몇몇 케이스는 순차적으로 진행이 필요할 때가 있다
아래와 같이 상태 모델을 통해 테스트할 상태 전환의 순서와 이러한 전환을 유발하는 이벤트 순서를 식별한다
자동화 테스팅(Automated testing)
가능하다면, 유닛 테스팅을 자동화하여 수동 개입 없이 테스트를 실행하고 확인해야 한다
JUnit과 같은 테스트를 짜는 framework(라이브러리) 도 존재한다
유닛 테스트는 특정 테스트 사례를 만들기 위해 확장하는 일반 테스트 클래스를 제공한다
그런 다음 사용자가 구현한 모든 테스트를 실행하고 일부 GUI를 통해 다른 테스트의 성공 여부를 보고할 수 있다
자동화 테스팅 구성요소
- Setup part - 테스트 케이스와 같이 초기화되는 것, 다시 말해 Input과 예상하는 Output 파트
- Call part - 실행한 객체 혹은 메서드가 테스트되는 파트
- Assertion part - 실행한 결과가 맞는지 아닌지 확인하는 파트
테스팅 계획 ( Testing strategies)
Partition testing - 공통적인 특징의 inputs의 그룹을 정의하고 같은 방법으로 테스트가 진행되는 것
Guideline-based testing - 테스트 가이드라인을 사용하여 테스트 사례를 선택할 수 있다. 이때의 가이드라인은 프로그래머가 이전에 개발하면서 얻은 경험이다
분할 테스팅(Partition testing)
분할 테스팅에서 가장 주의 깊게 봐야 할 점은 동등 분할(Equivalence partition)이다
Fig. 6.Input 도메인 쪽에 원이 4개가 있는데, 회사에서 사원을 구분하기 위해서 사원번호는 4가지 정수로 이루어진다고 가정해보자 1 xxx는 임원 2 xxx는 본사 직원 3 xxx는 연구소 직원 그리고 4 xxx는 미지정으로 이루어진다고 가정하고 이때 동등 분할 기법으로 테스트를 한다고 하면 가장 적절한 입력값은 {1000,2000,3000,4000}이 될 수 있다
Fig. 7과 같이 경계선 쪽 파이션(9999,10000,99999,100000)과 중간 쪽의 파티션(50000)을 테스트 사례를 선택해서 테스트하는 것이 좋다
블랙박스 테스트와 화이트 박스 테스트(Block-box test and white-box test)
블랙 박스 테스트는 말 그대로 검은색 상자는 안을 들여다보면 아무것도 보이지 않는 것처럼, 소프트웨어의 내부구조와 작동 원리를 모르는 상태에서 동작을 검사하는 방식이다
즉 사용자가 App를 통해 이것저것 눌러보고 사용하는 방식이 블랙박스 테스트와 동일하다
기법으로는 동등 분할 기법이 포함된다
화이트 박스 테스트는 응용 프로그램의 내부 구조, 동작을 디테일하게 검사하는 테스트 방식이다
개발자 관점의 단위 테스팅 기법이 사용된다
구성요소 테스팅(Component testing)
소프트웨어 구성 요소는 종종 여러 상호 작용하는 객체로 구성된 복합 구성 요소다
정의된 구성 요소 인터페이스를 통해 이러한 객체의 기능에 접근할 수 있다
따라서 복합 구성 요소 테스팅은 구성요소 인터페이스가 설계서에 따라 동작한다는 것을 보여주는데 초점을 맞춰야 한다
인터페이스 테스팅(Interface testing)
목표는 인터페이스 오류 또는 인터페이스에 대한 잘못된 가정으로 인한 결함을 탐지하는 것이다
- (인자) Parameter interfaces - 하나의 메서드로부터 데이터가 다른 곳으로 자나 가는지
- (공유된 메모리) Shared memory interfaces - 메모리 블록은 절차와 함수 간에 공유된다
- (절차) Procedural interfaces - 하위 시스템은 다른 하위 시스템에서 절차의 집합을 캡슐화합니다
- Message passing interfaces - 하위 시스템은 다른 하위 시스템에서 서비스를 요청합니다
시스템 테스팅(System testing)
구성 요소 간의 상호작용에 초점을 맞추고 테스트한다
구성 요소가 전부 모여져 있는 소프트웨어 개발 최종단계에서 테스트를 진행한다
여기서는 유즈 케이스 테스트가 도움을 줄 수 있다
시퀀스 다이어그램(Sequence Diagram)은 필요한 입력과 생성된 출력을 보여주기 때문에 필요한 특정 테스트 사례를 설계하는 데 도움이 된다
테스트 주도 개발(Test-driven development)
애자일(Agile)과 같은 최근 개발 방식에서 많이 사용된다
내가 구현할 코드에 대한 결과를 기반으로 테스트할 프로그램을 먼저 만들고 그다음 프로그램을 만드는 것
- 무엇을 테스트해야 할지 기능을 정의한다
- 이 기능을 위한 테스트를 작성한다
- 테스트를 실행하면 당연히 실패한다. (아직 코드가 구현되지 않은 상태)
- 기능을 구현하고 다시 실행합니다
- 모든 테스트가 성공적으로 실행되면 다음 기능의 정의로 이동합니다
장점
- Code coverage - 개발 프로세스에서는 보통 인수 테스트를 하는데, 이미 배치된 시스템을 대상으로 클라이언트가 의뢰한 소프트웨어가 사용자 관점에서 사용할 수 있는 수준인지 체크하는 과정이다. 이미 90% 이상 완성된 코드를 가지고 테스트하기 때문에, 문제를 발견해도, 정확하기 원인이 무엇인지 진단하기 힘들다. 하지만 TDD를 사용하면 기능 단위로 테스트를 진행하기 때문에 코드가 모두 완성되어 개발자를 떠나기 전에 피드백을 받을 수 있다
- Regression testing - 회귀 테스트 세트 프로그램이 개발됨에 따라 점진적으로 개발된다
- Simplified debugging - 특정 버그를 손쉽게 찾아낼 수 있다
- System documentation - 테스트 자체는 코드가 수행해야 하는 작업을 설명하는 문서의 한 형태가 될 수 있다
출시 테스트(Release testing )
- 출시 테스트는 말 그대로 프로그램이 개발자 팀을 떠나 사용자 입장에서 테스트하는 것
- 사용자가 한 요청에 따라 응답이 잘 오는지에 대해서만 테스트를 진행하는 것
- 위에서도 찾아볼 수 있듯이, 사용자는 프로그램의 세부사항을 모르는 상황에서 테스트를 하는 것이기 때문에 Black-box testing 과정이라고 할 수 있다
- 개발팀이 아닌 전담팀이 따로 꾸려져서 검증을 담당한다
요구사항 기반 테스트(Requirements based testing)
이전 강의에서 배웠던 요구사항 안에 여러 가지 가설에 대해서 테스트를 하는 것
Fig. 10 에서와 같이, 환자가 알레르기가 없는 경우 별도의 Warning 메시지가 생성되지 않는다 -> 알러지가 없는 임의의 환자 정보를 입력해서 확인해 본다
이러한 시나리오는 현실적이어야 하며 실제 시스템 사용자는 시나리오와 관련이 있어야 한다
성능 테스트(Performance testing)
제한된 사용자 정원에 따라 제한사항들이 잘 처리되는지 확인한다
접속에서 만약 1000명까지라고 한다면 1000명까지는 받고 나머지는 받지 않는 이러한 행위가 이루어지는지 가상의 부하(Stress testing)를 걸어 테스트한다
사용자 테스트(User testing)
사용자 테스트는 사용자가 시스템 테스트에 대한 입력 및 조언을 제공하는 테스트 과정의 단계이다
사용자 테스트가 중요한 이유는 사용자의 작업 환경의 영향이 시스템의 신뢰성, 성능, 사용성 및 견고성에 큰 영향을 미치기 때문이다
- 알파 Alpha testing - 선별한 사용자를 모아서 그들에게 의견을 묻는다. 돈을 주고 개발자에게 요구했던 그룹에게 테스트를 진행한다
- 베타 Beta testing - 소프트웨어에 정보를 가지고 있지 않고 기존의 소프트웨어를 사용해 오던 사람들을 기반으로 테스트한다
- 허가 Acceptance testing - 제대로 된 테스트가 진행되었음을 확인해주는 테스트
허가 테스트 과정(Acceptance testing process)
- Define acceptance criteria : 이상적으로는 시스템에 대한 계약이 체결되기 전에 프로세스 초기에 이루어져야 한다. 실제로 세부 요구사항을 사용할 수 없을 수 있고 개발 과정 중에 상당한 요구사항이 변경될 수 있다
- Plan acceptance testing : 테스트에 대한 계획(인력, 시간, 비용)을 세운다. 또한 요구사항의 적용범위, 시스템 기능이 테스트되는 순서, 테스트 프로세스에 대한 위험 논의가 포함된다
- Derive acceptance tests : 합격 기준이 설정되면, 시스템이 합격 여부에 대한 테스트를 설계한다. 이 과정에서는 시스템의 기능적 특성과 비기능적 특성(성능)을 모두 시험하는 것을 목표로 해야 한다
- Run acceptance tests : 합의된 acceptance test가 시스템에서 실행된다. 이상적으로 시스템이 사용될 실제 환경에서 실행됩니다
- Negotiate test results : 테스트를 모두 통과해 문제가 없을 가능성은 매우 낮다. 개발자와 고객은 시스템이 사용할 수 있을 만큼 충분히 좋은지 여부를 결정하기 위해 협상해야 한다
- Reject/accept system : 여기서 시스템의 수용 여부를 결정한다. 시스템이 사용하기에 충분하지 않으면, 확인된 문제를 해결하기 위해 추가 개발이 필요하다
Reference
[소프트웨어공학] 8장 Software Testing
실제 개발한 소프트웨어를 실험하고 검증하는 단계 주요의제 Development testing(개발에서 테스트가 무엇인지) Test-driven development(민감한 소프트웨어를 짤 때 많이 사용됨) Release testing(실제 사용자에
rainbow97.tistory.com