🎁 모든 강의 30% + 무료 강의 선물🎁

발자국 4주차: 그래서 우리는 왜 귀찮음을 이겨내야 하는가

발자국 4주차: 그래서 우리는 왜 귀찮음을 이겨내야 하는가

 

image

 

그래서 우리는 왜 귀찮음을 이겨내야 하는가

 

마지막 주간.

 

나는 이번 강의를 전반적으로 들으면서 문득 떠오른 그림이 있었다.

 

image

수학에서 함수를 이야기할 때 가장 먼저 나오는 그림이다.

 

우리가 테스트를 하는 대상은 결국 추상화된 로직 안쪽에 대한 구체적인 결과물이다.

 

테스트에서 가장 중요한 것은 I/O. 그리고 연계성.

 

여기에서 여러가지 박스가 중첩되어 있는 게 프로그램이고,

 

우리가 만든 이 프로그램에서 a라는 것이 정확한 f(a)를 보장하는가? 에 대한 물음표를 컴파일 타임에서 해소해 주는 것.

 

즉 I/O를 얼마나 촘촘하게 필터링할수 있을지에 대한 이야기이다.

 

Mockist가 여기서 발언할 수 있는 여지가 있다고 생각한다.

 

위에 있는 박스가 어떤 것을 뱉든 a가 막을 수 있는 테스트코드로 막으면 되잖아?

 

난 결국 a에 대한 모든 케이스를 전부 테스트했으니까. 연계에 있어서 굳이 힘을 뺄 이유가 있겠느냐는 패러다임이다.

 

나는 강의에서 말씀하신 것과 비슷한 시야를 가지고 있는 것 같은데 ㅎㅎ

 

결국 인간이란 실수할 수 있는 동물이지 않나... 하는 생각을 한다.

 

  • 어떠한 아웃풋이 나올지 모르니까 그걸 막으려고 테스트를 한다.

  • 어떠한 인풋이 나올지 모르니까 그걸 막으려고 테스트를 한다.

 

이 관점에서는 확실히 시나리오를 짜는 일이 유리해 보이니까.

나올 수 있는 케이스를 조금 더 촘촘히 만들고 막는 것이 Classicist의 접근 방향이지 않을까.... 하는 생각이 들었다.

 

근데 귀찮잖아. 많은 테스트는 귀찮잖아.

 

아니, 테스트는 귀찮잖아!

 

 

아, 귀찮아......

 

 

음... 테스트 작성은 귀찮다.

 

마지막 강의의 말미에서도 이야기하는 만큼, 선생님도 "귀찮음"을 이겨내고 테스트를 작성하신다고 했다.

 

결국은 장기적으로 유지보수가 될 프로그램에 대한 마음의 확신.

과감한 리팩토링을 가능하게 하는 것.

 

사실 이런 말이 무의미할 수도 있다.

 

이 강의를 듣는 것 자체가 테스트가 중요하다는 것을 알고 있어서라고 생각하니까.

 

그러면 우리는 이 귀찮음을 어떻게 이겨내는가?

 

 

그래서, 실행

 

강의나 책의 가장 중요한 핵심은 제목에 있다고 생각한다.

 

강의의 이름을 다시 한번 돌이켜 보자.

 

Practical Testing: 실용적인 테스트 가이드

 

결국 Practical.

 

강의에서도 계속 강조하는 만큼 결국 가장 중요한 것은 실무에서의 활용이다.

 

어떻게 활용할 수 있을까? 무엇이 귀찮음을 이겨내도록 할까?

 

무엇에 대한 내용은 강의에서 많이 들었다. 따라서 나는 어떻게로 접근해 보고자 했다.

 

 

귀찮음을 어떻게 이겨낼까?

 

 

많은 자기계발서들은 귀찮음을 이겨내는 방법에 대해서 이야기한다.

 

의지력을 발휘하는 법, 언제나 열정을 불어넣는 법, 시간과 체력을 관리하는 방법.... 등등등.

 

난 이게 다 무의미하다고 생각하는 사람이다.

 

결국 Do에 있어서의 방법론이 귀찮음을 누른다고 생각하니까.

 

나는 하기 싫은 일이 있을 때마다 하고 싶어질 때까지 아주 잘게 쪼갠다.

 

그럼 테스트에서도 이걸 적용하려면? 어떻게 해야할까?

 

나는 먼저 <Sudo 시나리오 짜기>로 접근해 보고자 했다.

 

우리는 f(a)라는 함수를 테스트하려고 한다.

개별에 대한 단위 해피 테스트, 엣지 테스트 같은 것들을 리스트에 포함해 보면 좋겠다.

그리고 연계 시의 단위 해피 테스트, 엣지 테스트 같은 것들을 리스트에 포함해 보면 좋겠다.

 

image

오. 나는 이제야 테스트 작성이 좀 더 빠르게 접근할 수 있는 것으로 보인다.

 

이것만 함수로 만들면 되잖아?

 

a에 대해 들어올 수 있는 값은 null일 수도, 숫자일 수도, 문자열일 수도, 객체일 수도 있다. 우리가 만약 string이라고 했다면, 숫자와 null에 대해서 필터링을 할 방법을 다 적어보면 되겠다.

 

강의에서는 이 방법으로 ParameterizedTest를 이야기했다.

 

@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {"Hello", "  ", "123", "!@#"})
@DisplayName("입력값이 null 또는 빈 문자열이면 안 된다.")
void shouldNotAllowNullOrEmptyString(String input) {
    // given
    String result = f(input);

    // then
    assertNotNull(result);
    assertFalse(result.isEmpty());
}

 

f(a)로 만들어질 수 있는 값도 동일하다. null일 수도, 숫자일 수도, 문자열일 수도, 객체일 수도 있다. 우리가 만약 객체라고 했다면, 그 객체가 만들어낸 값이 동일한지를 찾아보면 되겠다.

 

@Test
@DisplayName("출력값은 null이 아니어야 한다.")
void shouldNotReturnNull() {
    // given
    String input = "hello";

    // when
    String result = f(input);

    // then
    assertNotNull(result);
}

@Test
@DisplayName("출력값은 예상한 문자열과 일치해야 한다.")
void shouldReturnExpectedString() {
    // given
    String input = "hello";

    // when
    String result = f(input);

    // then
    assertEquals("HELLO", result);
}

@Test
@DisplayName("출력값은 모두 대문자로 변환되어야 한다.")
void shouldConvertToUpperCase() {
    // given
    String input = "hello";

    // when
    String result = f(input);

    // then
    assertTrue(result.matches("[A-Z]+"));
}

 

같은 식으로 말이다.

 

여기서 아주 촘촘하게 테스트를 짠다면 좋겠지만 인간은 언제나 놓치는 존재니까.

 

그래도 아무것도 없는 백지에서 짜는 것보다 훨씬 더 촘촘할 것이고,

 

조금 더 접근하기가 쉬워지지 않을까. 적어도 나는 그랬다.

 


 

테스트가 서비스 운영에서 어떤 위치를 가질 수 있는지 이야기해보는 시간이었으니,

 

나도 정리와 함께 활용 방법을 이야기해보고 싶어 여러 이야기들을 종합적으로 해 봤다.


이제 오늘을 끝으로 인프런 워밍업 클럽 스터디 3기는 막을 내리게 된다.

 

회사 일, 이직 면접, 스터디를 병행하며 했던 만큼 더욱 뿌듯함이 큰 것 같다.

 

(이 병행을 이유로 우수 수강생은 노리기 힘들 것 같아서 조금 아쉽기는 했다. ㅎㅎ 아직 수퍼맨은 아닌 걸로...)

 

사실 테스트 코드에 대한 배움을 가장 중점으로 가지고 들어왔지만, Readable Code 수강을 하면서 예상치 못한 배움들이 등장했다.

아는 것이라고 여기는 게 얼마나 바보같은 일인지 조금 더 절감하는 시간이었다.

 

수강은 이번에 막을 내리지만, 앞전 언급했던 것처럼 결국 가장 중요한 것은 실행이라는 것을 알고 있다.

 

실행을 토대로 내일부터 조금씩 테스트를 작성해 보는 시간을,

실제로 시간을 이유로 하지 못하더라도 어떠한 테스트 케이스가 나올 수 있는지에 대한 정리를 하고서

테스트를 하는 습관을 들여 보고자 한다.

 

3월은 짧았는데 어쩐지 워밍업 클럽은 길었던 느낌.

 

모두 고생하셨습니다.

 

 

 

댓글을 작성해보세요.


채널톡 아이콘