Open gaepury opened 4 years ago
어려운 이유
절차적 프로그램에서 모듈 단위를 식별하기 아주 어려움 합성을 통해 조립 가능한, 테스트 가능한 비즈니수 단위로 나눌 수 있음
단위 테스트는 독무대(sandbox)에서 작동햐야함 시스템 상태는 정확히 테스트 전 상태를 유지해야함
단위 테스트는 순서를 바꿔도 결과가 같아야함 (결합적commutative 해야함)
함수형 코드를 테스트하면 이로운점 설명
함수를 독립적으로 작성 => 부수효과 없음 => 임의 순서 결과 동일 예제 : https://jsfiddle.net/d4p86Lgy/1/
4.6절 함수 조합기를 사용하여 설계 분해 과정으로 구현 => 주요 로직 개별 함수만 테스트 하면됨 예제 : https://jsfiddle.net/d4p86Lgy/2/ 예제 설명
showStudent 함수형 버전 ( 합성 및 모나드 이용 재조립)
const showStudent = R.compose(
map(append('#student-info')),
liftIO,
getOrElse('학생 찾을 수 없음'),
map(csv),
map(R.props(['ssn','firstname','lastname'])),
chain(findStudent),
chain(checkLengthSsn).
lift(cleanInput)
);
테스트성 분석
믿음성 있는 함수에 대한 테스트 : https://jsfiddle.net/d4p86Lgy/4/
findStudent만 남음. 어떻게 테스트? mock object 기법으로 관리
mocking은 외부 디펜던시 제어/단언 하여 모방하는데 쓰임. 부수효과 다루기 좋은 기법 이책에서는 Sinon.js 사용 https://jsfiddle.net/changcc/wcsdh6Lu/
함수에 어떤 입력을 넣으면 어떤 출력이 나와야 맞는지 성명한다.
JSCheck 소개.
JSC.claim(이름, 술어, 특정자, 분류자)
예제
JSC.clear();
JSC.on_report((str) => console.log(str));
JSC.test(
'평균 학점 계산',
function (verdict, grades, grade) {
return verdict(computeAverageGrade(grades) === grade);
},
[
JSC.array(JSC.integer(20), JSC.number(90,100)),
'A'
],
function (grades, grade) {
return '평균 ' + grade + ' 학점에 관한 테스트: ' + grades;
}
);
expect(0);
QUnit과 연연동하여 사용
/**
QUnit.test('SSN에 대한 JSCheck 커스텀 특정자', function (assert) {
// 테스트 대상 함수
const validLength = (len, str) => str.length === len;
const find = R.curry((db, id) => db.find(id));
const checkLengthSsn = ssn => {
return Either.of(ssn)
.filter(R.partial(validLength, [11]))
.isRight;
};
JSC.clear();
JSC.on_report((report) => console.log('리포트' + str));
JSC.on_pass((object) => assert.ok(object.pass));
JSC.on_fail((object) =>
assert.ok(object.pass || object.args.length === 11, '테스트 실패: ' + object.args));
JSC.test(
'SSN 길이를 체크',
function (verdict, ssn) {
return verdict(checkLengthSsn(ssn));
},
[
JSC.SSN(JSC.integer(100, 999), JSC.integer(10, 99),
JSC.integer(1000, 9999))
],
function (ssn) {
return '커스텀 SSN 테스트: ' + ssn;
}
);
expect(0);
});
code coverage 측정 Blanket.js 사용 동작 과정
p227 페이지 명령형 버전 : 80% 함수형 버전 : 100%
명령형 버전 : 40% (if-else 갈래로 흩어짐) 함수형 버전 : 80% (입력값에 의존하는 함수만 건너 뜀) => 심리적 안정감줌?
순환 복잡도 : 함수의 선형 독립적인 경로의 개수를 측정하기 위한 지표
노드 : 더 이상 나눌 수 없는 코드 블록 간선 : A블록 이후에 B블록 실행 가능할 때 연결
M=E-N+P E=간선 개수 N=노드나 블록의 개수 P=출구 있는 노드의 개수
p232 그림 6-16 M=E-N+P=11-10+3=4
함수형 M=E-N+P=0-0+1=1
6.1 함수형 프로그래밍과 단위 테스트
테스트 분류
FP 영향력은 unit test > integration test >> acceptance test