반응형
1. Testing
Traditional Quality Assurance
전통적인 QA 방법은 9단계로 진행된다.
- 머리 속에서 코드 실행해보기
- IDE warning으로 인지해서 고치기
- complier warnings 고치기
- 코드 리뷰(피어 리뷰)
- Unit testing (black +white)
- Integration testing
- System testing
- Alpha testing
- Beta testing
얼마나 테스트를 진행해야할까?
- Bad: "Until time to ship"
- better: Lines of Test / Lines of code
- 1.2~1.5 값은 터무니 없는 값이 아니다. 적정하거나 더 많이 수행된다.
- 실제 프로덕트 시스템에서는 더욱 많은 테스트가 진행
- more better Question: "나의 테스트가 얼마나 철저한가?"
- Formal methods
Coverage mesearment
!!- 이 수업에서는 후자인 커버리지 측정에 집중하고, 전자는 steady transaction을 통해 얻고자 함.
Metrics
- X가 적어도 하나의 테스트에 의해서 한 번 이상 실행되는 경우 X가 커버되었다고 한다.
- Coverage(인기있는 메트릭임) = % coverd of total available
- Quality vs Cost의 트레이드 오프
- Coverage의 종류들
- X = methods -> method/function coverage
- X = statements -> statement/line/basic-block coverage
- X = branches -> branch coverage
- X = paths -> path coverage
Measuring Coverage - Basics
- S0: every method callsd
- S1: every method from every from every call site
C0: every statement
- C1+decision coverage: every subpression in conditional(조건문)
- C2: every path (어려움, 실질적으로 가치가 있는지 반대 의견이 있음)
Identifying What's Wrong in Your Code
- 코드가 깨끗하지 못하다고 판단하는 기준을 어떻게 잡을까?
- 어떻게 깨끗하지 못한 코드를 개선할 수 있을까?
- 양적 분석: software metriscs
- 질적 분석: code smell
- 일반적인 코드 스멜(각 항목에 대한 설명은 제가 이해한 바를 토대로 작성하였습니다. 오개념이 있을 수 있으니 틀린 점은 댓글로 알려주세요.)
- 응용 프로그램 수준
- 이해하기 어려운 이름(함수, 모듈, 클래스, 변수 등): 이러한 것들이 문서로 커뮤니케이션이 안된 상태면 더욱 문제.
- 중복 코드: 비슷한 코드들이 여기저기에 존재
- 억지스러운 복잡성: 더욱 간단히 디자인 패턴을 바꿀 수 있지만, 귀찮아서 복잡성을 계속 가져가는 경우(라고 이해함)
- Shotgun surgery: 하나의 기능을 복붙해서 여러 클래스나 함수에 사용하는 경우 발생
- 사이드 이펙트 제어 불가: 유닛테스트로 잡아낼 수 없는 런타임 에러
- Variable mutations: 런타임에서 변수가 변하는 것을 통제, 디버깅 하는 것이 어렵다. 따라서 const와 같이 immutable한 것들을 주로 쓰자.
- Boolean blindness: 실제 if-else문과 같은 곳에서 boolean의 의미를 파악하는 것은 해당 path를 다시 읽게 만들고, 여러번 boolean을 생각하다 보면, 머릿속에서 꼬이는 것을 말하는 듯 하다. ("easy to assert on the opposite value and still type checks"라고 원문에 적혀있으나 아직은 무슨 뜻인지 정확히 이해하진 못했다.)
- 예시코드
if 1 != 1: return True else: return False
- 클래스 수준
- 너무 큰 클래스
- 기능에 대한 욕심: 다른 클래스의 메서드를 과도하게 사용하는 경우
- 부적절한 관계: 다른 클래스에 대해 종속성을 갖게 되는 경우
- Refused bequest: 자식 클래스가 부모의 클래스를 상속받아 override하는 경우, 충실히 구현하지 못하는 때 발생한다. 이는 LSP(Liskov Substitution Principle)를 위반하게 되는데 해결하려면 상속 관계를 없애고 delegation(위임)하기.
- 게으른 클래스/freeloader: 클래스가 하는 일이 너무 적음.
- 리터럴의 과도한 사용: 상수를 가독성 좋게 만드는 리터럴을 너무 자주 많이 사용하는 경우, 다른 Resource(파일 or 서버 등등)로 분리하여 관리할 수 있을 것임.
- Cyclomatic complexity: 너무 많은 branch와 loop -> 코드를 더욱 작게 쪼갤 수 있음을 말한다. 더욱 작은 단위로 분리하자.
- DownCasting: 부모 클래스 객체를 자식 클래스 객체로 type 캐스팅 하는 것을 말함. downcast는 추상 모델을 깨버릴 위험이 있다. 따라서 타입캐스트 사용시 abstaction을 수정하거나 삭제하기.
- Orphan variable OR constant class: 상수만을 가진 클래스는 클래스보다는 변수로 구현하는게 나을 것 같음. 아니면 리터럴로. Orphan variable는 더이상 참조가 존재하지 않는 변수로, 자바에서는 자동적으로 가비지 컬렉션이 되지만, 다른 언어에서는 메모리 누수가 일어날 수 있다.
- Data clump: 여러 변수들이 프로그램의 여러 파트에서 들어올 경우 발생. 이 변수 그룹은 의존성을 가지게 되며, 리팩토링이 필요하다. 분리된 변수 객체를 하나의 객체로 합쳐서 받는 것이 해결책이라고 하는데, 함수형 컴포넌트를 주로 사용하는 리액트에서와 뭔가 개념적으로 충돌하는 것 같다. 추가적으로 고민해보기.
- 너무 큰 클래스
- 메서드 수준
- too many parameters
- Long method
- Excessively long identifiers: 링크 참조
- Excessively short identifiers
- Excessive return of data
- Excessive comments
- Excessively long line of code
- 안티패턴
- 응용 프로그램 수준
- 일반적인 코드 스멜(각 항목에 대한 설명은 제가 이해한 바를 토대로 작성하였습니다. 오개념이 있을 수 있으니 틀린 점은 댓글로 알려주세요.)
Quantative: Metrics
- 목표수치
- code-to-test ratio: 1:2 이하
- C0(statement) coverage: 90% 이상
- Assignment-Branch-Condition score(ABC score): 메서드 당 20 미만
- Cyclomatic complexity: 메서드당 10 미만(NIST)
- “Hotspots”: 여러 메트릭들이 기준치를 만족하지 못하면 경고해주는 코드 라인.
- 메트릭을 그냥 무시하지 말고, 왜 그런 수치가 나오는지 고민할 것!
- 리팩토링이 필요한 부분을 더욱 잘 선택할 수 있다.
Cyclomatic complexity
- 정의: 코드 상에서 선형적으로 독립적인 경로들의 개수
- E– N+2P (edges, nodes, connected components)
- 각 경로는 다른 경로에 포함되지 않는 edge를 적어도 하나 이상 가지고 있어야 한다.
- ex)
- 위 사진을 예시로 계산하는 경우, E=9, N=8, P=1이다 따라서 Cyclomatic Complexity=3
테스트 종류 중 무엇을 선택할 것인가?
- Unit: run fast, high coverage, Fine resolution, Many mocks, 인터페이스는 테스트 하지 않음.
- Function or module
- Integration/System: run slow, Low coverage, Coarse resolution, Few mocks, test interfaces
- 어느 하나를 맹신하지 말자. 두루 활용할 것. 한 계층의 테스트가 못 잡는걸 다른 계층의 테스트는 잡아낼 수 있음. 상호 보완적임
이외의 테스트들
- Acceptance testin
- Smoke/sanity testing: 심각한 오류가 발생하는지 간단히 테스트함
- Compatibility testing: 호환성을 테스트 (ex: 웹 구현 후 브라우저마다 테스트하기)
- Fault injection: bad inputs, bad returns에 잘 대응 되었는지 확인.
- Performance testing: Load/stress/scalability testing
- Usability testing(사용성)
반응형
'개발 > 학교 수업' 카테고리의 다른 글
[소개원실/swpp] Software Development Process (0) | 2021.10.12 |
---|---|
[소개원실] Requirements and Specification (0) | 2021.10.07 |
[소개원실] Project Sprints (0) | 2021.10.07 |
[소개원실] Testing 2 (0) | 2021.10.02 |
[컴퓨터 비전] 과제를 위한 개발환경 세팅하기(Anaconda, vscode, pycharm) (0) | 2021.09.14 |