클린 코드 8-9장

Park Jae Hong·2023년 6월 26일
0

경계

학습 테스트

: 우리쪽 코드를 작성해 외부 코드를 호출하는 대신 먼저 간단한 테스트 케이스를 작성하는 것

  • 패키지 새 버전이 나온다면 학습 테스트를 돌려 차이가 있는지 확인한다.

  • 학습 테스트는 패키지가 예상대로 도는지 검증한다.

  • 일단 통합한 이후라고 하더라도 패키지가 우리 코드와 호환되리라는 보장은 없다.

  • 패키지 작성자에게 코드를 변경할 필요가 생길지도 모른다.

  • 패키지 작성자는 버그를 수정하고 기능도 추가한다.

  • 패키지 새 버전이 나올 때 마다 새로운 위험이 생긴다.

  • 새 버전이 우리 코드와 호환되지 않으면 학습 테스트가 이 사실을 곧바로 밝혀낸다.

이런 경계 테스트가 있다면 패키지 새 버전으로 이전하기 쉬워진다. 그렇지 않다면 낡은 버전을 필요 이상으로 사용할 수 있다.

아직 존재하지 않는 코드

: 경계와 관련해 또 다른 유형은 아는 코드와 모르는 코드를 분리하는 경계다. 때로는 우리 지식이 경계를 넘어 미치지 못하는 코드 영역도 있다. 때로는 알려고 해도 알 수 없다. 때로는 더 이상 내다보지 않기로 결정한다.

깨끗한 경계

: 통제 불가능한 외부 패키지에 의존하는 대신 통제가 가능한 우리 코드에 의존하는 편이 훨씬 좋다. 자칫하면 외부 코드에 휘둘리고 만다. 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자.

처음에 사용하기 쉬운 것은 내부에서 지원하는 기능이 많다는 의미,
그것을 이해지 못하고 사용한다면 추후 관리가 더욱 어려워질 수 있다.
(Ex - Kotlin & Java)

결론적으로는, 외부 라이브러리는 최소화 하고 내부에서 해결하자 !

단위 테스트

TDD 법칙 세가지

  • 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.

  • 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.

  • 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.

깨끗한 테스트 코드 유지하기

: 테스트 코드는 실제 코드 못지 않게 중요하다. 테스트 코드는 유연성, 유지 보수성, 재사용선을 제공한다. 깨끗한 코드를 만들기 위해서는 가독성이 매우 중요하다.

실제 코드를 유연하게 만드는 버팀목 !

테스트 당 assert 하나

: Junit으로 테스트 코드를 짤 때는 함수마다 assert 문을 단 하나만 사용해야한다. 그러면 함수으 ㅣ결론이 하나라서 코드를 이해하기 쉽고 빠르다.

테스트 당 개념 하나

: 이것저것 잡다한 개념을 연속으로 테스트하는 긴 함수는 피한다.

FIRST

  • Fast
    : 테스트는 빨라야 한다. 테스트가 느리면 자주 돌릴 엄두를 못 낸다.

  • Indepandent
    : 각 테스트는 서로 의존하면 안된다. 한 테스트가 다음 테스트가 실행될 환경을 준비해서는 안된다. 하나가 실패할때 나머지도 잇달아 실패하므로 원인을 찾기 힘들다.

  • Repeatable
    : 테스트는 어떤 환경에서도 반복 가능해야한다. 실제 환경, QA 환경, 네트워크 X 환경에서도 실행할 수 있어야 한다.

  • Self-validating
    : 테스트는 Bool 값으로 결과를 내야 한다. 성공 아니면 실패다. 동과 여부를 알려고 로그 파일을 읽게 만들어서는 안된다. 통과 여부를 보려고 텍스트 파일 두 개를 수적업으로 비교하게 만들어서도 안된다.

  • Timely
    : 테스트는 적시에 작성해야 한다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다. 실제 코드를 구현한 다음에 테스트 코드를 만들면 실제 코드가 테스트하기 어렵다는 사실을 발견할지도 모른다.

결론

테스트 코드는 지속적으로 깨끗하게 관리하고 표현력을 높이고 간결가게 정리하자 !

@Test
@DisplayName("[성공] App 시작 시 네트워크가 연결 되어 있을 경우: Loading -> SUCCESS)
fun checkNetworkConnectSuccess() = runTest {
    // given
    coEvery {
        getSplashUseCase.observeConnectivityAsFlow()
    } returns flow { emit(true) }
    
    coEvery {
        getSplashUseCase.getCenterInfo(i)
    } returns flow { emit(ApiResult.Success(listOf(centerItemTest))) }

    // when
    viewModel.getCenterInfo()

    // then
    viewModel.uiState.test {
    	assertThat(this.awaitItem()).isEqualTo(UiState.LOADING)
        assertThat(this.awaitItem()).isEqualTo(UiState.SUCCESS)
    }
    
    viewModel.centerItems.test {
    	assertThat(this.awaitItem().size()).isGreaterThan(0)
    }
}
@Test
@DisplayName("[실패] App 시작 시 네트워크가 연결 되어 있지 않을 경우: Loading -> Error)
fun checkNetworkConnectSuccess() = runTest {
    // given
    coEvery {
        getSplashUseCase.observeConnectivityAsFlow()
    } returns flow { emit(false) }
    
    coEvery {
        getSplashUseCase.getCenterInfo(i)
    } returns flow { emit(ApiResult.Success(listOf(centerItemTest))) }

    // when
    viewModel.getCenterInfo()

    // then
    viewModel.uiState.test {
    	assertThat(this.awaitItem()).isEqualTo(UiState.LOADING)
        assertThat(this.awaitItem()).isEqualTo(UiState.Error)
    }
    
    viewModel.centerItems.test {
    	assertThat(this.awaitItem().size()).isEqualTo(0)
    }
}
profile
The people who are crazy enough to think they can change the world are the ones who do. -Steve Jobs-

0개의 댓글