많은 개발자분들께서 테스트 코드를 작성이 중요하고 작성을 하고 있다는 것을 알게되었습니다.
TDD 에 대하여 장단점을 논하면서 쓰자 쓰지말자 논쟁도 많았구요.
그러나 정말 중요한 것은 테스터블한 코드를 작성하는 것과 핵심 로직에 테스트 코드가 있다면
분명 없는 것보다 좋은 것은 분명한 진리인 것 같습니다.
뭐 불평불만하기 전에 테스트 코드 작성을 할 줄은 알아야 된다고 생각해서 공부를 해보려고하나
많이 어려운 분야인 것 같아요.
그래서 테스트 코드라는 것에 대한 기초 개념이나 입문에 필요한 내용 위주로
글을 작성해보려고합니다.
테스트 코드란 무엇일까요?
말 그대로 내가 개발한 코드에 대해서 의도대로 동작하는지 확인 할 수 있는 코드를 말합니다.
이로써 소프트웨어의 품질이나 안정성을 확인 할 수 있는 것이죠.
모바일 기준으로 저희가 알아야 할 것들은
1. Unit Test
2. Integration Test
2. UI Test
정도가 있을 것 같습니다 ??
그 외에는 퍼포먼스 테스팅 정도가 있을지...
일단 이 중에서도 근본적인 Unit Test 를 좀 잘 알아보고싶어요.
테스트 코드는 왜 필요할까?
장점
- 안정적인 개발 할 수 가 있습니다.
- 오히려 잘짜여진 테스트 코드들은 개발 생산성을 높여줍니다. (사이드 이펙트를 줄여서 생산성을 더 높이는 경우)
- 동작하는 방식 및 결과를 예상할 수 있고 개발 중 예상치 못한 오류를 발견할 수도 있다.
단점
- 테스트 코드를 작성하는데 시간이 걸려 생산성이 저하 될 수 있다.
- 의미가 없는 테스트 코드를 작성 할 경우 무의미하다.
- 러닝 커브가 있다.
없는거보다 있는 것이 더 좋은건 분명한 것 같아요.
(근데 뭐 컴퓨터가 테스트 코드를 알아서 짜주냐고)
회사마다 개발 분야와 환경이 다르니까 선택적으로 하면 될 것 같다는게 제 생각이에요
예를 들어봅시다!
백엔드는 중요한 로직들이 있을 수 있어 테스트 코드를 짜는 것이 프론트나 모바일보다는 상대적으로 중요할 것 같아요.
(안중요하다는게 아니에요... 때론 더 중요할 수도 있겠죠)
간단한 UI 를 그려주고 계산하는 확인하는 테스트 코드가 정말 유의미할까요?
반대로 금융권 프론트, 모바일 앱에서라면?
테스트 코드가 정말 중요할지도요..?
결론은 각자 환경에 맞춰서 잘 작성합시다!!!
Unit Test 란
제일 작은 단위의 테스트로서 테스트 피라미드에 가장 베이스가 되는 테스트
작은 단위 하나하나의 테스트를 진행하는 것으로 보통 메서드 단위로 테스트를 진행합니다.
어디에나 설계 원칙이 있는데 다음은 Unit Test 설계 원칙이라네요.
아래 원칙에 따라 작성하다보면 자연스럽게 Testable 한 코드를 만들어 낼 수 있을 것 같아요.
F.I.R.S.T / Unit Test 설계 원칙
F(Fast): 유닛 테스트는 빨라야한다.
I(Independent & isolated): 다른 테스트에 종속적인 테스트는 절대 작성하지 않는다.
R(Repeatable): 테스트는 실행할 때 마다 같은 결과를 만들어야한다.
S(Self-validating): 테스트는 스스로 결과물이 옳은지 그른지 판단할 수 있어야한다. 특정 상태를 수동으로 만들어야 동작하는 테스트는 작성하지 않는다.
T(Thorough & Timely): 유닛테스트는 프로덕션 코드가 테스트를 성공하기 직전에 구성해야한다.
XCTest
1. setUpWithError - 테스트 코드 시작 전 값 셋팅 부분
2. tearDownWithError - 테스트가 끝난 후 호출하여 setUpWithError 메모리 해제로 많이 쓰임
(tearDown 은 해제하다. 분해하다. 라는 뜻의 영어 뜻)
3. testExample - 테스트 할 메서드는 반드시 test 로 시작해야함
4. testPerformanceExample - 이름처럼 성능 테스트 시 사용
테스트 템플릿? 포멧?
- Given - When - Then 구조를 많이 이야기하죠!
Given : 필요 value 셋팅
When : 테스트 코드 실행
Then: 결과 확인
간단하게 이렇게 설명 할 수 있을 것 같아요.
코드로 본다면?
func test_needUpdate_호출시_스토어버전을받아올때_결과값을받는지() throws {
// Given
let expectation = expectation(description: "스토어 버전 호출")
// When
sut?.needUpdate() { value in
// Then
XCTAssertNotNil(value)
expectation.fulfill()
}
wait(for: [expectation], timeout: 10)
}
이런 느낌이 될 것 같아요 .
Test Double(테스트를 진행하기 어려운 경우 테스트 진행 할 수 있도록 만들어주는 객체)
혹시 면접 준비를 하시거나 현업에서 목데이터, 더미 데이터 이야기 들어보셨나요?
테스트 시에 필요한 것(가능하게 하는 것)들을 통합해서 부르는 말이 테스트 더블(Test Double) 이라고하는데
명칭과 쓰임에 따라 구분지어 놓았더라구요.
(하지만 실제로는 구분 짓기보단 편의상 목데이터라고 부르시는 경우도 있다고 하네요.)
Test Double 의 종류
1. Dummy (모조의, 가짜의)
Dummy는 가장 기본적인 테스트 더블입니다.
어떤 기능이 구현되어 있지 않은, 단지 인스턴스화된 객체로 사용되기 때문에 Dummy의 메서드는 정상적으로 동작하지 않습니다.
객체를 전달하기 위한 목적으로 주로 사용됩니다.
2. Stub (쓰다 남은 물건의 토막, 남은 부분)
Stub은 Dummy가 실제로 동작하는 것처럼 만들어 실제 코드를 대신해서 동작해 주는 객체입니다.
테스트가 곤란한 부분의 객체를 도려내어 그 역할을 최소한으로 대신해 줄 만큼만 간단하게 구현되어 있습니다.
3. Fake
Fake는 Stub보다 구체적으로 동작해서 실제 로직처럼 보이지만 실제 앱의 동작에서는 적합하지 않은 객체를 말합니다. 로직 자체는 실제 앱의 코드와 비슷하지만 그 동작을 단순화하여 구현한 객체를 Fake 객체라고 합니다.
4. Spy
Spy는 Stub의 역할을 가지면서 호출된 내용에 대한 방법 혹은 과정 등 약간의 정보를 기록하는 객체입니다. 예를 들어, 호출되었는지, 몇 번 호출되었는지 등에 대한 정보를 기록할 수 있습니다.
5. Mock
실제 객체와 가장 비슷하게 구현된 수준의 객체라고 할 수 있습니다.
Stub이 상태 기반 테스트(State Base Test)라면 Mock은 행위 기반 테스트(Behavior Base Test)라고 이야기하기도 합니다. 여기서 상태 기반 테스트는 메서드를 호출하고 그 결괏값과 예상 값을 비교하는 식으로 동작하는 테스트를 말하고, 행위 기반 테스트는 예상되는 행위들에 대한 시나리오를 만들어 놓고, 시나리오대로 동작했는지에 대한 여부를 확인하는 것입니다.
레퍼런스
https://silver-g-0114.tistory.com/142
https://leeari95.tistory.com/60
https://ios-development.tistory.com/334https://hanamon.kr/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1/
'개발 > 개발' 카테고리의 다른 글
[개발] Github vs AWS Code Commit (0) | 2023.02.06 |
---|---|
[iOS] - XcodeGen 에서 Tuist 로 전환 후기 (0) | 2022.12.14 |
[Swift] - Array의 Count 함수는 과연 속도 차이가 있을까? (3) | 2022.11.01 |
[iOS] - SkeletonView 를 RxDataSources 에 적용해보기 (0) | 2022.10.31 |
[SwiftUI] - SwiftUI Button Hide 버튼 숨기기 (0) | 2022.10.11 |