메뉴
HN
Hacker News 54일 전

AI 코딩 에이전트를 위한 나만의 TDD 스킬

IMP
8/10
핵심 요약

현재 AI 에이전트는 학습 데이터의 한계로 인해 테스트 코드 작성에 매우 서툽니다. 하지만 켄트 벡(Kent Beck)의 정석적인 TDD 원칙과 '명세-인코딩-이행(Specify-Encode-Fulfill)' 루프 같은 명확한 가이드라인을 제공하면, AI도 논리적이고 의미 있는 테스트를 작성할 수 있습니다. 이 글은 AI가 스스로 테스트 설계 오류를 점검하게 하고 불필요한 코드 작성을 방지하는 실용적인 에이전트 활용법을 소시합니다.

번역된 본문

Jason Swett의 '테스트 주도 개발(TDD)을 위한 나만의 에이전트 스킬'

AI 에이전트는 적어도 이 글을 작성하는 현재까지도 테스트를 작성하는 데 서툽니다. 에이전트가 작성한 테스트는 종종 모호하고, 알아보기 어렵고, 지나치게 복잡하며, 임시방편적이고, 체계가 없으며, 동어반복적이고, 보여주기식이고, 대충 때우는 느낌이며, 완전히 무의미할 때가 많습니다.

안타깝게도 저는 별다른 지도 없이는 에이전트들이 당장 테스트 작성 실력을 크게 향상시킬 것이라고 기대하지 않습니다. 왜냐하면 에이전트는 인간이 작성한 사례를 통해 학습하는데, 솔직히 말해 인간이 작성한 예시들 역시 대체로 좋지 않기 때문입니다. '초보자'들이 작성한 테스트의 품질이 낮을 뿐만 아니라, 안타깝게도 강사들이 가르치는 테스트 방식도 종종 꽤 형편없습니다. 현재 상황은 정말 처참합니다.

다행히 좋은 소식은, 약간의 가이드만 제공해도 에이전트가 합리적인 TDD 프로세스를 따르고 명확하고 의미 있는 테스트를 작성할 수 있다는 것입니다. 그 가이드는 정확히 무엇일까요? 진실에 아주 가까운 짧은 대답은 켄트 벡(Kent Beck)의 정석적인 TDD(Canon TDD)입니다. 에이전트의 스킬에 "켄트 벡의 정석 TDD를 따르라"는 지시 하나만 추가해도 원하는 결과의 약 60%는 달성할 수 있을 것입니다.

조금 더 긴 대답은 제가 직접 나만의 TDD 스킬에 녹여낸 내용과 같습니다.

나만의 TDD 스킬

이 가이드는 계속 업데이트되는 살아있는 문서이기 때문에, 블로그 포스트에 작성하여 영원히 멈춰버리게 두고 싶지 않았습니다. 대신 GitHub에서 저의 TDD 스킬을 확인할 수 있습니다. 그렇지만 그 핵심은 변하지 않을 것이 확실하므로 여기에 그 본질을 공유하겠습니다.

먼저 저는 에이전트에게 제가 '명세-인코딩-이행(specify-encode-fulfill)' 루프라고 부르는 개념을 알려줍니다. 이는 기존의 '레드-그린-리팩토링(red-green-refactor)'을 대체하는 저만의 방식입니다.

명세-인코딩-이행(SEF)은 다음과 같이 진행됩니다:

명세(Specify): 구축하고자 하는 것의 명세를 작성합니다. 인코딩(Encode): 그 명세를 자동화된 테스트(실행 가능한 명세)로 인코딩합니다. 이행(Fulfill): 명세를 충족시키는 코드를 작성합니다.

SEF는 저에게 TDD가 무엇인지 보여주는 높은 수준의 관점입니다. 조금 더 구체적인 수준에서는 켄트 벡의 정석 TDD가 있으며, 이를 제 나름의 말로 아래와 같이 설명할 수 있습니다.

  1. 현재 TDD 세션의 범위 내에 있는 명세 목록을 작성합니다.
  2. 목록의 각 항목을 자동화된 테스트로 인코딩합니다.
  3. 현재 테스트 실패를 해결하기 위해 딱 맞는 최소한의 코드만 수정합니다. '투기적 코딩(Speculative coding)'을 피하세요. 현재 테스트 실패를 해결하는 데 필요한 것보다 더 많은 코드를 작성하면, 어떤 테스트도 실행되지 않는 코드를 만들 위험이 있습니다.
  4. 선택적으로 리팩토링을 수행하되, 동작 변경을 커밋하기 전에는 리팩토링을 하지 마세요. 동작 변경과 리팩토링을 절대 섞지 마세요.
  5. 목록이 빌 때까지 2번 항목으로 돌아갑니다.

나의 TDD 스킬에는 조금 더 많은 세부 사항이 포함되어 있지만, 이것이 프로세스의 핵심입니다. 하지만 이 프로세스는 테스트 자체의 설계에는 큰 영향을 미치지 않으므로, 이를 위해 '테스트 설계 검토(Test Design Review)'라는 별도의 스킬을 사용합니다.

테스트 설계 검토 스킬은 편향을 피하기 위해 별도의 에이전트를 생성하여, (예를 들어 테스트가 목적이 아닌 수단에 초점을 맞추는 경우와 같은) 설계 원칙 위반을 찾아내고 수정 제안을 합니다. 때로는 이 '수정'이 모호할 때도 있지만 대체로 정확합니다. 에이전트가 특정 테스트를 작성한 방식에 만족하지 못할 때, 저는 에이전트가 스스로 실수를 찾아낼 수 있도록 이 테스트 설계 검토를 실행합니다.

일반적인 설계 검토

많은 테스트 설계 위반은 "사물을 있는 그대로 호출하라"와 같은 일반적인 소프트웨어 설계 원칙을 위반한 것일 뿐입니다. 테스트 설계 검토 스킬을 통해 테스트를 검토하는 것 외에도, '소프트웨어 설계 검토(Software Design Review)' 스킬을 통해 테스트를 한 번 더 검토하는 것을 선호합니다.

에이전트는 저를 놀라게 할 때가 있습니다. 제 TDD 스킬에 "작성하려는 테스트를 작성하기 어렵다면, 그것은 식사를 하기 전에 먼저 주방을 청소해야 한다는 신호일 수 있다"는 지시를 별다른 기대 없이 포함시켰습니다. 그런데 어떤 이유에서인지 Claude가 이 지시를 아주 진지하게 받아들여서, 심심하면 잠시 멈추고 혹시 주방을 청소해야 하는지 묻곤 합니다. 그리고 실제로 대부분의 경우 청소를 해야 하는 상황이 맞았습니다.

아직 저는 제 에이전트가 글을 완벽하게 작성하게 하지는 못했습니다.

원문 보기
원문 보기 (영어)
My Agent Skill for Test-Driven Development by Jason Swett AI agents tend to be, at least as of this writing, lousy at writing tests. The tests they write are often vague, cryptic, overcomplicated, hacky, disorganized, tautological, performative, perfunctory and downright pointless. Unfortunately, I don't expect uncoached agents to get much better at writing tests anytime soon, because the agents learned by human-written example, and the human-written examples out there are often, I'm sorry to say, just as bad. Not only are the tests written by "amateurs" often poor quality, but, sadly, the testing practices preached by teachers are often pretty bad as well. It's truly rough out there. The good news is that I've found that, with a bit of guidance, agents are capable of following a rational TDD process and of writing clear, meaningful tests. What exactly is that guidance? The short answer, which can serve as a close enough approximation to the truth, is Kent Beck's Canon TDD . If you give your agent a skill that says nothing more than "Follow Kent Beck's Canon TDD" then I suspect you'll be a good 60% of the way there. The longer answer is what I've baked into my own personal TDD skill. My TDD skill Since it's a living document, I don't want to bake my TDD skill into this blog post and freeze it in time. Instead, you can see my TDD skill here on GitHub . Having said that, I can certainly share the essence of the skill here since I'm sure that that isn't going to change. First I clue the agent in to what I call the specify-encode-fulfill loop, which is my personal alternative to red-green-refactor. Specify-encode-fulfill (SEF) goes like this: Specify : Come up with the specifications for what you want to build Encode : Encode those specifications as automated tests (executable specifications) Fulfill : Write the code to fulfill the specifications SEF is the high-level view of what, to me, TDD is all about. At a slightly lower level is Kent Beck's Canon TDD, which I've described below in my own words. Write a list of the specifications within scope of the current TDD session Encode each item in the list as an automated test Change the code just barely enough to make the current test failure go away. Avoid "speculative coding" - if we write more code than necessary to make the current test failure go away, we risk having code never exercised by any test Optionally refactor, but not before committing the behavior change. Never mix behavior changes with refactoring Until the list is empty, go back to #2 My TDD skill contains a bit more detail but this is the essence of the process. This process doesn't have much influence over the design of the tests themselves, though, so I have a different skill for that, Test Design Review . Test Design Review spawns a separate agent (in an effort to avoid bias), looks for violations of design principles (such as case is where a test focusing on means rather than ends) and makes suggestions for fixes. Sometimes the "fixes" are dubious but usually they're on the mark. When I'm not satisfied with the way my agent has written a certain test, I run Test Design Review to try to let the agent catch its own mistakes. General design review Many test design violations are just violations of general software design principles, such as the principle of "call things what they are". In addition to feeding my tests through my Test Design Review skill, I like to feed them through my Software Design Review skill as well. My agent surprises me sometimes. In my TDD skill I included an instruction, without much expectation that it would particularly be followed, that if it turns out to be hard to write the test we want to write, that might be a sign we need to "clean the kitchen before we make dinner". For whatever reason, Claude has really taken this to heart, and it pauses quite often to ask if perhaps we should clean the kitchen, and quite often it's the case that we should. I haven't yet gotten my agents to write acceptable tests 100% of the time, not by a long shot, but my TDD skill has worked well enough for me that it has become my default way of making any change. It's not surprising to me that applying these TDD and test design principles yields such good results. In my judgment, the biggest AI productivity gains come from when AI is combined with timeless, immutable principles which were discovered decades ago, hold just as true today, and which, no matter what new technologies may arise, will never cease to be useful. Jason Swett is the host of the Code with Jason Podcast , the author of Professional Rails Testing , and the creator of SaturnCI .