InfoGrab DocsInfoGrab Docs

테스트 가이드라인

요약

이 페이지는 GitLab의 인가 변경에 대한 정책 사양을 작성하는 방법에 대한 지침을 제공합니다. 각 권한에는 자체 describe 블록이 있어야 합니다. where 테이블 구문을 사용하여 각 역할을 명시적으로 테스트하십시오.

이 페이지는 GitLab의 인가 변경에 대한 정책 사양을 작성하는 방법에 대한 지침을 제공합니다.

  • 단위 테스트는 spec/policies/ee/spec/policies/에 있습니다.

구조#

권한당 하나의 describe 블록#

각 권한에는 자체 describe 블록이 있어야 합니다. 여러 권한을 단일 블록으로 그룹화하지 마십시오 — 이렇게 하면 실패한 테스트가 어떤 권한과 관련이 있는지 식별하기 어려워집니다.

# bad - multiple permissions in one block
describe 'read and update issue' do
  it { is_expected.to be_allowed(:read_issue, :update_issue) }
end

# good - one block per permission
describe 'read_issue' do
  # ...
end

describe 'update_issue' do
  # ...
end

역할 기반 확인에 테이블 구문 사용#

where 테이블 구문을 사용하여 각 역할을 명시적으로 테스트하십시오. 이렇게 하면 어떤 역할이 액세스 권한을 가지고 어떤 역할이 없는지 즉시 명확해지고, 반복적인 it 블록을 피할 수 있습니다.

describe 'read_vulnerability' do
  where(:current_user, :allowed) do
    ref(:guest)      | false
    ref(:planner)    | false
    ref(:reporter)   | false
    ref(:developer)  | true
    ref(:maintainer) | true
    ref(:auditor)    | false
    ref(:owner)      | true
    ref(:admin)      | true
  end
end

항상 테이블에 모든 역할을 포함하십시오 — 허용되지 않을 것으로 예상되는 역할을 생략하지 마십시오. 명시적인 false 값은 true 값만큼 중요한데, 의도된 액세스 경계를 문서화하기 때문입니다.

모든 블록에서 주제 지정#

let_it_be를 사용하여 각 describe 블록 내에서 주제를 명시적으로 정의하십시오. 상위 범위에서 정의된 주제에 의존하지 마십시오 — 이렇게 하면 우발적인 테스트 오염을 방지하고 각 블록을 자체 포함으로 만듭니다.

# bad - subject defined at top level, shared across all blocks
let_it_be(:project) { create(:project) }

describe 'read_vulnerability' do
  # implicitly uses the project above
end

# good - subject defined inside each block
describe 'read_vulnerability' do
  let_it_be(:project) { private_project }

  where(:current_user, :allowed) do
    # ...
  end
end

일반적인 project보다는 테스트 중인 가시성이나 상태를 반영하는 설명적인 이름의 프로젝트 픽스처(private_project, public_project, archived_project)를 사용하십시오.

전체 예시#

RSpec.describe ProjectPolicy do
  describe 'write_example_feature' do
    let_it_be(:project) { private_project }

    before do
      stub_feature_flags(example_feature: true)
      stub_licensed_features(example_feature: true)
    end

    where(:current_user, :allowed) do
      ref(:owner)      | true
      ref(:reporter)   | true
      ref(:planner)    | false
      ref(:guest)      | false
      ref(:non_member) | false
    end

    with_them do
      if params[:allowed]
        it { expect_allowed(:write_example_feature) }
      else
        it { expect_disallowed(:write_example_feature) }
      end
    end

    context 'with admin mode enabled', :enable_admin_mode do
      let(:current_user) { admin }

      it { expect_allowed(:write_example_feature) }
    end

    context 'without admin mode enabled' do
      let(:current_user) { admin }

      it { expect_disallowed(:write_example_feature) }
    end

    context 'when example_feature feature flag is disabled' do
      before do
        stub_feature_flags(example_feature: false)
      end

      it { expect_disallowed(:write_example_feature) }
    end

    context 'when example_feature licensed feature is disabled' do
      before do
        stub_licensed_features(example_feature: false)
      end

      it { expect_disallowed(:write_example_feature) }
    end
  end
end

테스트 가이드라인

GitLab v19.2
원문 보기
요약

이 페이지는 GitLab의 인가 변경에 대한 정책 사양을 작성하는 방법에 대한 지침을 제공합니다. 각 권한에는 자체 describe 블록이 있어야 합니다. where 테이블 구문을 사용하여 각 역할을 명시적으로 테스트하십시오.

이 페이지는 GitLab의 인가 변경에 대한 정책 사양을 작성하는 방법에 대한 지침을 제공합니다.

  • 단위 테스트는 spec/policies/ee/spec/policies/에 있습니다.

구조#

권한당 하나의 describe 블록#

각 권한에는 자체 describe 블록이 있어야 합니다. 여러 권한을 단일 블록으로 그룹화하지 마십시오 — 이렇게 하면 실패한 테스트가 어떤 권한과 관련이 있는지 식별하기 어려워집니다.

# bad - multiple permissions in one block
describe 'read and update issue' do
  it { is_expected.to be_allowed(:read_issue, :update_issue) }
end

# good - one block per permission
describe 'read_issue' do
  # ...
end

describe 'update_issue' do
  # ...
end

역할 기반 확인에 테이블 구문 사용#

where 테이블 구문을 사용하여 각 역할을 명시적으로 테스트하십시오. 이렇게 하면 어떤 역할이 액세스 권한을 가지고 어떤 역할이 없는지 즉시 명확해지고, 반복적인 it 블록을 피할 수 있습니다.

describe 'read_vulnerability' do
  where(:current_user, :allowed) do
    ref(:guest)      | false
    ref(:planner)    | false
    ref(:reporter)   | false
    ref(:developer)  | true
    ref(:maintainer) | true
    ref(:auditor)    | false
    ref(:owner)      | true
    ref(:admin)      | true
  end
end

항상 테이블에 모든 역할을 포함하십시오 — 허용되지 않을 것으로 예상되는 역할을 생략하지 마십시오. 명시적인 false 값은 true 값만큼 중요한데, 의도된 액세스 경계를 문서화하기 때문입니다.

모든 블록에서 주제 지정#

let_it_be를 사용하여 각 describe 블록 내에서 주제를 명시적으로 정의하십시오. 상위 범위에서 정의된 주제에 의존하지 마십시오 — 이렇게 하면 우발적인 테스트 오염을 방지하고 각 블록을 자체 포함으로 만듭니다.

# bad - subject defined at top level, shared across all blocks
let_it_be(:project) { create(:project) }

describe 'read_vulnerability' do
  # implicitly uses the project above
end

# good - subject defined inside each block
describe 'read_vulnerability' do
  let_it_be(:project) { private_project }

  where(:current_user, :allowed) do
    # ...
  end
end

일반적인 project보다는 테스트 중인 가시성이나 상태를 반영하는 설명적인 이름의 프로젝트 픽스처(private_project, public_project, archived_project)를 사용하십시오.

전체 예시#

RSpec.describe ProjectPolicy do
  describe 'write_example_feature' do
    let_it_be(:project) { private_project }

    before do
      stub_feature_flags(example_feature: true)
      stub_licensed_features(example_feature: true)
    end

    where(:current_user, :allowed) do
      ref(:owner)      | true
      ref(:reporter)   | true
      ref(:planner)    | false
      ref(:guest)      | false
      ref(:non_member) | false
    end

    with_them do
      if params[:allowed]
        it { expect_allowed(:write_example_feature) }
      else
        it { expect_disallowed(:write_example_feature) }
      end
    end

    context 'with admin mode enabled', :enable_admin_mode do
      let(:current_user) { admin }

      it { expect_allowed(:write_example_feature) }
    end

    context 'without admin mode enabled' do
      let(:current_user) { admin }

      it { expect_disallowed(:write_example_feature) }
    end

    context 'when example_feature feature flag is disabled' do
      before do
        stub_feature_flags(example_feature: false)
      end

      it { expect_disallowed(:write_example_feature) }
    end

    context 'when example_feature licensed feature is disabled' do
      before do
        stub_licensed_features(example_feature: false)
      end

      it { expect_disallowed(:write_example_feature) }
    end
  end
end