테스트 주도 개발 ( TDD ) 을 Pintos 할 때, 이용해 보자 [ 크래프톤 정글 64일차 ]

jinsung·2025년 7월 16일
4

크래프톤 정글 9기

목록 보기
54/59


테스트가 중요한 이유.png

안녕하세요.

드디어 대망의 Pintos 첫 주차를 진행 했습니다.

이번 주차에 느꼈던 점, 개선하고 싶은 점, 그리고 공유하고 싶은 점 등을 적어보려고 해요. 특히 TDD에 대해서요.

근데 우리가 TDD를 작성하자는 이야기는 아닙니다.
테스트 코드는 이미 작성되어있으니까, 그걸 최대한 이용해보자는 이야기예요.

✅ [ WEEK09 ] 정글 끝까지(PintOS) - Threads


WEEK 진행률

🎯 1. 키워드 공부

  • ☑️ Process, Thread
  • ☑️ CPU Scheduling 알고리즘
  • ☑️ Semaphore와 Mutex
  • ☑️ Race Condition
  • ☑️ Deadlock
  • ☑️ Context Switching
  • ☑️ Multi-Level Feedback Queue Scheduler (MLFQS)

🎯 2. 테스트 케이스

  • ☑️ alarm-single
  • ☑️ alarm-multiple
  • ☑️ alarm-simultaneous
  • ☑️ alarm-priority
  • ☑️ alarm-zero
  • ☑️ alarm-negative
  • ☑️ priority-change
  • ☑️ priority-donate-one
  • ☑️ priority-donate-multiple
  • ☑️ priority-donate-multiple2
  • ☑️ priority-donate-nest
  • ☑️ priority-donate-sema
  • ☑️ priority-donate-lower
  • ☑️ priority-fifo
  • ☑️ priority-preempt
  • ☑️ priority-sema
  • ☑️ priority-condvar
  • ☑️ priority-donate-chain
  • ❗️ mlfqs-load-1
  • ❗️ mlfqs-load-60
  • ❗️ mlfqs-load-avg
  • ❗️ mlfqs-recent-1
  • ❗️ mlfqs-fair-2
  • ❗️ mlfqs-fair-20
  • ❗️ mlfqs-block
  • ❗️ mlfqs-nice-2
  • ❗️ mlfqs-nice-10

진행률 : 70% ( MLFQS 제외 "완벽히 이해" )

테스트 주도 개발 ( TDD )

정글에 입소하기 전에 1년 10개월 정도 프론트엔드 개발자로 일을 하면서 테스트 주도로 개발하는 TDD 라는 방식이 있고, 꽤 많이 사용되는 것을 알고 있었어요.

근데 솔직히, 개발하면서 피드백이 거의 실시간으로 화면에 반영이 되니

  • "화면에 바로 보이는데 굳이 테스트가 필요한가?"
  • "내가 테스트 케이스 작성이 필요할 정도로 어려운 도메인을 개발하고 있나?"

라는 의문이 있었고, 회사에서도 TDD 개발을 실제로 해보진 않았습니다.
그리고 사실은, 어떻게 하는지도 잘 몰랐어요.

그런데 이번에 Pintos 에서 os를 직접 개발해보면서 TDD 의 강점을 확실히 느낀 것 같아요.
Pintos는 작성되어 있는 기능을 더 업그레이드, 즉 유지보수 하는 작업이 많았어요.

예를 들어, 원래는 ready_list는 쓰레드를 list 의 가장 뒤 쪽으로 순서대로 넣어주고 가장 앞 쪽에 있는 쓰레드를 CPU에 스케쥴링 하는 Queue와 같은 FIFO 방식이었어요.

근데 우선순위 스케쥴링을 구현하면 ready_list 에 입력할 때, 우선순위 순으로 쓰레드를 정렬해서 넣어줘야 했습니다.

이 기능을 구현할 때, "어떤 함수를 수정해야 하는가","무엇을 추가해야 하는가"를 파악하는 것도 꽤 공수가 드는 일이었는데요.

Pintos에 작성되어 있는 tests 파일의 테스트 케이스를 보면 그 일이 훨씬 수월해짐을 느꼈습니다.

TDD에 대해 간단히 설명하고 Pintos 에서는 어떻게 테스트 케이스를 보면서 더 코드 분석시간이 줄어드는지 2분안에 살펴보겠습니다.

TDD란?

TDD는 말 그대로 테스트 주도로 개발하는 방식인데요.

"테스트를 먼저 작성하고, 그 테스트를 통과하도록 코드를 작성하는 방식의 개발" 입니다.

  1. Red: 실패하는 테스트 코드를 먼저 작성
  2. Green: 해당 테스트를 통과하는 최소한의 코드를 작성
  3. Refactor: 코드 구조를 개선 ( 그러나 기능은 유지 )

이렇게 테스트 코드를 먼저 작성하고 개발을 진행하면

  • 요구사항이 명확해집니다.
  • 코드를 수정, 기능을 추가할 때 수시로 빠르게 검증할 수 있습니다.
  • 리팩토링 시 안전성을 확보할 수 있습니다.

저희가 이번 주 개발을 진행할 때도, 코드 변경점이 있을 때마다 수시로 테스트를 진행하면서 코드에 대한 피드백을 빠르게 받을 수 있었어요.
만약 테스트코드 자체가 없었다면 이 코드가 올바른지 확인하는 것도 어려운 작업이었을 거예요.

TDD 에도 단점이 있는데요.

1. 학습 곡선이 존재한다.

테스트 코드를 작성하는 법도 배워야 하고, 테스트 코드를 먼저 작성하는 방식이 초보자한테는 좀 어려워요.

2. 복잡한 UI/비동기 로직은 테스트 작성이 어렵다

제가 개발을 할 때 느꼈던 거지만, DOM 조작이나 비동기로직은 테스트 코드 작성하기가 난감하더라구요. 또 UI는 뭐 TEXT 가 잘 출력되는걸 확인하는건지..사실 아직도 잘 모르겠습니다.

3. 잘못된 테스트는 발목을 잡는다.

테스트 코드 자체가 잘못되었을 경우에는 오히려 전혀 원인을 알 수 없는 문제에 빠졌다고 느껴질거예요. 오히려 코드 작성을 방해하는 경우가 될 수도 있습니다.

Pintos 에서는 어떻게?

친절하게도 Pintos 에서는 테스트 케이스를 단계별로 완성하면, 이전 테스트 케이스에 영향을 주지 않아요. ( 지금까지는요 ㅋ 앞으로는 나도 몰?루 )


F1 car racer "김기래"가 만든 편의성 테스트 케이스

이 테스트 코드를 실행하면 테스트 케이스를 순서대로 확인할 수 있는데요.
각 테스트 케이스를 단계별로 파악하면서 코드 수정을 진행하면 제법 빠르게 진도를 나갈 수 있어요.

두 가지를 파악하는게 중요한데요. 기능을 완성하기 위해서:

  • "어떻게 수정해야 하는가?"
  • "어떤 것을 수정해야 하는가?"

이것을 3번 alarm-priority 를 예시로 빠르게 파악해 보겠습니다.

우선, Pintos-kaist/tests 폴더에 가면, 작성된 테스트 케이스들을 확인할 수 있어요.

.c파일에는 작성된 테스트 케이스를 확인할 수 있고
.ck파일에는 정답 출력이 나와있어요.

alarm-priority.ck 를 보면 30 29 28 27.. 순서대로 출력이 되고 있고
이게 내가 달성해야 하는 목표임을 알 수 있어요.

"어떻게 수정해야 하는가"를 한 눈에 확인할 수 있습니다.

그럼 원래의 출력은 어떻게 되나 살펴볼까요?

원래의 출력은 순서도 이상하고 뒤죽박죽입니다.

이걸 "큰 숫자부터 출력되게 변경해야 한다" 라는 목표를 설정할 수 있었어요.

그럼 "어떤 걸 수정해야 하는가"는 어떻게 알 수 있을까요?

c파일에서 어떤 함수가 사용되고 있는가를 파악하면 알 수 있어요.

thread_create의 3번째 매개변수로 들어가는 함수가
실제로 해당 쓰레드가 실행할 작업입니다.

그 함수에는 다른 여러가지 것들이 있지만 거의 유일하게 timer_sleep이라는 함수가 사용되고 있는걸 확인할 수 있어요.

그럼 보통 "직접 함수를 만들고 추가하지 않는 것을 제외하고는 그 부분을 수정"하면 웬만하면 정답입니다.

timer_sleep안에 30부터 출력하게 끔 할 수 있는 함수는 보이지 않고
내부적으로 thread_sleep이라는 함수를 또 호출하고 있네요.

이런 무언가를 찾은 것 같습니다!

실제로 list 는 정렬된 상태로 있어야 하지만 list 에 입력할 때 무조건 앞에 넣어주고 있어요.

이걸 정렬된 상태로 넣는다면 문제가 해결이 되지 않을까요?

그렇게 해서 해결이 될 수도 있겠지만, 아닐 수도 있습니다.

만약 저 함수를 정렬하는 방식으로 바꿔주었는데도 정답이 출력되지 않는다면
다른 곳을 수정해줘야 할 수도 있어요.

하지만 어떤 것을 수정해야 하는가는 좀 더 빠르게 찾을 수 있을 것 같아요.
thread_sleep과 같은 리스트를 수정한다던가 관리한다던가요.

마무리

이런 방식으로 테스트 케이스를 잘 활용한다면
좀 더 빠르게 문제를 어떤식으로 해결해야할지 감을 잡을 수 있어요.

민첩한 하루 되세요.

1개의 댓글

comment-user-thumbnail
2025년 7월 16일

당신은 신입니까?

답글 달기