테스트
테스트는 프로그래밍에 있어 너무나 중요한 부분이다.
특히 알고리즘이 관련된 복잡한 프로그래밍에 있어서는, 코드를 눈으로만 읽어서 그 결과값을 예측하는 것이 한계가 있기에, 여려 경우의 수를 고려하여 직접 실행결과를 확인해보는 것이 매우 중요하다. 따라서, 작성하는 함수마다 그 함수가 원래 계획했던 대로 잘 동작하는 지 확인할 수 있는 테스트코드를 만들어서 확인한다. 잘 만들어진 테스트코드는, 향후 만들어 놓았던 함수의 내부 코드를 변경해야만 할 때, 자신있게 코드를 바꿀 수 있게 해준다. 제대로 동작하는지의 여부를 테스트코드가 보장해주기 때문이다.
이번 장에서는 앞 장에서 만든 add와 increase함수를 테스트하는 코드를 설명하겠다. 그와 더불어, 테스트의 입력값을 편하게 해주는, 그리고 결과값의 확인을 위해서 필요한 몇가지 도우미 함수들이 필요한대, 이 부분에 대해서도 작성하도록 하겠다.
도우미 함수들
함수를 테스트한다는 것은, 여러가지 테스트케이스에 따라 입력값을 주고, 결과값이 예상값과 맞는 지 확인하는 것이다.
add와 increase의 경우 입력값으로 BIGINT형 값을 넘겨줘야 하는데, 이 BIGINT는 INT형 배열이다. 즉, INT형 배열을 아래와 같이 길게 정의한다음 그것을 넘겨줘야 한다.
BIGINT a, b, c; //a: 3333 4444 aabb ccdd a[0]=2; a[1] = 0xaabbccdd; a[2] = 0x33334444; //b: 1122 3344 5566 7788 99aa bbcc b[0]=3; b[1] = 0x99aabbcc; b[2] = 0x55667788; b[3] = 0x11223344; //c = a + b // a: 3333 4444 aabb ccdd // b:1122 3344 5566 7788 99aa bbcc // c:1122 3344 8899 bbcd 4466 88a9 add(a,b,c);
만약, hexa 스트링 형태를 BIGINT형으로 변환시켜주는 함수가 있다면, 테스트용 코드가 간단해질 것이다. 즉,
BIGINT a,b,c;
a = hexstr2bigint("33334444aabbccdd");
b = hexstr2bigint("112233445566778899aabbcc");
add(a,b,c);
위와 같이 hex string을 BIGINT로 변환하는 함수인 hexstr2bigint를 포함해서, 아래와 같은 도우미 함수들을 작성했다.
- BIGINT관련 도우미 함수들 (bigint.c내에 포함)
- compare_big, increase, negative, hexstr2bigint, hexstr2bytes, bytes2bigint, bigint2hexstr, copy_big, setmax, complement, isPositive
- 일반 도우미 함수들 (doumi.c에 포함)
- do_reverse, do_len, do_hex2num, do_power, do_int2hexchar, do_copy, do_compare
코드내용은 <부록3> 참조
*이번 장에 대한 전체 소스안에도 이 도우미 함수들이 포함되어 있음
*도우미함수로 increase가 들어 있는데, 이는 negative함수내에서 사용되기 때문에, 연산함수임에도 불구하고 할 수 없이 도우미함수로 넣어 둠
add함수에 대한 테스트 벡터 작성
add함수에 대해서 어떤 테스트를 하면 될까?
더 만들어 낼 수 도 있겠지만, 다음 9가지 테스트케이스를 생각해 볼 수 있겠다.
*테스트벡터: 테스트를 하는 각 경우의 수에 대한 입력값 및 결과값을 테스트벡터라 한다.
1)작은 수에 대한 연산: 0x01 + 0x01
2)자릿수가 a>b인 경우
3)자릿수가 a<b인 경우
4)자릿수가 같은 경우
5)항등원 0과의 합
6)(양수 + 음수) > 0
7)(양수 + 음수) < 0
8)(양수 + 양수) : overflow
9)(음수 + 음수): overfloww
이 아홉가지 케이스에 대해서 어떻게 테스트 코드를 만드는 지 차례차례로 보도록 하자.
먼저, test.c파일을 만들어서 main함수를 만들자. 그러면, 소스파일은 앞장 및 부록3까지 만든 bigint.c doumi.c와 함께 test.c가 존재하게 된다.
main함수에는 아래와 같이 코딩.
void main(){
printf("01. test_add: ");
if(test_add() == 0){
printf("OK");
}else{
printf("Fail");
}
printf("\n\n");
getchar();
}
main함수를 보면, test_add를 호출하고, 그 결과값을 보고서 테스트가 성공했는 지를 확인하고 있다. 향후에 빼기, 곱하기 등의 함수를 만들면, 그 함수들을 이어서 호출해서 테스트하면 될 것이다.
실제 add함수를 테스트하는 함수는 test_add이다. 이 함수의 코드는 다음과 같다.
int test_add(){ BIGINT a,b,c; BIGINT expected; int result=-1; int i; //1. 작은 수에 대한 연산 hexstr2bigint("01",a); hexstr2bigint("01",b); hexstr2bigint("02",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //2. 자릿수가 a>b의 경우 //112233445566778899aabbcc // 112233445566 //11223344556688aaccef1132 hexstr2bigint("112233445566778899aabbcc",a); hexstr2bigint("112233445566",b); hexstr2bigint("11223344556688aaccef1132",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //3. 자릿수가 a<b의 경우 hexstr2bigint("112233445566",a); hexstr2bigint("112233445566778899aabbcc",b); hexstr2bigint("11223344556688aaccef1132",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //4. 자릿수가 같은 경우 hexstr2bigint("ff112233445566778899aabbcc",a); hexstr2bigint("ff112233445566778899aabbcc",b); hexstr2bigint("01fe22446688aaccef1133557798",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //5. 항등원 0과의 합 hexstr2bigint("ff112233445566778899aabbcc",a); b[0]=0; hexstr2bigint("ff112233445566778899aabbcc",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //6. (양수 + 음수) > 0 hexstr2bigint("112233445566778899aabbdd",a); hexstr2bigint("-112233445566778899aabbcc",b); hexstr2bigint("11",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //7. (양수 + 음수) < 0 hexstr2bigint("112233445566778899aabbcc",a); hexstr2bigint("-112233445566778899aabbdd",b); hexstr2bigint("-11",expected); add(a,b,c); result = compare_big(c,expected); if(result != 0) return result; //8. (양수 + 양수): overflow a[0] = MAX_INT_LEN; b[0] = MAX_INT_LEN; for(i=1;i <= MAX_INT_LEN;i++){ a[i]= (INT)(do_power(2, sizeof(INT)*8-1) - 2); b[i]= (INT)(do_power(2, sizeof(INT)*8-1) - 3); } result = add(a,b,c); if(result != E_Overflow) return -1; //9. (음수 + 음수): overflow a[0] = MAX_INT_LEN; b[0] = MAX_INT_LEN; a[MAX_INT_LEN] = (INT)(do_power(2, sizeof(INT)*8-1) + 2); b[MAX_INT_LEN] = (INT)(do_power(2, sizeof(INT)*8-1) + 3); for(i=1;i < MAX_INT_LEN;i++){ a[i]= 0; b[i]= 0; } result = add(a,b,c); if(result != E_Overflow) return -1; return 0; }
test_add함수를 보면, add함수를 테스트하기 위해 생각해뒀던 아홉가지 케이스에 대해서 구현했음을 알 수 있을 것이다.
여기서 입력값으로 a,b를 설정하는 부분에는, hex형태의 문자열을 BIGINT로 변환해주는 hexstr2bigint함수를 써서 간편하게 되었다.
hexstr2bigint("112233445566778899aabbcc",a); hexstr2bigint("112233445566",b);
두 수 a와 b의 합은 "1122334455667788aaccef1132"가 되야한다. 결과값이 예상값과 일치하는지 자동으로 확인하기 위해서, expected변수에 나와야될 결과값을 넣어두고, 실제 add함수에 의해 계산된 c 값을 비교해서, add함수가 제대로 동작되는지 확인한다.
hexstr2bigint("11223344556688aaccef1132",expected);
add(a,b,c);
result = compare_big(c,expected);
여기서 compare_big함수는, 두 BIGINT값이 같으면 0, c가 크면 1, c가 작으면 -1을 리턴한다. 따라서, add함수가 제대로 구현되었다면 compare_big(c,expected)은 0(zero)을 리턴할 것이다.
add함수에 의한 결과값과 예상값이 다르다면, test_add함수 수행이 멈춰지고 0이 아닌 값을 리턴한다. main함수에서는 test_add함수가 0이 아닌 수를 리턴하므로 테스트가 실패했음을 표출하고 프로그램 종료하게 된다.
increase에 대한 테스트벡터
다음과 같은 테스트벡터를 생각할 수 있겠다.
1) increase from 0 -> 1
2) increase from 1 -> 2
3) 일반적인 BIGINT값에 대한 increase: A -> A+1
4) MAX에 대한 increase
전체 소스
add, increase함수 및 두 함수를 테스트하는 코드가 들어 있는, 풀 소스는 아래 파일 참조. (Visual Studio용 프로젝트)
Viaual Studion에 로드해보면 002.Add_Test라는 솔루션이 보이고, bigint.c에 구현된 add함수를 테스트하는 test.c파일이 보일 것이다.
실행해서 다음과 같은 화면이 뜨면 성공.
'암호화프로그래밍 > (Old)C-BIGINT' 카테고리의 다른 글
010. 감소(decrese) (0) | 2013.07.30 |
---|---|
009. 뺄셈(subtract) (0) | 2013.07.30 |
007. 증가(increse) (0) | 2013.07.29 |
006. 덧셈(add) (0) | 2013.06.20 |
005. 큰 수에 대한 프로그래밍 (0) | 2013.06.19 |