InfoGrab DocsInfoGrab Docs

AI 기능 테스트

요약

이 문서는 GitLab 표준 테스트 가이드라인을 보완하는 AI 관련 테스트 고려사항을 강조합니다. AI 기반 기능은 AI Gateway 및 IDE 확장 프로그램과 같이 GitLab 모노리스 외부의 시스템 구성 요소에 의존합니다.

이 문서는 GitLab 표준 테스트 가이드라인을 보완하는 AI 관련 테스트 고려사항을 강조합니다. 제3자 제공자의 비결정론적 응답과 같이 AI 기능이 테스트에 가져오는 과제에 초점을 맞춥니다. 각 테스트 수준에 대한 예시가 포함됩니다.

AI 기반 기능은 AI Gateway 및 IDE 확장 프로그램과 같이 GitLab 모노리스 외부의 시스템 구성 요소에 의존합니다. 이러한 가이드라인 외에도 각 구성 요소 프로젝트에 문서화된 테스트 가이드라인을 참조합니다.

단위 테스트#

표준 단위 테스트 가이드라인을 따르십시오. AI 기능의 경우 빠르고 신뢰할 수 있는 테스트를 보장하기 위해 항상 제3자 AI 제공자 호출을 모킹합니다.

단위 테스트 예시#

통합 테스트#

AI 제공자에 대한 요청 구성 및 응답 처리를 확인하려면 통합 테스트를 사용합니다. 다양한 응답, 오류 및 상태 코드를 처리하는 예측 가능하고 빠른 테스트를 보장하기 위해 AI 제공자 응답을 모킹합니다.

통합 테스트 예시#

프론트엔드 기능 테스트#

최종 사용자 관점에서 AI 기능을 검증하려면 프론트엔드 기능 테스트를 사용합니다. 속도와 안정성을 유지하기 위해 AI 제공자를 모킹합니다. 고위험 시나리오에 대한 선택적 부정 경로 테스트와 함께 행복한 경로에 집중합니다.

프론트엔드 기능 테스트 예시#

핵심 기능 페이지의 DAP 기능 테스트#

기능 페이지에 DAP 구성 요소를 기본적으로 로드하려면 기능 사양에 공유 컨텍스트 include_context 'with duo features enabled and agentic chat available for group on SaaS'를 포함합니다.

Duo 에이전틱 채팅 기능 사양#

에이전틱 채팅 기능 사양의 커버리지는 ee/spec/features/duo_chat/agentic_chat_smoke_spec.rb에 통합되어 있습니다. 에이전틱 채팅을 테스트하기 위해 새 기능 사양을 추가하기보다 ee/spec/frontend/integration/ai_duo_panel/duo_agentic_chat/의 MSW 통합 스위트를 사용할 것을 강력히 권장합니다.

에이전틱 채팅과 다른 기능 간의 상호작용을 테스트하려는 경우에 기능 사양을 구현합니다. 예를 들어 agentic_chat_smoke_spec.rb 테스트 스위트는 작업 항목, 파이프라인, 머지 리퀘스트 페이지의 Call-to-Action 버튼으로 에이전틱 채팅을 여는 동작을 검증합니다.

AI Gateway에서 변경 시 DAP 기능 테스트 실행#

이 기능 테스트는 AI Gateway 리포지터리에 변경 사항을 적용할 때도 실행되어 MR이 DAP 기능을 실수로 중단하지 않는지 확인합니다. 예를 들어:

  1. 개발자가 AI Gateway 프로젝트에서 MR을 엽니다.
  2. MR에 대한 파이프라인이 실행되며, 이는 aigw/test-branch 테스트 브랜치에 대해 GitLab 프로젝트에서 다운스트림 파이프라인을 트리거합니다. 이 브랜치는 마스터와 동일한 SHA를 가리킵니다.
  3. 파이프라인이 실패하면 개발자는 제안된 변경 사항이 실수로 회귀를 도입하지 않는지 조사해야 합니다.
Note

aigw/test-branch 브랜치는 AIGW 및 DWS 관리자가 GitLab 프로젝트에서 다운스트림 파이프라인을 트리거할 수 있도록 기본적으로 보호되지 않습니다.

DWS/AIGW 변경 사항으로 기능 사양 로컬 실행#

  1. gdk start를 실행하여 DWS를 포함한 서비스를 시작합니다.
  2. <gdk-root>/gitlab에서 터미널을 열고 다음 옵션 중 하나를 사용합니다:
    • export TEST_AI_GATEWAY_REPO_REF=<your-remote-feature-branch>를 실행하고 <gitlab-rails-root>/tmp/tests/gitlab-ai-gateway/ 캐시 디렉터리를 삭제하거나,
    • export TEST_DUO_WORKFLOW_SERVICE_ENABLED="false" && export TEST_DUO_WORKFLOW_SERVICE_PORT=<your-local-dws-port>를 실행합니다. 이를 통해 기능 테스트가 로컬 DWS 인스턴스에 요청할 수 있습니다. 로컬 DWS에 다음 구성이 설정되고 실행 중인지 확인합니다:
      • AIGW_MOCK_MODEL_RESPONSES를 true로 설정
      • AIGW_USE_AGENTIC_MOCK을 true로 설정
  3. 기능 사양을 실행합니다. 예를 들어 bundle exec rspec ee/spec/features/duo_chat/agentic_chat_smoke_spec.rb를 실행합니다.

테스트 케이스의 로그 확인#

DAP는 여러 서비스와 API 호출로 구성됩니다. 테스트 케이스 실패를 디버깅하려면 근본 원인을 파악하기 위해 서비스 로그를 검사해야 할 수 있습니다. 다음 몇 가지 포인터가 있습니다:

  • GitLab-Rails REST API ... log/api_json.log

  • GitLab-Rails GraphQL API ... log/graphql_json.log

  • GitLab-Workhorse ... log/workhorse-test.log

  • DWS ... log/duo-workflow-service.log. CI는 이 파일을 작업 아티팩트로 수집하며, :duo_workflow_service 태그가 붙은 예시가 실패하면 마지막 60줄이 RSpec 출력에 자동으로 출력됩니다.

  • JS 콘솔 로그 출력을 사용하여 VueJS 앱 상태를 검사할 수도 있습니다:

    it 'runs a test' do
      ...
    
      # 브라우저 로그를 출력합니다. JavaScript의 console.log()와 결합하십시오.
      browser_logs.each do |log|
        puts "#{log.level}: #{log.message}"
      end
    
      ...
    end
    

엔드투엔드 테스트#

실제 제공자 응답으로 AI 기능이 작동하는지 확인하기 위해 엔드투엔드 테스트를 드물게 사용합니다. 주요 고려사항:

  • 느린 실행과 잠재적인 제공자 중단으로 인해 테스트를 최소화합니다.
  • 테스트 설계에서 비결정론적 AI 응답을 고려합니다. 예를 들어, AI 생성 콘텐츠가 아닌 챗봇 이름과 같이 제어 가능한 요소에 대한 결정론적 검증을 사용합니다.

E2E 테스트 예시#

라이브 환경 테스트#

  • GitLab.com: 스테이징 및 프로덕션 환경에서 최소한의 E2E 테스트를 지속적으로 실행합니다. 예를 들어 코드 제안 스모크 테스트.
  • GitLab Self-Managed: gitlab-qa 오케스트레이터를 AI Gateway 시나리오와 함께 사용하여 GitLab Self-Managed 인스턴스에서 AI 기능을 테스트합니다.

Duo Agent Platform foundational 플로#

Duo Agent Platform foundational-flow 스모크 테스트는 실제 CI 파이프라인을 통해 플로를 구동하는 오케스트레이션된 엔드투엔드 테스트입니다. gitlab-qa 오케스트레이터는 두 테스트를 e2e:test-on-omnibus-ee 하위 파이프라인의 duo-agent-platform 작업으로 실행합니다.

developer/v1 테스트는 start_workflow: true와 함께 POST /ai/duo_workflows/workflows를 통해 워크플로를 생성한 다음, duo_workflow 소스 파이프라인이 성공하고 워크플로가 finished에 도달하는지 검증합니다. code_review/v1 테스트는 머지 리퀘스트를 생성한 다음, 제품에서 리뷰를 요청하는 방식대로 GitLabDuo 리뷰 봇을 리뷰어로 할당합니다. 그런 다음 duo_workflow 소스 파이프라인이 성공하고, 플로가 finished에 도달하며, 리뷰 봇이 머지 리퀘스트에 리뷰 요약을 게시하는지 검증합니다.

이 테스트들은 두 개의 리포지터리에 걸쳐 있습니다. GitLab 리포지터리는 사양과 플로 프로비저닝 헬퍼를 보유합니다. gitlab-qa 오케스트레이터는 Duo Workflow Service를 부팅하고 GitLab 인스턴스를 해당 서비스로 라우팅하는 인프라를 보유합니다:

  • Component::DuoWorkflowService는 AI Gateway와 동일한 model-gateway 이미지에서 gRPC 및 agentic-mock 모드로 전환된 Duo Workflow Service를 부팅하고, 종료 시 컨테이너 로그를 작업 아티팩트에 캡처합니다.
  • Test::Integration::AiGatewayBase는 Duo Workflow Service를 시나리오에 연결하고 GITLAB_DUO_WORKFLOW_SERVICE_URL 및 GITLAB_DUO_WORKFLOW_SECURE 값을 omnibus Rails 환경에 전달합니다.
  • Test::Integration::DuoAgentPlatform은 AI Gateway 시나리오의 하위 클래스인 전용 시나리오이므로, 플로가 자체 duo-agent-platform omnibus 작업으로 실행되고 Duo Workflow Service 컨테이너는 ai-gateway 작업에서 제외됩니다.

agentic-mock 모드는 실제 모델을 호출하는 대신 지시문에 따라 결정론적 응답을 반환하며, 이는 Duo Chat 및 코드 제안 테스트가 AI Gateway에 사용하는 방식과 동일합니다. 이 지시문을 어디에 넣는지는 플로에 따라 다릅니다. developer/v1 목표는 자유 형식이므로, 이 테스트는 플로 목표에 지시문을 넣습니다. code_review/v1 목표는 머지 리퀘스트 IID 또는 머지 리퀘스트 URL이어야 검증을 통과하며, 그 외의 값은 400을 반환합니다. Code Review 테스트는 대신 지시문을 프로젝트 기본 브랜치에 .gitlab/duo/mr-review-instructions.yaml로 커밋한 사용자 지정 지침에 넣습니다. 이 필드가 플로가 이스케이프 없이 모델 프롬프트로 복사하는 유일한 필드이기 때문입니다.

이스케이프를 잘못 처리하면 모의 응답이 아무 알림 없이 자리 표시자 텍스트를 반환하므로, 다음 규칙에 유의합니다:

  1. 모의 응답은 프롬프트 전체를 XML로 파싱하므로, 머지 리퀘스트 diff나 제목의 어디에든 이스케이프되지 않은 <, >, &가 있으면 스크립트로 작성한 모든 응답이 자리 표시자로 바뀝니다. 시드로 넣는 diff는 일반 ASCII로 유지합니다.
  2. 모의 응답은 <tool_calls> 요소의 텍스트만 읽으므로, 그 안의 JSON 페이로드에 있는 <, >, &는 XML 이스케이프해야 합니다.
  3. 플로의 각 단계는 자체 모델 인스턴스를 만들므로, 스크립트는 모델을 호출하는 플로의 모든 단계에서 처음부터 다시 재생됩니다. 특정 단계의 도구 집합에 없는 도구 호출은 해당 단계를 실패시키지만, 플로는 그래도 다음 단계로 진행합니다.

Gitlab::Duo::CodeReview::Modes::Dap은 루트 네임스페이스에 :code_review_flow_dap_routing에 대한 동의가 기록되어 있지 않으면 Duo Enterprise 좌석을 가진 사용자에 대한 Duo Agent Platform 라우팅을 거부합니다. 이 동의가 없으면 리뷰어 할당은 성공하지만 비에이전틱 리뷰 서비스로 대체되므로 플로가 전혀 시작되지 않습니다. 따라서 enable_on_group!은 code_review/v1이 활성화하는 플로일 때마다 create_code_review_flow_consent: true를 보냅니다. 네임스페이스에 Duo Enterprise 애드온이 없어 동의가 필요하지 않은 경우 API는 이 파라미터를 무시합니다.

GitLab 리포지터리의 다음 파일들이 이 테스트들을 구성합니다:

파일 설명
qa/qa/specs/features/ee/api/16_ai_powered/duo_foundational_flow_in_ci_spec.rb Duo Developer 플로 사양. 플로를 프로비저닝하고, 워크플로를 생성하며, 파이프라인 및 워크플로 상태를 검증합니다.
qa/qa/specs/features/ee/api/16_ai_powered/duo_code_review_flow_in_ci_spec.rb Code Review 플로 사양. 머지 리퀘스트와 agentic-mock 스크립트를 시드하고, 봇에 리뷰를 요청한 다음, 파이프라인, 플로 상태, 머지 리퀘스트에 게시된 리뷰를 검증합니다.
qa/qa/ee/flow/foundational_flow.rb 그룹, 프로젝트, Duo 좌석, 플로 소비자를 위한 프로비저닝 헬퍼와 봇에 코드 리뷰를 요청하는 헬퍼.
qa/qa/ee/resource/ai/duo_workflow.rb DuoWorkflow API 리소스, 리소스가 생성할 수 있는 플로 참조의 FOUNDATIONAL_FLOWS 레지스트리, GitLab이 직접 생성한 플로를 찾는 파인더.
qa/qa/ee/scenario/test/integration/duo_agent_platform.rb 사양들을 duo-agent-platform omnibus 작업으로 선택하는 시나리오.

foundational 플로는 foundational_flow.rb에서 네 가지 설정 단계가 완료된 후 실행됩니다:

  • assign_duo_seat!는 작업 사용자에게 Duo 좌석을 할당합니다.
  • enable_on_group!은 최상위 그룹에서 플로를 활성화하며, 이는 연쇄적으로 항목 소비자와 서비스 계정을 생성합니다.
  • enable_remote_flows_on_project!는 프로젝트에서 원격 플로를 활성화합니다.
  • wait_for_flow_consumer!는 소비자, 해당 활성 서비스 계정, 서비스 계정 프로젝트 멤버십이 모두 확인될 때까지 대기합니다. 2단계의 연쇄 작업은 콜드 인스턴스에서 지연될 수 있으므로, 이 헬퍼는 프로비저닝이 안정될 때까지 플로를 다시 활성화합니다.

다른 foundational 플로를 추가하려면:

  • 사양에서 플로 참조를 프로비저닝 헬퍼에 전달합니다.
  • 플로가 네임스페이스 동의나 특정 애드온에 따라 제한된다면 enable_on_group!을 확장합니다.
  • 목표를 항상 사용할 수 있는 것은 아니므로, 플로의 프롬프트가 모의 지시문을 어디에서 받는지 확인합니다.
  • 사양이 POST /ai/duo_workflows/workflows로 플로를 생성한다면 qa/qa/ee/resource/ai/duo_workflow.rb의 FOUNDATIONAL_FLOWS 레지스트리에 플로 참조를 등록하되, 플로의 목표가 고정된 경우에만 default_goal을 지정합니다. Code Review처럼 목표가 리소스를 지칭하는 플로는 사양이 goal을 제공해야 하며, 플로가 브랜치를 체크아웃한다면 source_branch도 제공해야 합니다. GitLab이 직접 트리거하는 플로는 대신 DuoWorkflow.find_latest_in_project로 찾으며 레지스트리 항목이 필요하지 않습니다.

사용자 정의 카탈로그 플로는 foundational 플로 목록을 사용하지 않으므로, enable_on_group!을 호출하는 대신 카탈로그 항목과 해당 소비자를 직접 생성해야 합니다.

탐색적 테스트#

예상치 못한 워크플로와 UX 문제 외의 버그를 발견하기 위해 중요한 마일스톤 이전에 탐색적 테스트를 수행합니다. 이는 AI 기능이 실험, 베타, GA 단계를 거치면서 특히 중요합니다.

독식#

독식은 모든 것에 적용됩니다. 이는 빠르게 변화하는 분야의 특성을 고려할 때 AI 기능에 특히 중요합니다. 자세한 내용은 독식 프로세스를 참조합니다.

AI 기능 테스트

GitLab v19.5
원문 보기

요약

이 문서는 GitLab 표준 테스트 가이드라인을 보완하는 AI 관련 테스트 고려사항을 강조합니다. AI 기반 기능은 AI Gateway 및 IDE 확장 프로그램과 같이 GitLab 모노리스 외부의 시스템 구성 요소에 의존합니다.

이 문서는 GitLab 표준 테스트 가이드라인을 보완하는 AI 관련 테스트 고려사항을 강조합니다. 제3자 제공자의 비결정론적 응답과 같이 AI 기능이 테스트에 가져오는 과제에 초점을 맞춥니다. 각 테스트 수준에 대한 예시가 포함됩니다.

AI 기반 기능은 AI Gateway 및 IDE 확장 프로그램과 같이 GitLab 모노리스 외부의 시스템 구성 요소에 의존합니다. 이러한 가이드라인 외에도 각 구성 요소 프로젝트에 문서화된 테스트 가이드라인을 참조합니다.

단위 테스트#

표준 단위 테스트 가이드라인을 따르십시오. AI 기능의 경우 빠르고 신뢰할 수 있는 테스트를 보장하기 위해 항상 제3자 AI 제공자 호출을 모킹합니다.

단위 테스트 예시#

통합 테스트#

AI 제공자에 대한 요청 구성 및 응답 처리를 확인하려면 통합 테스트를 사용합니다. 다양한 응답, 오류 및 상태 코드를 처리하는 예측 가능하고 빠른 테스트를 보장하기 위해 AI 제공자 응답을 모킹합니다.

통합 테스트 예시#

프론트엔드 기능 테스트#

최종 사용자 관점에서 AI 기능을 검증하려면 프론트엔드 기능 테스트를 사용합니다. 속도와 안정성을 유지하기 위해 AI 제공자를 모킹합니다. 고위험 시나리오에 대한 선택적 부정 경로 테스트와 함께 행복한 경로에 집중합니다.

프론트엔드 기능 테스트 예시#

핵심 기능 페이지의 DAP 기능 테스트#

기능 페이지에 DAP 구성 요소를 기본적으로 로드하려면 기능 사양에 공유 컨텍스트 include_context 'with duo features enabled and agentic chat available for group on SaaS'를 포함합니다.

Duo 에이전틱 채팅 기능 사양#

에이전틱 채팅 기능 사양의 커버리지는 ee/spec/features/duo_chat/agentic_chat_smoke_spec.rb에 통합되어 있습니다. 에이전틱 채팅을 테스트하기 위해 새 기능 사양을 추가하기보다 ee/spec/frontend/integration/ai_duo_panel/duo_agentic_chat/의 MSW 통합 스위트를 사용할 것을 강력히 권장합니다.

에이전틱 채팅과 다른 기능 간의 상호작용을 테스트하려는 경우에 기능 사양을 구현합니다. 예를 들어 agentic_chat_smoke_spec.rb 테스트 스위트는 작업 항목, 파이프라인, 머지 리퀘스트 페이지의 Call-to-Action 버튼으로 에이전틱 채팅을 여는 동작을 검증합니다.

AI Gateway에서 변경 시 DAP 기능 테스트 실행#

이 기능 테스트는 AI Gateway 리포지터리에 변경 사항을 적용할 때도 실행되어 MR이 DAP 기능을 실수로 중단하지 않는지 확인합니다. 예를 들어:

  1. 개발자가 AI Gateway 프로젝트에서 MR을 엽니다.
  2. MR에 대한 파이프라인이 실행되며, 이는 aigw/test-branch 테스트 브랜치에 대해 GitLab 프로젝트에서 다운스트림 파이프라인을 트리거합니다. 이 브랜치는 마스터와 동일한 SHA를 가리킵니다.
  3. 파이프라인이 실패하면 개발자는 제안된 변경 사항이 실수로 회귀를 도입하지 않는지 조사해야 합니다.
Note

aigw/test-branch 브랜치는 AIGW 및 DWS 관리자가 GitLab 프로젝트에서 다운스트림 파이프라인을 트리거할 수 있도록 기본적으로 보호되지 않습니다.

DWS/AIGW 변경 사항으로 기능 사양 로컬 실행#

  1. gdk start를 실행하여 DWS를 포함한 서비스를 시작합니다.
  2. <gdk-root>/gitlab에서 터미널을 열고 다음 옵션 중 하나를 사용합니다:
    • export TEST_AI_GATEWAY_REPO_REF=<your-remote-feature-branch>를 실행하고 <gitlab-rails-root>/tmp/tests/gitlab-ai-gateway/ 캐시 디렉터리를 삭제하거나,
    • export TEST_DUO_WORKFLOW_SERVICE_ENABLED="false" && export TEST_DUO_WORKFLOW_SERVICE_PORT=<your-local-dws-port>를 실행합니다. 이를 통해 기능 테스트가 로컬 DWS 인스턴스에 요청할 수 있습니다. 로컬 DWS에 다음 구성이 설정되고 실행 중인지 확인합니다:
      • AIGW_MOCK_MODEL_RESPONSES를 true로 설정
      • AIGW_USE_AGENTIC_MOCK을 true로 설정
  3. 기능 사양을 실행합니다. 예를 들어 bundle exec rspec ee/spec/features/duo_chat/agentic_chat_smoke_spec.rb를 실행합니다.

테스트 케이스의 로그 확인#

DAP는 여러 서비스와 API 호출로 구성됩니다. 테스트 케이스 실패를 디버깅하려면 근본 원인을 파악하기 위해 서비스 로그를 검사해야 할 수 있습니다. 다음 몇 가지 포인터가 있습니다:

  • GitLab-Rails REST API ... log/api_json.log

  • GitLab-Rails GraphQL API ... log/graphql_json.log

  • GitLab-Workhorse ... log/workhorse-test.log

  • DWS ... log/duo-workflow-service.log. CI는 이 파일을 작업 아티팩트로 수집하며, :duo_workflow_service 태그가 붙은 예시가 실패하면 마지막 60줄이 RSpec 출력에 자동으로 출력됩니다.

  • JS 콘솔 로그 출력을 사용하여 VueJS 앱 상태를 검사할 수도 있습니다:

    it 'runs a test' do
      ...
    
      # 브라우저 로그를 출력합니다. JavaScript의 console.log()와 결합하십시오.
      browser_logs.each do |log|
        puts "#{log.level}: #{log.message}"
      end
    
      ...
    end
    

엔드투엔드 테스트#

실제 제공자 응답으로 AI 기능이 작동하는지 확인하기 위해 엔드투엔드 테스트를 드물게 사용합니다. 주요 고려사항:

  • 느린 실행과 잠재적인 제공자 중단으로 인해 테스트를 최소화합니다.
  • 테스트 설계에서 비결정론적 AI 응답을 고려합니다. 예를 들어, AI 생성 콘텐츠가 아닌 챗봇 이름과 같이 제어 가능한 요소에 대한 결정론적 검증을 사용합니다.

E2E 테스트 예시#

라이브 환경 테스트#

  • GitLab.com: 스테이징 및 프로덕션 환경에서 최소한의 E2E 테스트를 지속적으로 실행합니다. 예를 들어 코드 제안 스모크 테스트.
  • GitLab Self-Managed: gitlab-qa 오케스트레이터를 AI Gateway 시나리오와 함께 사용하여 GitLab Self-Managed 인스턴스에서 AI 기능을 테스트합니다.

Duo Agent Platform foundational 플로#

Duo Agent Platform foundational-flow 스모크 테스트는 실제 CI 파이프라인을 통해 플로를 구동하는 오케스트레이션된 엔드투엔드 테스트입니다. gitlab-qa 오케스트레이터는 두 테스트를 e2e:test-on-omnibus-ee 하위 파이프라인의 duo-agent-platform 작업으로 실행합니다.

developer/v1 테스트는 start_workflow: true와 함께 POST /ai/duo_workflows/workflows를 통해 워크플로를 생성한 다음, duo_workflow 소스 파이프라인이 성공하고 워크플로가 finished에 도달하는지 검증합니다. code_review/v1 테스트는 머지 리퀘스트를 생성한 다음, 제품에서 리뷰를 요청하는 방식대로 GitLabDuo 리뷰 봇을 리뷰어로 할당합니다. 그런 다음 duo_workflow 소스 파이프라인이 성공하고, 플로가 finished에 도달하며, 리뷰 봇이 머지 리퀘스트에 리뷰 요약을 게시하는지 검증합니다.

이 테스트들은 두 개의 리포지터리에 걸쳐 있습니다. GitLab 리포지터리는 사양과 플로 프로비저닝 헬퍼를 보유합니다. gitlab-qa 오케스트레이터는 Duo Workflow Service를 부팅하고 GitLab 인스턴스를 해당 서비스로 라우팅하는 인프라를 보유합니다:

  • Component::DuoWorkflowService는 AI Gateway와 동일한 model-gateway 이미지에서 gRPC 및 agentic-mock 모드로 전환된 Duo Workflow Service를 부팅하고, 종료 시 컨테이너 로그를 작업 아티팩트에 캡처합니다.
  • Test::Integration::AiGatewayBase는 Duo Workflow Service를 시나리오에 연결하고 GITLAB_DUO_WORKFLOW_SERVICE_URL 및 GITLAB_DUO_WORKFLOW_SECURE 값을 omnibus Rails 환경에 전달합니다.
  • Test::Integration::DuoAgentPlatform은 AI Gateway 시나리오의 하위 클래스인 전용 시나리오이므로, 플로가 자체 duo-agent-platform omnibus 작업으로 실행되고 Duo Workflow Service 컨테이너는 ai-gateway 작업에서 제외됩니다.

agentic-mock 모드는 실제 모델을 호출하는 대신 지시문에 따라 결정론적 응답을 반환하며, 이는 Duo Chat 및 코드 제안 테스트가 AI Gateway에 사용하는 방식과 동일합니다. 이 지시문을 어디에 넣는지는 플로에 따라 다릅니다. developer/v1 목표는 자유 형식이므로, 이 테스트는 플로 목표에 지시문을 넣습니다. code_review/v1 목표는 머지 리퀘스트 IID 또는 머지 리퀘스트 URL이어야 검증을 통과하며, 그 외의 값은 400을 반환합니다. Code Review 테스트는 대신 지시문을 프로젝트 기본 브랜치에 .gitlab/duo/mr-review-instructions.yaml로 커밋한 사용자 지정 지침에 넣습니다. 이 필드가 플로가 이스케이프 없이 모델 프롬프트로 복사하는 유일한 필드이기 때문입니다.

이스케이프를 잘못 처리하면 모의 응답이 아무 알림 없이 자리 표시자 텍스트를 반환하므로, 다음 규칙에 유의합니다:

  1. 모의 응답은 프롬프트 전체를 XML로 파싱하므로, 머지 리퀘스트 diff나 제목의 어디에든 이스케이프되지 않은 <, >, &가 있으면 스크립트로 작성한 모든 응답이 자리 표시자로 바뀝니다. 시드로 넣는 diff는 일반 ASCII로 유지합니다.
  2. 모의 응답은 <tool_calls> 요소의 텍스트만 읽으므로, 그 안의 JSON 페이로드에 있는 <, >, &는 XML 이스케이프해야 합니다.
  3. 플로의 각 단계는 자체 모델 인스턴스를 만들므로, 스크립트는 모델을 호출하는 플로의 모든 단계에서 처음부터 다시 재생됩니다. 특정 단계의 도구 집합에 없는 도구 호출은 해당 단계를 실패시키지만, 플로는 그래도 다음 단계로 진행합니다.

Gitlab::Duo::CodeReview::Modes::Dap은 루트 네임스페이스에 :code_review_flow_dap_routing에 대한 동의가 기록되어 있지 않으면 Duo Enterprise 좌석을 가진 사용자에 대한 Duo Agent Platform 라우팅을 거부합니다. 이 동의가 없으면 리뷰어 할당은 성공하지만 비에이전틱 리뷰 서비스로 대체되므로 플로가 전혀 시작되지 않습니다. 따라서 enable_on_group!은 code_review/v1이 활성화하는 플로일 때마다 create_code_review_flow_consent: true를 보냅니다. 네임스페이스에 Duo Enterprise 애드온이 없어 동의가 필요하지 않은 경우 API는 이 파라미터를 무시합니다.

GitLab 리포지터리의 다음 파일들이 이 테스트들을 구성합니다:

파일 설명
qa/qa/specs/features/ee/api/16_ai_powered/duo_foundational_flow_in_ci_spec.rb Duo Developer 플로 사양. 플로를 프로비저닝하고, 워크플로를 생성하며, 파이프라인 및 워크플로 상태를 검증합니다.
qa/qa/specs/features/ee/api/16_ai_powered/duo_code_review_flow_in_ci_spec.rb Code Review 플로 사양. 머지 리퀘스트와 agentic-mock 스크립트를 시드하고, 봇에 리뷰를 요청한 다음, 파이프라인, 플로 상태, 머지 리퀘스트에 게시된 리뷰를 검증합니다.
qa/qa/ee/flow/foundational_flow.rb 그룹, 프로젝트, Duo 좌석, 플로 소비자를 위한 프로비저닝 헬퍼와 봇에 코드 리뷰를 요청하는 헬퍼.
qa/qa/ee/resource/ai/duo_workflow.rb DuoWorkflow API 리소스, 리소스가 생성할 수 있는 플로 참조의 FOUNDATIONAL_FLOWS 레지스트리, GitLab이 직접 생성한 플로를 찾는 파인더.
qa/qa/ee/scenario/test/integration/duo_agent_platform.rb 사양들을 duo-agent-platform omnibus 작업으로 선택하는 시나리오.

foundational 플로는 foundational_flow.rb에서 네 가지 설정 단계가 완료된 후 실행됩니다:

  • assign_duo_seat!는 작업 사용자에게 Duo 좌석을 할당합니다.
  • enable_on_group!은 최상위 그룹에서 플로를 활성화하며, 이는 연쇄적으로 항목 소비자와 서비스 계정을 생성합니다.
  • enable_remote_flows_on_project!는 프로젝트에서 원격 플로를 활성화합니다.
  • wait_for_flow_consumer!는 소비자, 해당 활성 서비스 계정, 서비스 계정 프로젝트 멤버십이 모두 확인될 때까지 대기합니다. 2단계의 연쇄 작업은 콜드 인스턴스에서 지연될 수 있으므로, 이 헬퍼는 프로비저닝이 안정될 때까지 플로를 다시 활성화합니다.

다른 foundational 플로를 추가하려면:

  • 사양에서 플로 참조를 프로비저닝 헬퍼에 전달합니다.
  • 플로가 네임스페이스 동의나 특정 애드온에 따라 제한된다면 enable_on_group!을 확장합니다.
  • 목표를 항상 사용할 수 있는 것은 아니므로, 플로의 프롬프트가 모의 지시문을 어디에서 받는지 확인합니다.
  • 사양이 POST /ai/duo_workflows/workflows로 플로를 생성한다면 qa/qa/ee/resource/ai/duo_workflow.rb의 FOUNDATIONAL_FLOWS 레지스트리에 플로 참조를 등록하되, 플로의 목표가 고정된 경우에만 default_goal을 지정합니다. Code Review처럼 목표가 리소스를 지칭하는 플로는 사양이 goal을 제공해야 하며, 플로가 브랜치를 체크아웃한다면 source_branch도 제공해야 합니다. GitLab이 직접 트리거하는 플로는 대신 DuoWorkflow.find_latest_in_project로 찾으며 레지스트리 항목이 필요하지 않습니다.

사용자 정의 카탈로그 플로는 foundational 플로 목록을 사용하지 않으므로, enable_on_group!을 호출하는 대신 카탈로그 항목과 해당 소비자를 직접 생성해야 합니다.

탐색적 테스트#

예상치 못한 워크플로와 UX 문제 외의 버그를 발견하기 위해 중요한 마일스톤 이전에 탐색적 테스트를 수행합니다. 이는 AI 기능이 실험, 베타, GA 단계를 거치면서 특히 중요합니다.

독식#

독식은 모든 것에 적용됩니다. 이는 빠르게 변화하는 분야의 특성을 고려할 때 AI 기능에 특히 중요합니다. 자세한 내용은 독식 프로세스를 참조합니다.