1P by GN⁺ | ★ favorite | 댓글 1개

Meta의 새로운 LLM 기반 테스트 생성기는 개발의 미래를 엿볼 수 있는 기회

  • Meta는 "Automated Unit Test Improvement using Large Language Models at Meta"라는 논문을 발표함.
  • 이 논문은 AI를 사용하여 개발 속도를 높이고 소프트웨어의 버그를 줄이는 방법을 보여줌.
  • LLM을 개발자의 워크플로우에 통합하면서, 현재 코드 커버리지를 개선하는 정확하고 완전한 소프트웨어 개선안을 제안함.

주요 포인트

  • TestGen-LLM은 'Assured LLM-based Software Engineering' (Assured LLMSE) 접근 방식을 사용함.
  • 여러 LLM, 프롬프트, 하이퍼파라미터를 사용하여 코드 개선안을 생성하고, 최선의 개선안을 선택하는 앙상블 접근법을 사용함.
  • TestGen-LLM은 기존의 인간이 작성한 테스트를 개선하는 데 특별히 설계되었음.

통계

  • Instagram의 Reels와 Stories 제품 평가에서 TestGen-LLM이 생성한 테스트 케이스의 75%가 정상적으로 빌드되었고, 57%가 신뢰성 있게 통과했으며, 25%가 커버리지를 증가시킴.
  • TestGen-LLM은 적용된 모든 클래스의 10%를 개선할 수 있었고, 개발자들이 73%의 테스트 개선안을 수용하여 프로덕션에 적용함.
  • Meta 엔지니어들이 Instagram의 테스트 커버리지를 늘리기 위해 테스트를 생성하는 "test-a-thon"에서 TestGen-LLM 테스트가 추가한 코드 라인의 중간값은 2.5였음.

실천 가능한 인사이트

  • LLM을 사용하여 개발 생산성과 소프트웨어 신뢰성을 효율적으로 향상시킬 수 있는 좋은 예시임.
  • LLM의 진정한 가치는 예상치 못한 엣지 케이스를 찾고 잡는 데 있음.
  • LLM을 생산에 사용하기 위해서는 오케스트레이션, 파이프라인, 처리가 필요함.

TestGen-LLM 작동 방식

  • TestGen-LLM은 Meta의 내부 LLM에 의해 생성된 후보 솔루션에 일련의 의미론적 필터를 적용하여 가장 가치 있는 테스트만 보존함.
  • 필터 1: 빌드 가능성, 필터 2: 실행(테스트 통과 여부), 필터 3: 변덕스러움, 필터 4: 커버리지 개선.
  • 이러한 처리 필터는 테스트 스위트의 개선을 보장함.

결론

  • 이 논문은 많은 개발자들이 이미 LLM을 사용하여 소프트웨어 신뢰성 공간에서 LLM의 진보를 추적하는 좋은 방법임.
  • LLM이 점점 더 복잡한 소프트웨어 시스템에서 버그를 찾고 테스트할 수 있게 될 것임.

GN⁺의 의견

  • 이 기사는 인공지능이 소프트웨어 개발의 미래에 어떤 영향을 미칠 수 있는지에 대한 흥미로운 통찰을 제공함.
  • TestGen-LLM과 같은 도구는 개발자의 작업을 자동화하고 효율성을 높이는 데 큰 도움이 될 수 있음.
  • 이러한 기술의 발전은 소프트웨어 개발의 복잡성을 줄이고, 품질을 향상시키며, 개발자의 시간을 절약하는 방향으로 나아가고 있음.

댓글과 토론

Hacker News 의견들
  • LLM을 구현보다 테스트 코드 작성에 먼저 쓰려는 흐름이 흥미로움
    TDD를 너무 많이 해서 그런지, 테스트는 시스템이 어떻게 동작해야 하는지를 설명하는 것이고 이 부분은 사람이 정의해야 한다고 봄. 코드는 테스트가 만든 가드레일 안에 맞춰져야 함
    다만 LLM이 명세가 부족한 영역을 짚어 주는 데는 도움이 될 수 있음. 명세가 덜 된 부분에 대한 단위 테스트를 제안하게 하는 방식이 여기서 일어나는 일일 수도 있음
    LLM 이전에도 테스트를 다 써두면 원숭이가 타자기로 애플리케이션을 만들 수 있지 않을까 가끔 생각했음

    • 레거시 코드베이스에서는 흔히 특성화 테스트(characterisation tests) 를 만듦
      사람이 코드가 어떻게 동작해야 한다고 믿는지가 아니라, 현재 코드베이스가 실제로 어떻게 동작하는지를 정의하는 테스트임
      이를 통해 회귀를 최소화하면서 재작성, 리팩터링, 재설계를 할 수 있음. 많은 레거시 코드의 문제는 아무도 의도된 동작을 이해하지 못한다는 데 있고, 때로는 사용자조차 실제 동작과 다른 방식으로 동작해야 한다고 믿음
      그래서 명시적으로 원하는 변경이 아니라면 동작을 바꾸지 않는 것이 가장 중요함
    • 이미 알고 있을 수도 있지만 속성 기반 테스트(property-based testing) 를 떠올려볼 만함. Hypothesis가 아마 가장 널리 알렸고 추천할 만하지만, 유일한 접근도 고품질 구현도 아님. Haskell의 QuickCheck도 HN에 보일 만큼 커졌던 시기가 있었음
      기본 아이디어는 완전한 닫힌 형식의 증명 체계보다는 약한 코드 동작 명제를 “속성”으로 표현하고, 본질적으로 확률적인 한계 안에서 검증하는 것임
      대표 예시는 문자열 뒤집기임. 문자열을 두 번 뒤집으면 보통 입력이 나와야 함. 코드 한 줄로 시간과 전기만 허락하는 만큼 이상한 유니코드 경계 사례도 확인할 수 있음
      예시는 사소해 보이지만, PyTorch가 된 자동 미분과 커널 작업을 하던 CUDA 고수들이 이 방식을 엄청나게 잘 써서 절반의 노력과 비용으로 코드 신뢰도를 5배쯤 얻는 걸 봤음
      항상 잘 맞지는 않지만 맞아떨어지면 훌륭하고, LLM은 처음부터 시작하는 것보다는 Hypothesis 사례에 꽤 가까이 접근할 수 있어 보임
    • 구현 코드를 쓰는 건 애플리케이션이 실제로 해야 할 일을 만드는 것이어서 훨씬 즐겁고 흥미로움
      반대로 테스트를 쓸 때는 극도로 장황하고 제약 많은 언어로 애플리케이션이 해야 할 일을 설명해야 하고, 몇 개의 미화된 if/else를 넣기 위해 수십 줄 또는 수백 줄의 설정 코드를 써야 함
      C++나 Java 같은 언어에서는 단위 테스트가 지루함으로 이루어져 있어서, LLM에게 그 일을 맡기려는 본능이 생기는 게 전혀 놀랍지 않음
    • 많은 엔지니어가 실제로는 테스트를 잘 하지 않기 때문일 수 있음
      며칠 동안 코드를 짠 뒤 어쩔 수 없이 시스템이 동작한다는 걸 “증명”하는 테스트 몇 개를 나중에 쓰는 엔지니어들을 많이 봤음. 커버리지는 낮고 보통 깨지기 쉬움
      그런 식으로 생각하고 일하는 엔지니어에게 이런 시스템은 신의 선물처럼 보일 것임
      테스트를 먼저 쓰면 느리다며 금지한 매니저도 있었음. 다행히 파견 상태라 “내 상사에게 말하라”고 하며 무시할 수 있었지만, 아마 위 엔지니어들과 같은 생각이었을 것임
      다른 식으로 보면 대부분의 개발자는 문서를 싫어함. 코드에서 훌륭한 문서를 써주는 AI가 있다면 좋아할 것임. 그리고 그런 개발자들에게는 자신이 쓰지 않아도 되는 문서가 훌륭한 문서임
    • AI 바깥에서도 테스트 코드가 다뤄지는 방식을 보면 비슷하게 느낌
      테스트 코드는 종종 낮은 우선순위 코드로 취급되어 더 주니어 엔지니어에게 맡겨지는데, 원하는 방향과 정반대로 보임
  • 전체를 다 검토하고 싶지는 않지만, 한 부분은 특히 크게 빗나간 듯함
    원 논문은 올라온 직후 대충 읽었고 지금은 훑어보는 중이라 기억이 흐릿하다는 전제가 있음
    블로그는 Meta의 TestGen-LLM 테스트 대부분이 추가로 2.5줄만 커버했지만 한 테스트가 1326줄을 커버했고, 그 한 테스트의 가치가 “지수적으로 더 크며” LLM이 적극적으로 틀 밖에서 생각해 예상치 못한 경계 사례를 잡는 가치가 크다고 썼음
    하지만 “지수적으로 더 가치 있다”는 표현부터 헛소리 탐지기를 울려야 함. 논문을 보면 저자들은 이 1326줄 커버리지를 잭팟을 맞은 단일 테스트로 설명하고, 단일 TestGen-LLM 테스트에서 기대할 현실적인 추가 라인 커버리지는 중앙값 2.5줄이라고 말함
    저자들은 “예상치 못한 경계 사례”나 “틀 밖에서 생각하기”를 언급하지 않음. 오히려 끔찍한 switch 문의 한 분기를 건드렸거나, 코드 커버리지 계산 방식의 우연일 수도 있는 예외적 사례로 제시함
    “정성적 결과” 섹션에서도 이를 더 파고들지 않은 점이 눈에 띔. 부정확한 해설은 아무에게도 도움이 안 됨. 인터넷에는 읽은 척한 것을 이해한 척하는 사람이 이미 너무 많음

    • 글쓴 사람인데, 논문 저자들이 “예상치 못한 경계 사례”나 “틀 밖에서 생각하기”를 말했다고 하려던 건 아니었음
      일부 해석은 내 의견이라는 점이 더 분명해지도록 글을 수정했음
      이 글은 논문 요약이라기보다 논문 결과가 의미하는 바에 대한 논평에 가까움. 어쨌든 Hacker News는 토론을 위한 곳이니까
      그래도 “지수적으로 더 가치 있다”는 부분은 여전히 맞다고 봄. LLM이 테스트 커버리지 측면에서 우연히 “잭팟”을 맞을 수 있다는 점이 바로 가치의 핵심임
      계속 여러 조합을 시도하다가 논문처럼 잭팟 하나만 맞아도 팀에는 매우 가치 있음. 사람이 직접 쓰기엔 명확하지 않았거나 너무 지루했던 테스트일 수 있음
      Big Tech 코드베이스(F/G)에서 무엇을 테스트해야 하는지는 이미 알면서도 “어떻게 테스트할지”만 알아내느라 너무 많은 시간을 쓴 입장에서는 그 가치가 크다고 봄
    • Meta의 코드 생산 인센티브는 전반적으로 잘못돼 있음
      이 팀도 코드 줄 수와 diff 개수 중심으로 몰아가고 있는 게 분명함. 결국 디버그하기 어려운 코드 산을 하나 더 만드는 코드 생성 도구가 될 뿐임
  • 좋은 테스트는 어렵고, 커버리지는 무조건 좋은 것이 아님
    테스트를 너무 많이 써서 프로그램을 굳혀버리고 사실상 변경 감지 프로그램을 만들기 쉽다. “뭔가 바꿨네요, 모든 테스트가 깨졌습니다. 괜찮아요, 이제 LLM에게 다시 생성하라고 하면 됩니다! 100% 커버리지! 놀랍네요! 진보네요!” 같은 식이 됨

    • 동의함. 좋은 테스트는 좋은 코드보다 한 자릿수 이상 더 어려움
    • “변경 감지 프로그램”이라는 관점이 흥미로움. 왜 그게 나쁜지 궁금함
      내게는 그 변경이 의도된 것인지 확인할 기회임. 그게 없으면 프로그램이 해야 할 일을 하는지 어떻게 알 수 있나?
    • 커버리지가 없는 코드에는 형편없는 테스트가 있다는 건 확실히 알 수 있음
      그 외에는 다른 다섯 사람이 생각한 좋은 테스트를 읽어봐야 함. 우리는 모두 테스트를 잘 못 쓰고, 각자 자기 방식으로 할 뿐임
    • 한 일터에는 웹 컴포넌트 테스트가 있었는데, 기대 DOM의 스냅샷을 커밋하고 컴포넌트가 그걸 뱉는지 검증했음
      이후 모든 변경에서 개발자는 자연스럽게 재생성 버튼을 누르고 전부 커밋했음. diff는 풍부했지만 신호는 의심스러웠음
    • 핵심은 긴 꼬리 사례에 있음
  • 반도체 업계, 특히 계산 리소그래피에서 테스트 주도 설계가 표준인 곳에서 일해본 뒤로는 납득이 잘 안 됨
    프로덕션 코드보다 테스트를 항상 먼저 써야 한다는 뜻은 아님. 하지만 테스트는 코드베이스의 다른 부분만큼이나 코드의 일부이고, 반드시 테스트 대상 코드와 함께 작성되어야 함
    테스트에서 가장 중요한 부분은 개발자의 의도를 보여주는 것임. 테스트 스위트는 코드가 어떻게 사용되어야 하는지, 무엇을 하는지, 무엇을 하지 않는지, 무엇을 위해 작성되었는지를 보여줌
    그러면 다른 개발자가 그 코드를 쓰거나 수정할 때 코드베이스에서 셜록 홈즈처럼 단서를 찾아다닐 필요가 없음
    테스트가 이야기를 들려주지 않는다면 테스트를 잘못 쓰고 있는 것임
    컴퓨터가 마음을 읽고 의도를 더 잘 이해할 수 있게 되기 전까지는 AI/LLM 기반 생성기가 이 일을 대신할 수 없음
    물론 테스트 스위트의 유일한 목표가 커밋 전 체크에서 초록 체크 표시를 받고 멋진 커버리지 숫자를 보여주는 것이라면 AI로 생산성을 두 배로 만들 수 있음
    자동 코드 생성기는 나쁜 코드를 빛의 속도로 더 많이 쓰게 도와줄 것임. 보일러플레이트가 많아 코드가 비대하고 이해하기 어렵다고 누가 불평하면, AI로 처리하라고 하면 됨. 당신에게는 먹혔으니까
    정말 개발의 미래가 그렇게 보이지만, 내가 기대하는 미래는 아님

    • 거의 전부 동의하지만, 이런 유형의 테스트에도 자리는 있다고 봄
      설명한 건 코드의 “핵심”을 테스트하는 쪽으로 보임. 문서화, 검증, 안정성의 일부를 겸하는 테스트임
      퍼징 같은 다른 테스트는 완전히 다른 가치를 제공함. AI 기반 테스트는 분포의 꼬리 쪽, 인간의 에너지와 시간이 부족해서 방치되는 가치가 낮은 다수의 테스트를 겨냥하는 공간을 차지할 수 있다고 봄
      현재 AI 도구의 상태도 그렇게 봄. 인지 보조 도구
      이 연구 방향이 앞으로 몇 년 안에 꽤 결실을 내지 못한다면 오히려 놀랄 것 같음
  • 논문 자체가 올라왔을 때 썼던 내용을 약간 다듬어 다시 인용함. 이들의 글은 통계를 잘못 표현함
    https://news.ycombinator.com/item?id=39406726
    초록은 실제 논문 내용과 맞지 않음. 요약은 테스트 케이스 기준 비율처럼 “75%가 올바르게 빌드, 57%가 안정적으로 통과, 25%가 커버리지 증가”라고 읽히게 함
    실제 보고서는 테스트 클래스 기준으로 말하며, 각 클래스에는 하나 이상의 테스트 케이스가 있음
    “75%의 테스트 클래스에 올바르게 빌드되는 새 테스트 케이스가 하나 이상 있었다”, “57%의 테스트 클래스에 올바르게 빌드되고 안정적으로 통과하는 테스트 케이스가 하나 이상 있었다”, “25%의 테스트 클래스에 같은 빌드 대상의 다른 테스트 클래스 대비 빌드되고 통과하며 라인 커버리지를 늘리는 테스트 케이스가 하나 이상 있었다”는 뜻임
    이 둘은 완전히 다른 문장임. 각 테스트 클래스 확장 시도에는 테스트 케이스 생성 시도가 여러 번 있을 수 있어서, 테스트 케이스당 성공률은 보통 테스트 클래스당 성공률보다 훨씬 낮다는 각주까지 있음
    그런데 결론에서는 초록처럼 다시 결과를 잘못 표현함. 실험 모드에서 TestGen-LLM을 쓰면 테스트 케이스당 성공률이 25%였고, 라인 커버리지 요구를 완화해 빌드와 통과만 요구하면 성공률이 57%로 오른다고 씀

  • 앞으로 이 형편없는 LLM 레거시 코드를 유지보수할 사람들에게 감정이입됨
    보기 흉할 것임

    • 당연히 그걸 유지보수할 LLM을 쓰게 될 것임
    • 그렇다면 LLM은 일자리를 없애기보다 만들고 있는 셈임. 다만 별로 재미있는 일자리는 아닐 듯함
    • 엔터프라이즈식 코드보다 더 나쁘지는 않을 것 같음
      오히려 꽤 비슷해 보일 수도 있고, 주석과 문서는 더 충실하며 적극적으로 틀릴 가능성은 낮을 수도 있음
    • 테스트를 지우면 문제 해결임. CI 대시보드도 초록 체크를 보여줌
    • 동의함
      LLM은 지금보다 절대 나아지지 않을 것이고 지난 2년 동안 전혀 발전하지 않았음. 그냥 화려한 마르코프 체인일 뿐임
      코딩을 모르는 사람이 아무 검토 없이 프로덕션에 코드를 맹목적으로 커밋할 때만 코드 작성에 쓸 수 있음
      코딩을 아는 사람에게는 쓸모가 있을 리 없고 생산성도 높여주지 못함
      세상을 전혀 바꾸지 않는 이 LLM 헛소리는 무시할 것이고, 당신도 반드시 그래야 함
  • 잘 분리해두지 않으면, 무지한 관리자가 높은 커버리지를 요구하고 열정적인 주니어들이 대량의 AI 테스트를 몰래 넣으면서 쉽게 개발자에게 적대적인 환경이 됨
    결국 작업을 제출할 때마다 유지보수하기 어려운 LLM 생성 테스트 코드에서 도장을 받아야 하는 상황이 됨
    일부 테스트 작성은 빨라질 수 있지만 유지보수가 빨라진다는 보장은 없음. 테스트 대상 코드의 유지보수도 마찬가지임. 좋은 테스트가 생성된다는 보장이 없기 때문임
    테스트를 쓰며 고생하는 과정은 개발자가 설계를 초기에 점검하는 데도 보통 도움이 됨. 테스트하기 어렵다면 대개 좋은 설계가 아니고, 예컨대 다른 사람들과 함께 코드를 작성해야 하는 맥락에서 컴포넌트 계약이 충분히 추상화되지 않은 경우가 많음
    놓치기 쉬운 점은 테스트가 희생 가능한 코드라는 점임. 대부분은 평생 아무것도 잡지 못할 것이고, 그래도 괜찮음. 자동화된 안심을 주고 실패 시 잘못된 단서를 줄여주기 때문임
    하지만 확률적 안전장치에 최대 투자를 한다고 항상 보상이 나오지는 않음. 커버리지가 꼭대기에 가까워질수록 한계 효용은 줄어듦. 표준 라이브러리처럼 트래픽이 많은 실행 경로가 아니라면 높은 커버리지를 자랑해도 대개 보답받지 못함
    게다가 거의 항상 단위 테스트만이 아니라 통합 테스트, 시스템 테스트 등 테스트 생태계가 있어야 전체가 굴러감. LLM이 설계 회의에 앉아 아키텍처를 이해하고 그런 테스트도 써줄까? 아니면 할 수 있는 일이 과장되어 해야 할 일을 밀어낼까?
    테스트에 노력을 투자할 때는 작성 시점뿐 아니라 설계와 유지보수 시점에도 “무엇이 관련 있는가”를 판단하는 감각이 필요함. 인간은 이걸 꽤 잘하지만 AI 도구는 그렇지 않음
    LLM이 시간을 아껴줄 수 있는 부분은 무엇을 테스트하면 좋고 아닌지 이미 감이 있는 숙련 개발자의 키 입력임. 동시에 별로 관련 없는 것들을 코드에 몰래 들여오게 만들어 방해가 될 수도 있고, 이미 그래 왔음
    키 입력을 생산하는 경제는 원하지 않음. 충분히 생각된, 관련성 높은 키 입력의 집합을 원함. 그리고 후자가 전자와 잘 분리되어 시간이 지나며 객관적 효용 또는 그 부재가 드러나길 바람

  • 이미 GPT-4로 해봤음
    TypeScript 모듈을 보여주고 단위 테스트를 생성하라고 했더니 정상 경로뿐 아니라 몇 가지 경계 사례까지 커버하는 동작하는 테스트를 만들어줬음

    • 비슷한 댓글들이 왜 다운보트를 받는지 잘 공감이 안 됨
      ChatGPT는 여러 면에서 기대 이상으로 해줌. 테스트는 GPT 능력 기준으로는 쉬워 보임
      지난주에는 AST를 순회해 React Flow 그래프와 컴포넌트를 만드는 Python 코드를 쓰게 했음. 수정은 하지 않았고 프롬프트 피드백을 몇 번 반복했더니 아주 잘 동작했음. GPT에서 비슷한 흥미로운 능력을 많이 봤음
  • AI는 어떤 테스트를 써야 하는지 어떻게 아는가?
    흥미로운 실험이긴 하지만 다소 미심쩍음. 소프트웨어 개발에서 AI가 가장 잘 도울 수 있는 방식은 프로그래머가 자기 코드나 다른 사람의 코드에 대해 질문하면 AI가 답하는 것이라고 봄. 때로는 코드 제안이 포함되겠지만 항상 그럴 필요는 없음
    “이 코드를 단순화할 방법이 있나?”, “어떤 입력이 오류를 일으킬 수 있나?” 같은 질문에 답할 수 있어야 함
    AI는 우리가 코드를 이해하고 개선 방법을 이해하도록 도와야 함. 우리가 무엇을 하라고 말하지 않으면 AI는 우리가 원하는 것을 알 수 없으므로 전부 스스로 쓰게 해서는 안 됨
    테스트가 좋은 예임. 우리는 무엇을 테스트하길 원하는가?

  • 드디어 납득되는 AI 코드 생성이 나왔음