나는 좋은 온라인 자료 (이 주제에 관한 영어 위키 백과 기사는 개선 될 수없는 경향이 있음)를 가리킬 수 없지만, 기본적인 테스트 이론을 다루는 강의를 요약 할 수 있습니다.
테스트 모드
단위 테스트 또는 통합 테스트 와 같은 다양한 테스트 클래스가 있습니다 . 단위 테스트는 일관성있는 코드 조각 (함수, 클래스, 모듈)이 예상대로 작동한다고 주장하는 반면 통합 테스트는 그러한 여러 조각이 올바르게 함께 작동한다고 주장합니다.
테스트 사례는 특정 테스트 입력을 사용하거나 다른 클래스를 조롱하여 코드 조각이 실행되는 알려진 환경 입니다. 그런 다음 코드의 동작을 예상 된 동작 (예 : 특정 반환 값)과 비교합니다.
테스트는 버그의 존재 만 증명할 수 있으며 모든 버그가없는 것은 아닙니다. 테스트는 프로그램 정확성에 상한을 두었습니다 .
코드 범위
코드 커버리지 메트릭을 정의하기 위해 소스 코드를 각 노드에 코드의 선형 세그먼트가 포함 된 제어 흐름 그래프 로 변환 할 수 있습니다 . 제어는 각 블록의 끝에서만 이러한 노드 사이를 흐르며 항상 조건부입니다 (조건 인 경우 노드 A로 이동하고 그렇지 않으면 노드 B로 이동). 그래프 갖는 하나 개의 시작 노드와 하나 개의 엔드 노드.
- 이 그래프에서 명령문 범위 는 모든 방문한 노드 대 모든 노드의 비율입니다. 완전한 진술 범위는 철저한 테스트에 충분하지 않습니다.
- 분기 범위 는 CFG의 노드 간 방문 된 모든 에지 대 모든 에지의 비율입니다. 루프 테스트가 불충분합니다.
- 경로 적용 범위 는 모든 방문 경로와 모든 경로의 비율이며, 여기서 경로는 시작부터 끝 노드까지의 모든 가장자리 시퀀스입니다. 문제는 루프를 사용하면 무한한 수의 경로가있을 수 있으므로 전체 경로 적용 범위를 실제로 테스트 할 수 없다는 것입니다.
따라서 조건 범위 를 확인하는 것이 종종 유용합니다 .
- 에서 간단한 조건 범위 , 각 원자 상태는 한 번 true와 false 번이다 - 그러나 이것은 전체 문장 커버리지를 보장하지 않습니다.
- 에서 여러 조건 범위 , 원자 조건의 모든 조합에 촬영 한
true
과 false
. 이는 전체 지점 범위를 의미하지만 다소 비쌉니다. 프로그램에는 특정 조합을 제외시키는 추가 제한 조건이있을 수 있습니다. 이 기술은 브랜치 커버리지를 얻는 데 유용하고 데드 코드를 찾을 수 있지만 잘못된 조건 에서 발생하는 버그는 찾을 수 없습니다 .
- 에서는 최소한의 여러 조건에 따르면 , 각각 원과 합성 조건은 참과 거짓 번이다. 여전히 전체 지사 범위를 의미합니다. 여러 조건 범위의 하위 집합이지만 테스트 사례가 더 적습니다.
조건 범위를 사용하여 테스트 입력을 구성 할 때는 단락을 고려해야합니다. 예를 들어
function foo(A, B) {
if (A && B) x()
else y()
}
요구 사항은 테스트 할 foo(false, whatever)
, foo(true, false)
그리고 foo(true, true)
완벽하게 최소한의 여러 조건 적용.
여러 상태에있을 수있는 객체가있는 경우 흐름 제어와 유사한 모든 상태 전이를 테스트하는 것이 합리적입니다.
좀 더 복잡한 범위 메트릭이 있지만 일반적으로 여기에 제시된 메트릭과 유사합니다.
이들은 화이트 박스 테스트 방법이며 부분적으로 자동화 할 수 있습니다. 단위 테스트 스위트는 선택한 메트릭 으로 높은 코드 적용 범위를 목표로 하지만 100 %가 항상 가능한 것은 아닙니다. 특정 위치에 결함을 주입해야하는 예외 처리를 테스트하는 것은 특히 어렵습니다.
기능 테스트
그런 다음 구현을 블랙 박스로보고 코드가 사양을 준수 하는지 확인 하는 기능 테스트 가 있습니다. 이러한 테스트는 단위 테스트 및 통합 테스트 모두에 유용합니다. 가능한 모든 입력 데이터로 테스트 할 수 없기 때문에 (예 : 가능한 모든 문자열로 문자열 길이 테스트) 입력 (및 출력)을 동등한 클래스로 그룹화하는 것이 유용합니다 (올 length("foo")
바르면 올바른 경우 ) foo("bar")
. 입력과 출력 동등성 클래스 사이의 각 가능한 조합에 대해, 하나 이상의 대표 입력이 선택되고 테스트됩니다.
추가로 테스트해야합니다
- 에지의 경우
length("")
, foo("x")
, length(longer_than_INT_MAX)
,
- 언어에 의해 허용 아닌 함수의 계약에 의해되는 값
length(null)
, 및
- 가능한 정크 데이터
length("null byte in \x00 the middle")
...
숫자를 사용하면 이는 테스트를 의미 0, ±1, ±x, MAX, MIN, ±∞, NaN
하고 부동 소수점 비교는 두 개의 인접 플로트를 테스트합니다. 또 다른 추가로, 등가 클래스에서 무작위 테스트 값을 선택할 수 있습니다. 디버깅을 쉽게하려면 사용 된 시드를 기록해 두는 것이 좋습니다.
비 기능 테스트 :로드 테스트, 스트레스 테스트
소프트웨어에는 작동하지 않는 요구 사항이 있으므로 테스트해야합니다. 여기에는 정의 된 경계에서의 테스트 (부하 테스트)와 그 너머 (스트레스 테스트)가 포함됩니다. 컴퓨터 게임의 경우, 이것은로드 테스트에서 초당 최소 프레임 수를 주장 할 수 있습니다. 예상보다 두 배나 많은 방문자가 서버를 공격하는 경우 응답 시간을 관찰하기 위해 웹 사이트에 스트레스 테스트를 수행 할 수 있습니다. 이러한 테스트는 전체 시스템뿐만 아니라 단일 엔터티와도 관련이 있습니다. 해시 테이블이 어떻게 백만 항목으로 저하됩니까?
다른 종류의 테스트는 시나리오가 시뮬레이션되는 전체 시스템 테스트 또는 개발 계약이 이행되었음을 입증하는 승인 테스트입니다.
비 테스트 방법
리뷰
품질 보증에 사용할 수있는 비 테스트 기술이 있습니다. 연습, 공식 코드 검토 또는 페어 프로그래밍이 그 예입니다. 일부 부품은 자동화 될 수 있지만 (예 : 린터 사용) 시간이 많이 소요됩니다. 그러나 숙련 된 프로그래머의 코드 검토는 높은 버그 발견 속도를 가지며 자동화 된 테스트가 불가능한 설계 중에 특히 유용합니다.
코드 검토가 너무 좋은데 왜 여전히 테스트를 작성합니까? 테스트 스위트의 가장 큰 장점은 (대부분) 자동으로 실행될 수 있으며 회귀 테스트에 매우 유용하다는 것입니다 .
공식 검증
공식적인 확인은 가고 증명 코드의 특정 속성을. 수동 검증은 대부분 중요 부품에 대해 실행 가능하며 전체 프로그램에 대해서는 덜 유효합니다. 증명은 프로그램 정확성에 하한을 둡니다. 예를 들어 정적 유형 검사기를 통해 증거를 어느 정도 자동화 할 수 있습니다.
assert
명령문 을 사용하여 특정 불변량을 명시 적으로 확인할 수 있습니다 .
이러한 모든 기술은 그 자리에 있으며 보완 적입니다. TDD는 기능 테스트를 미리 작성하지만 일단 코드가 구현되면 커버리지 메트릭으로 테스트를 판단 할 수 있습니다.
테스트 가능한 코드 작성은 개별적으로 테스트 할 수있는 작은 코드 단위를 작성하는 것을 의미합니다 (적절한 세분성, 단일 책임 원칙을 가진 도우미 기능). 각 함수의 인수가 적을수록 좋습니다. 이러한 코드는 또한 예를 들어 의존성 주입을 통해 모의 객체를 삽입하는 데 적합합니다.
double pihole(double value) { return (value - Math.PI) / (value - Math.PI); }
에게서 배웠습니다 . 이 코드에는 정확히 하나의 구멍 이 있으며 블랙 박스 테스트만으로는 자동으로 검색 할 수 없습니다. 수학에는 그런 구멍이 없습니다. 미적분학에서는 한쪽 한계가 같으면 구멍을 닫을 수 있습니다.