개발을 하다 보면 코드의 신뢰성을 검증하거나 내용을 전달하는 목적으로 테스트 코드를 많이 작성하게 되는데요. 링크모은 작성하는 것보다 단위 테스트(unit test) 코드를 작성하는 데에 가장 많은 시간을 투여하게 됩니다. 단위 테스트는 하나의 기능만 테스트하는 것이기 때문에 영향을 받는 부분이 매우 적으며, 비용이 저렴하기 때문입니다.
단위 테스트에서 반복되는 보일러 플레이트 코드
팀 내에서 이러한 테스트 코드를 Kotlin 스타일로 더 쉽게 작성하기 위해 KoTest라는 테스트 프레임워크와 모킹(mocking)을 위한 mockk 라이브러리를 이용하고 있습니다.
테스트 코드 작성에 많이 알려진 Given-When-Then Pattern도 이용하고 있는데요.
대부분 아래와 같은 흐름으로 작성되게 됩니다.
위의 테스트 코드는 제가 이전까지 경험해 온 팀들도 대다수 사용하는 패턴으로 테스트 대상 시스템(system under test)를 이루는 의존성을 모킹(mocking)하여 격리시킨 뒤 온전하게 테스트 대상 시스템만 테스트하는 단위 테스트 방식입니다.
링크모은 코드를 작성하기 위해서는 given 절에서 수행되는 내용이 아래처럼 항상 반복되는 것을 알게 됩니다.
1.테스트 대상 시스템 (SUT)을 제외한 의존성을 모킹(mocking)한다.
2.SUT에 대상 의존성을 주입한다.
즉, 우리는 단위 테스트를 작성할 때 위 패턴을 반복해서 작성하게 됩니다. 따라서 이렇게 반복되는 패턴을 자동화할 필요성이 있다고 느껴 여러 Intellij 플러그인을 찾게 되었습니다.
그 중, TestMe라는 플러그인을 찾았으나 아쉽게도 Kotlin 그리고 Kotest 를 별도로 지원하지는 않았습니다. 그래서 별도로 개발을 진행해야 겠다는 생각을 가지게 되었고, 10월 초에 개발을 진행하게 되었습니다.
플러그인 개발기
Intellij 내부에서 우리가 코드를 작성하거나, 파일을 생성하기 위해 단축키인(Cmd + N)을 누르는 과정 모두 하나의 Action으로 취급됩니다. 기존에 우리가 테스트 파일을 쉽게 생성하기 위해 만드는 단축키인 (Cmd + Shift + T) 조차도 Create Test라는 하나의 행위(Action)으로 취급됩니다.
따라서, 기본적으로 제공하는 Action이 있다면 상속(extend)하여, 약간 수정하면 좀 더 수월하게 개발할 수 있는데요. Intellij에서는 이미 CreateTestAction이라는, 테스트를 생성할 때 발생하는 Action의 기본 동작들을 다루는 클래스를 제공하고 있습니다. 따라서, 저 또한 아래와 같이 CreateTestAction Class를 상속받아 개발을 진행하였습니다.
링크모은 생성하는 단축키인 행위(action)에 제 커스텀 이벤트를 등록시키기 위해서는, Intellij 내장 클래스인 GoToTestOrCodeHandler()에 위에서 생성한 CustomHandler를 이용하여 코드를 실행할 수 있도록 등록해야 합니다.
Kotlin 파일 분석하기
(들어가기에 앞서, 이 부분에서는 간단하게 문맥을 잘 이해할 수 있을 정도의 코드만 설명할 예정입니다.)
이제 Handler는 잘 등록을 했고, 우리가 원하는 테스트 파일을 만들기 위해서는 우리가 현재 마우스를 올리고 있는 파일에 대한 정보를 분석할 수 있어야 합니다. Kotlin 파일은 Intellij 내에서 KtFile 형태 (Type)으로 분류됩니다. KtFile Type에는 클래스 내부 정보를 쉽게 알 수 있도록 몇몇 메서드들을 지원합니다. 그래서, 해당 메서드를 이용하여 좀 더 수정하여 Kotlin 파일을 분석하는 저만의 Parser 클래스를 작성하였습니다.
여기서는 클래스 이름 혹은 메서드와 같은 현재 클래스에 대한 정보를 해석할 수 있는 기능을 제공하게 됩니다. 우리는 여기서 getProperties() 함수를 통해 우리가 원하던 Class 내부 의존성을 파악할 수 있게 됩니다.
테스트 파일 생성
이제 분석한 정보를 앞으로 클래스 메타 데이터(ClassMetaData)라고 표현하겠습니다. 이 클래스 메타 데이터(ClassMetaData)를 기반으로 아까 위에서 작성했던, 테스트 대상 시스템(SUT)에 모킹한 의존성을 넣는 코드를 작성해 봅시다.
테스트 파일을 생성할 때 아무런 규격이 없이 단순 문자열로만 파일을 생성하게 되면, 이후 오픈소스로 기여(Contribution)받게 되면 유지보수가 힘들어지고 규칙성 있게 코드를 작성하기 힘들어질 수 있어 Builder 라이브러리를 찾아보게 되었습니다.
팀에서 추천받은 KotlinPoet이라는 FileBuilder를 이용했는데, 아래 코드와 같이 빌더 방식으로 Kotlin 파일을 생성할 수 있습니다.
위 라이브러리를 이용하여 아래와 같이 테스트 파일을 생성하는 코드를 작성했습니다. 코드를 모두 보여주기에는 너무 길어져서 테스트 코드의 검증부 부분만 보여드리겠습니다.
TestClassTest라는 클래스는 의존성으로 List Type의 ages 변수를 가지고 있는 경우 아래 then 절의 결과와 같이 테스트 파일이 생성됩니다. 지금까지 우리가 위에서 언급했던 단위 테스트(unit test)에서의 반복되는 부분을 쉽게 생성할 수 있도록 코드로 간략하게 확인해 보았습니다. 이제 실질적으로 어떻게 사용하는지 알아봅시다
마켓에 배포하기
플러그인을 마켓에 배포하려면 빌드하여 플러그인을 .jar 또는 .zip 파일로 만들어야 합니다.
Chapter 3. 컴퓨터! 커피 한 잔 마시고 올게, 전부 정리해놔! | 6개월 치 업무를 하...Byunghyun Ban
* SlideShare 오류로 빈 화면이 나올 경우 다운로드하여 이용해주시기 바랍니다.
<6개월 치 업무를 하루 만에 끝내는 업무 자동화, 2020, 생능출판사>의 수업용 PPT 자료입니다. 교재로 활용하실 경우 출판사를 통해 한 학기 분량의 PPT를 제공받으실 수 있습니다.
개발을 하다 보면 코드의 신뢰성을 검증하거나 내용을 전달하는 목적으로 테스트 코드를 많이 작성하게 되는데요. 링크모은 작성하는 것보다 단위 테스트(unit test) 코드를 작성하는 데에 가장 많은 시간을 투여하게 됩니다. 단위 테스트는 하나의 기능만 테스트하는 것이기 때문에 영향을 받는 부분이 매우 적으며, 비용이 저렴하기 때문입니다.
단위 테스트에서 반복되는 보일러 플레이트 코드
팀 내에서 이러한 테스트 코드를 Kotlin 스타일로 더 쉽게 작성하기 위해 KoTest라는 테스트 프레임워크와 모킹(mocking)을 위한 mockk 라이브러리를 이용하고 있습니다.
테스트 코드 작성에 많이 알려진 Given-When-Then Pattern도 이용하고 있는데요.
대부분 아래와 같은 흐름으로 작성되게 됩니다.
위의 테스트 코드는 제가 이전까지 경험해 온 팀들도 대다수 사용하는 패턴으로 테스트 대상 시스템(system under test)를 이루는 의존성을 모킹(mocking)하여 격리시킨 뒤 온전하게 테스트 대상 시스템만 테스트하는 단위 테스트 방식입니다.
링크모은 코드를 작성하기 위해서는 given 절에서 수행되는 내용이 아래처럼 항상 반복되는 것을 알게 됩니다.
1.테스트 대상 시스템 (SUT)을 제외한 의존성을 모킹(mocking)한다.
2.SUT에 대상 의존성을 주입한다.
즉, 우리는 단위 테스트를 작성할 때 위 패턴을 반복해서 작성하게 됩니다. 따라서 이렇게 반복되는 패턴을 자동화할 필요성이 있다고 느껴 여러 Intellij 플러그인을 찾게 되었습니다.
그 중, TestMe라는 플러그인을 찾았으나 아쉽게도 Kotlin 그리고 Kotest 를 별도로 지원하지는 않았습니다. 그래서 별도로 개발을 진행해야 겠다는 생각을 가지게 되었고, 10월 초에 개발을 진행하게 되었습니다.
플러그인 개발기
Intellij 내부에서 우리가 코드를 작성하거나, 파일을 생성하기 위해 단축키인(Cmd + N)을 누르는 과정 모두 하나의 Action으로 취급됩니다. 기존에 우리가 테스트 파일을 쉽게 생성하기 위해 만드는 단축키인 (Cmd + Shift + T) 조차도 Create Test라는 하나의 행위(Action)으로 취급됩니다.
따라서, 기본적으로 제공하는 Action이 있다면 상속(extend)하여, 약간 수정하면 좀 더 수월하게 개발할 수 있는데요. Intellij에서는 이미 CreateTestAction이라는, 테스트를 생성할 때 발생하는 Action의 기본 동작들을 다루는 클래스를 제공하고 있습니다. 따라서, 저 또한 아래와 같이 CreateTestAction Class를 상속받아 개발을 진행하였습니다.
링크모은 생성하는 단축키인 행위(action)에 제 커스텀 이벤트를 등록시키기 위해서는, Intellij 내장 클래스인 GoToTestOrCodeHandler()에 위에서 생성한 CustomHandler를 이용하여 코드를 실행할 수 있도록 등록해야 합니다.
Kotlin 파일 분석하기
(들어가기에 앞서, 이 부분에서는 간단하게 문맥을 잘 이해할 수 있을 정도의 코드만 설명할 예정입니다.)
이제 Handler는 잘 등록을 했고, 우리가 원하는 테스트 파일을 만들기 위해서는 우리가 현재 마우스를 올리고 있는 파일에 대한 정보를 분석할 수 있어야 합니다. Kotlin 파일은 Intellij 내에서 KtFile 형태 (Type)으로 분류됩니다. KtFile Type에는 클래스 내부 정보를 쉽게 알 수 있도록 몇몇 메서드들을 지원합니다. 그래서, 해당 메서드를 이용하여 좀 더 수정하여 Kotlin 파일을 분석하는 저만의 Parser 클래스를 작성하였습니다.
여기서는 클래스 이름 혹은 메서드와 같은 현재 클래스에 대한 정보를 해석할 수 있는 기능을 제공하게 됩니다. 우리는 여기서 getProperties() 함수를 통해 우리가 원하던 Class 내부 의존성을 파악할 수 있게 됩니다.
테스트 파일 생성
이제 분석한 정보를 앞으로 클래스 메타 데이터(ClassMetaData)라고 표현하겠습니다. 이 클래스 메타 데이터(ClassMetaData)를 기반으로 아까 위에서 작성했던, 테스트 대상 시스템(SUT)에 모킹한 의존성을 넣는 코드를 작성해 봅시다.
테스트 파일을 생성할 때 아무런 규격이 없이 단순 문자열로만 파일을 생성하게 되면, 이후 오픈소스로 기여(Contribution)받게 되면 유지보수가 힘들어지고 규칙성 있게 코드를 작성하기 힘들어질 수 있어 Builder 라이브러리를 찾아보게 되었습니다.
팀에서 추천받은 KotlinPoet이라는 FileBuilder를 이용했는데, 아래 코드와 같이 빌더 방식으로 Kotlin 파일을 생성할 수 있습니다.
위 라이브러리를 이용하여 아래와 같이 테스트 파일을 생성하는 코드를 작성했습니다. 코드를 모두 보여주기에는 너무 길어져서 테스트 코드의 검증부 부분만 보여드리겠습니다.
TestClassTest라는 클래스는 의존성으로 List Type의 ages 변수를 가지고 있는 경우 아래 then 절의 결과와 같이 테스트 파일이 생성됩니다. 지금까지 우리가 위에서 언급했던 단위 테스트(unit test)에서의 반복되는 부분을 쉽게 생성할 수 있도록 코드로 간략하게 확인해 보았습니다. 이제 실질적으로 어떻게 사용하는지 알아봅시다
마켓에 배포하기
플러그인을 마켓에 배포하려면 빌드하여 플러그인을 .jar 또는 .zip 파일로 만들어야 합니다.
Chapter 3. 컴퓨터! 커피 한 잔 마시고 올게, 전부 정리해놔! | 6개월 치 업무를 하...Byunghyun Ban
* SlideShare 오류로 빈 화면이 나올 경우 다운로드하여 이용해주시기 바랍니다.
<6개월 치 업무를 하루 만에 끝내는 업무 자동화, 2020, 생능출판사>의 수업용 PPT 자료입니다. 교재로 활용하실 경우 출판사를 통해 한 학기 분량의 PPT를 제공받으실 수 있습니다.
1. 과제 #2) 색인어 생성기 만들기
색인어 생성기는 아래의 동작을 해야 한다. (단, 입력 데이터는 html 문서임)
1) 입력된 문서에서 <body>~</body> Tag 내에 존재하는 데이터를 plain text로 변환한다.
(모든 tag를 삭제한다.)
2) 1)의 결과를 이용하여 token을 구분하고 불용어(stop words)를 제거한다.
이 때, 불용어 목록은 직접 정하여, 적용한다.
3) 2)의 결과를 이용하여 Porter stemming algorithm을 적용한 색인어 목록을 출력한다.
<프로그램의 동작 및 출력물>
1) 프로그램은 콘솔에서 동작하며 아래의 명령어 형식으로 작동한다.
$ makeindex.exe {입력파일명}
ex) $ makeindex.exe input.txt
2) 입력은 하나 혹은 다수의 파일명이 적힌 text파일이다. (파일명은 줄바꿈으로 구분)
[파일의 내용]
srcnews01.html
srcnews02.html
…
srcnews10.html
3) ./doc 폴더에 뉴스 기사만 plain text 형태로 저장된 *.txt 파일을 저장한다.
하나의 html 파일은 같은 이름의 text 파일 하나로 저장되어야 한다.
ex) 입력: news01.html 출력: news02.txt
4) ./words 폴더에 최종 색인어가 포함된 index_words.txt 파일을 저장한다.
색인어는 중복되지 않아야 하며, 모든 색인은 index_words.txt 파일 하나에 통합한다.
<제출내용>
① 프로그램 소스 코드 (C/C++, 컴파일이 가능한 형태)
② 코딩에 사용한 불용어(stop words) 목록과 해당 불용어를 선택한 간략한 이유(*.doc 파일)
<참고>
* C/C++를 이용하여 구현할 것 (STL 이외의 타인이 구현한 library 사용하지 말 것)
* 입력 데이터는 http://www.nytimes.com에서 수집한 뉴스 기사를 사용한다.
* <body>~</body> 태그 내에는 뉴스 기사뿐 아니라 메뉴 등의 텍스트가 포함되어 있어 색인어
로 적합하지 않은 단어들이 있다. 뉴스 본문만 읽어오도록 프로그램을 작성하라. (선택사항)
* 컴파일 되지 않는 소스는 채점에서 제외될 수 있음
* 다른 사람과 유사한 코드가 발견되면 감점 혹은 수업시간에 자신의 코드를 설명하도록 하고 그
결과를 점수에 반영함. (참조하여 작성한 경우 해당 reference를 밝힐 것. 정상참작)