본문 바로가기
프로젝트/사이드 프로젝트

TDD기반 개발 프로젝트3-1: 드디어 함수 코딩하기..?

by soypablo 2023. 6. 23.

드디어 테스트를 수행할 함수를 만들 때가 되었다!

일단 1번 테스트를 해결할 수 있는 함수를 만드는 것을 목표로 하자.

1번 테스트의 내용은 다음과 같다

입력은 문자열을 입력받는다.

test1str: list[str] = [
    """여러가지 ~니다 로 끝나는 말을 알려드리겠습니다.

       * 감사합니다: 감사하다는 뜻
       * 고맙습니다: 고맙다는 뜻
       * 안 감사합니다: 안감사하다는 뜻
       * 즐겁습니다: 즐겁다는 뜻""",
    """여러가지 ~니다 로 끝나는 말을 알려드리겠습니다.

       - 감사합니다: 감사하다는 뜻
       - 고맙습니다: 고맙다는 뜻
       - 안 감사합니다: 안감사하다는 뜻
       - 즐겁습니다: 즐겁다는 뜻""",
]

반환값은 볼딩처리한 문자열을 리턴한다.

test1answer: list[str] = [
    """여러가지 ~니다 로 끝나는 말을 알려드리겠습니다.

       * **감사합니다**: 감사하다는 뜻
       * **고맙습니다**: 고맙다는 뜻
       * **안 감사합니다**: 안감사하다는 뜻
       * **즐겁습니다**: 즐겁다는 뜻""",
    """여러가지 ~니다 로 끝나는 말을 알려드리겠습니다.

       - **감사합니다**: 감사하다는 뜻
       - **고맙습니다**: 고맙다는 뜻
       - **안 감사합니다**: 안감사하다는 뜻
       - **즐겁습니다**: 즐겁다는 뜻""",
]

bolding(test1str[0]) == test1answer[0] 이 True이면 1-1번 테스트 통과
bolding(test1str[1]) == test1answer[1] 이 True이면 1-2번 테스트 통과 인 것이다.

그럼 함수를 만들어보자

import re
from pathlib import Path


def bolding(s: str | Path) -> str:
    """
    markdown형태로 작성된 문자열에서 특정 패턴을 찾아 볼드처리(**)를 자동화하는 함수입니다.

    이 함수는 입력된 문자열 혹은 파일에서 특정 패턴을 찾아 해당 패턴을 볼드 처리(**)합니다.
    패턴은 이 함수의 내부 로직에 의해 결정됩니다.
    문자열 s는 raw string이거나 .md 파일의 경로(Path)일 수 있습니다.
    만약 s가 경로인 경우, 해당 파일을 읽어서 문자열로 변환한 후 볼드 처리를 진행합니다.

    Args:
        s (str | Path): 볼드처리할 문자열 또는 markdown 파일의 경로.

    Returns:
        str: 볼드처리가 완료된 문자열. 만약 입력이 파일 경로였다면, 이는 볼드 처리가 완료된 파일의 내용을 문자열로 반환합니다."""
    return 0

일단 bolding이라는 함수를 정의하는 것은 완료했고, 세심한 독스트링까지 완료했다.(참고로 독스트링은 ChatGPT가 잘만든다.)

그럼 함수의 내부 로직을 설정해보자.

내부 로직

  1. s가 문자열이면 그냥 두고, 파일의 주소이면 파일을 읽어온다.
  2. 패턴을 찾아 볼드처리 한다.
  3. 문자열을 반환 or 파일을 수정한다.

간단한 3단계이다.

엄격한 TDD에서는 이 내부 로직을 목표로 하는 작은 테스트를 만들어야 한다.

하지만 나는 TDD라는 이름에 너무 매몰되지 않는게 좋다고 생각한다.

근데 일단 만들기는 하겠다.

1. s가 문자열이면 그냥 두고, 파일의 주소이면 파일을 읽어온다.

s라는 변수명이 별로인거 같아 'path_or_text'이라는 변수명으로 대체하겠다.

다음과 같은 세부 테스트를 만들었다.

    def test_load_file_path():
        assert read_file_if_path(Path("./test.txt")) == "테스트를하자."
        assert read_file_if_path(test1str[0]) == test1str[0]

해당 테스트가 성공하면 해당 기능은 되는거다.

해당 기능을 구현하고 테스트해보자.

구현

import re
from pathlib import Path

def read_file_if_path(path_or_text:str|Path) -> str:
    if isinstance(path_or_text, Path):
        with open(path_or_text, 'r', encoding='utf-8') as file:
            text = file.read()
            return text

    return path_or_text

테스트 실행

이렇게 방금 만든 테스트가 성공했다!(1 passed라고 써있는게 성공한 것이다.)

좀 길어진 것 같으니 다음편에 계속...