'가독성'에 해당하는 글 2건

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
코드를 작성하는 것과 글을 쓰는 것은 무척 유사하다는 생각이 들 때가 많다. 코드를 쓸 때면 관련있는 코드끼리 묶어보고 해당 코드를 글 쓸 때의 문단처럼 생각한다. 문단 사이에는 빈줄을 넣어 구분한다. 켄트벡이 구현 패턴에서 강조했던 것처럼 읽는 사람이 좀더 내 의도를 알아주기를 바라는 마음에서다. 

테스트 메서드에서는 이런 문단 개념이 더욱 쉽게 적용될 수 있는 것 같다. 왜냐하면 대부분의 테스트 메서드는 세 개의 문단을 가지고 있기 때문이다. 준비, 테스트 실행, 검증이다. 아래 DAO 통합 테스트는 이런 세 단계를 잘 보여준다,

@Test
public void 데이터베이스에_저장한_이름을_조회한다() {
Name persistedName = sut.persist(new Name("Some name"));
        
        Name result = sut.findBy(persistedName.id());        

assertThat(result, is(persistedName));
}

위 예제를 보면 

1. 이름을 저장한다. [준비]
2. 방금 저장한 이름을 가져온다. [테스트 실행]
3. 저장한 이름을 정확히 가져왔는지 검증한다. [검증]

로 문단이 구분되어 있음을 볼 수 있다. 또 다른 예제도 있다. 비슷한 구성을 확인할 수 있다.

@Test
public void serviceShouldBeStopped_WhenNeedingReadOnlyStop() {
        when(readOnlyStop.stopNow()).thenReturn(success);
        when(readOnlyNotifier.relatedServices()).thenReturn(createRelatedServices());
        when(readOnlyNotifier.notifyToRelatedServices(any(StopMessage.class))).thenReturn(success);

        target.stop(readOnlyStopType, "Read Only Stop");

        verify(readOnlyStop).stopNow();
}

그런데 문단을 나누는 것이 정말 가치가 있을까? 이 글을 읽는 사람이 어떻게 느꼈는지는 모르겠지만 만약 문단별로 띄어쓰기를 하지 않으면 방금 전 소스는 아래처럼 보인다.

@Test
public void serviceShouldBeStopped_WhenNeedingReadOnlyStop() {
        when(readOnlyStop.stopNow()).thenReturn(success);
        when(readOnlyNotifier.relatedServices()).thenReturn(createRelatedServices());
        when(readOnlyNotifier.notifyToRelatedServices(any(StopMessage.class))).thenReturn(success);
        target.stop(readOnlyStopType, "Read Only Stop");
        verify(readOnlyStop).stopNow();
}

어디까지가 테스트 데이터를 준비하는 곳이고 어떤 곳이 실행 부분인지 잘 구분이 되지 않는다. 결국 문단별 띄어쓰기가 가독성에 긍정적인 영향을 미친다는 것을 알 수 있다.

행위 주도 개발(Behavior Driven Development)에서는 '비지니스 요구사항에 따른 필요한 행위'라는 관점에서 테스트를 작성한다. 주요 의도 중 하나는 테스트를 개발자가 아닌 사람도 이해할 정도로 만들겠다는 것이다. 사실 UML 사례처럼 이런 시도가 좋은 결과를 낸 경우가 많지 않다는 점이 먼저 생각난다. 하지만 가독성이라는 관점에서는 이런 형식을 따라도 손해볼 일은 없을 것 같다. 위키피디아에 소개 된 BDD 기반 테스트 예제는 아래와 같다.

@Test
public void shouldCloseWindows() {
// Given
WindowControl control = new WindowControl("My AFrame");
AFrame frame = new AFrame();
// When
control.closeWindow();
// Then
ensureThat(!frame.isShowing());       
}


문단 관점에서 보면 앞서 소개한 예제와 동일하게 세개의 문단으로 구성되어 있다. 다만 Given, When, Then으로 문단의 소주제를 결정한 것이 특징이다. 테스트명은 테스트하고자 하는 행위를 나타내고 있다. 쭉 읽어보면 상당히 읽기도 좋고 이해도 잘 된다. 

테스트도 사람이 읽고 유지보수해야 하는 코드이다. 따라서 코드에 적용될 수 있는 내용 중 많은 부분이 그대로 적용될 수 있다. 그중 문단 나누기는 테스트의 가독성을 향상시키려고 할 때 많은 도움이 될 것이라 생각한다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예전에 "13C 유럽의 교육"이란 글을 쓴 적이 있습니다. 그 글의 주제는 읽기,쓰기,말하기,듣기와 같은 의사소통이 매우 중요하다는 것이였습니다. 그리고 최근에는 코드도 마찬가지가 아닐까라는 생각이 들었습니다.

언제인가 회사의 동료 분과 페어 프로그래밍을 하고 있었습니다. 우리의 목표는 특정 코드를 분석하여 이 코드가 우리가 원하는 바를 이루는 데 도움이 될 수 있는지 판단을 하는 것이였습니다. 키보드는 동료분이 가지고 있었고 우리는 함께 자리에 앉아 코드를 살펴보기 시작했습니다. 잠시 후 그 분은 "이건 가능하겠네요.","이건 좀 고쳐야겠군요"하며 판단하고 화면을 넘겼습니다. 그렇게 몇몇 페이지를 넘나들다 밝은 표정으로 말했습니다. "가능할 것 같습니다. 여기 저기를 좀 수정하면 될 것 같네요." 일은 이렇게 잘 끝났습니다.

그런데 그 동료 분이 돌아간 후 전 부끄러움을 느꼈습니다. 왜냐하면 동료 분이 코드를 읽고, 파악하고, 문제 해결을 시도할 때 전 그 속도를 전혀 따라가지 못했기 때문입니다. 제가 코드를 읽으며 이해하려 할 때 그 분은 이미 판단을 끝내고 다음으로 넘어갔기 때문에 저는 뒤에서 그냥 바라보고 있을 수 밖에 없었습니다.

왜 이런 일이 발생을 했는지 생각해보았습니다. 저의 결론은 제가 쓰기에만 집중하고 읽기에 대해 훈련하지 않았기 때문이라는 것이였습니다. 실제로 저는 여러 문서를 참고하며 코드를 잘 쓰기 위한 훈련을 해왔습니다. 그러나 코드 읽기에 대해서는 학습도 훈련도 하지 않았습니다. 어쩔 수 없이 남의 코드를 봐야 할 때를 제외하곤 읽기에 대해 고민하는 시간이 많지 않았던 것이였습니다.

최근 많은 곳에서 코드 잘 쓰기의 중요성을 강조합니다. 반면에 코드 읽기에 대한 중요성은 많이 얘기 되지 않는 것 같습니다. 보편적인 경우 소프트웨어를 개발하는 기간보다 유지보수 하는 기간이 더욱 길다고 합니다. 이러한 점을 생각해보면 코드 쓰기 능력과 더불어 코드 읽기 능력도 균형 있게 훈련해야 하지 않을까 생각합니다.

2007/10/16 ~ 2008/07/01

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,