콘솔로 이동

단위 테스트 빌드

Firebase 에뮬레이터를 사용하면 앱의 동작을 완전하게 검증하고 Firebase 보안 규칙 구성을 확인하기가 훨씬 쉬워집니다. Firebase 에뮬레이터를 사용하여 로컬 환경에서 단위 테스트를 실행하고 자동화하세요. 이 문서에서 설명하는 방법은 규칙을 검증하는 앱에서 단위 테스트를 빌드하고 자동화는 데 도움이 됩니다.

아직 설치하지 않았다면 Firebase 에뮬레이터를 설치하세요.

에뮬레이터 실행 전 주의 사항

에뮬레이터 사용을 시작하려면 다음 사항에 주의하세요.

  • 현재 에뮬레이터를 지원하는 유일한 SDK는 Node.js SDK입니다. Google에서 제공되는 @firebase/testing 모듈을 사용하면 보다 쉽게 에뮬레이터를 활용할 수 있습니다.
  • 에뮬레이터는 선택적으로 사용할 수 있는 --rules CLI 플래그를 지원합니다. 규칙이 포함된 로컬 파일 이름을 요청한 후 이 규칙을 모든 프로젝트에 적용합니다. 로컬 파일 경로를 제공하지 않거나 loadFirestoreRules 또는 loadDatabaseRules 메소드를 사용하는 경우 에뮬레이터는 공개 규칙에 따라 모든 프로젝트를 취급합니다.

에뮬레이터와 프로덕션의 차이점

  • 데이터베이스 인스턴스를 명시적으로 만들 필요가 없습니다. 에뮬레이터가 액세스되는 데이터베이스 인스턴스를 자동으로 만듭니다.
  • 각각의 새 데이터베이스가 폐쇄된 규칙으로 시작되므로 관리자가 아닌 사용자는 읽거나 쓸 수 없습니다.
  • 에뮬레이트된 각 데이터베이스에는 Spark 요금제 한도 및 할당량(특히 각 인스턴스를 동시 연결 100개로 제한)이 적용됩니다.
  • 모든 데이터베이스가 "owner" 문자열을 관리자 인증 토큰으로 허용합니다.
  • 에뮬레이터는 현재 다른 Firebase 제품과 함께 작동하지 않습니다. 특히 일반적인 Firebase 인증 흐름이 작동하지 않습니다. 대신 auth 필드를 적용하는 테스트 모듈에서 initializeTestApp() 메소드를 사용할 수 있습니다. 이 메소드로 만든 Firebase 객체는 입력한 항목으로 인증된 것처럼 작동합니다. 단, null을 전달하면 인증되지 않은 사용자처럼 작동합니다. 예를 들어 auth != null 규칙은 실패합니다.

로컬 테스트 실행

@firebase/testing 모듈을 사용하여 로컬로 실행되는 에뮬레이터를 활용하세요. 시간 초과나 ECONNREFUSED 오류가 발생하면 에뮬레이터가 실제로 실행 중인지 다시 확인하세요.

async/await 표기법을 사용하려면 최신 버전의 Node.js를 사용하는 것이 좋습니다. 테스트할 동작의 거의 대부분이 비동기 함수와 관련이 있으며 테스트 모듈은 프라미스 기반 코드로 작동하도록 설계되어 있습니다.

에뮬레이터 메소드

제품을 선택하여 에뮬레이터 모듈이 노출하는 메소드를 확인하세요.

Cloud Firestore

Cloud Firestore

initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp

이 메소드는 옵션에 지정된 프로젝트 ID 및 인증 변수에 따라 초기화된 Firebase 앱을 반환합니다. 테스트에 사용할 특정 사용자로 인증된 앱을 만들려면 이 메소드를 사용합니다.

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", email: "alice@example.com" }
});

initializeAdminApp({ projectId: string }) => FirebaseApp

이 메소드는 초기화된 관리자 Firebase 앱을 반환합니다. 이 앱은 읽기 및 쓰기를 수행할 때 보안 규칙을 우회합니다. 테스트용 상태를 설정할 관리자로 인증된 앱을 만들려면 이 메소드를 사용하세요.

firebase.initializeAdminApp({ projectId: "my-test-project" });
    

apps() => [FirebaseApp] 이 메소드는 현재 초기화된 테스트 및 관리자 앱을 모두 반환합니다. 테스트 중에 또는 테스트 후에 앱을 정리하려면 이 메소드를 사용하세요.

Promise.all(firebase.apps().map(app => app.delete()))

loadFirestoreRules({ projectId: string, rules: Object }) => Promise

이 메소드는 로컬에서 실행 중인 데이터베이스에 규칙을 전송합니다. 이때 규칙을 문자열로 지정하는 객체를 선택해야 합니다. 데이터베이스 규칙을 설정하려면 이 메소드를 사용하세요.

firebase.loadFirestoreRules({
  projectId: "my-test-project",
  rules: fs.readFileSync("/path/to/firestore.rules", "utf8")
});
    

assertFails(pr: Promise) => Promise

이 메소드는 입력이 성공하면 거부된 프라미스를 반환하고, 입력이 거부되면 성공한 프라미스를 반환합니다. 데이터베이스 읽기 또는 쓰기 실패를 알리는 어설션을 만들려면 이 메소드를 사용하세요.

firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
    

assertSucceeds(pr: Promise) => Promise

이 메소드는 입력이 성공하면 성공한 프라미스를 반환하고, 입력이 거부되면 거부된 프라미스를 반환합니다. 데이터베이스 읽기 또는 쓰기 성공을 알리는 어설션을 만들려면 이 메소드를 사용하세요.

firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
    

clearFirestoreData({ projectId: string }) => Promise

이 메소드는 로컬에서 실행되는 Firestore 인스턴스의 특정 프로젝트와 연결된 모든 데이터를 지웁니다. 테스트 후 삭제하려면 이 메소드를 사용하세요.

firebase.clearFirestoreData({
  projectId: "my-test-project"
});
   

실시간 데이터베이스

실시간 데이터베이스

initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp

테스트에 사용할 특정 사용자로 인증된 앱을 만들려면 이 메소드를 사용하세요.

옵션에 지정된 데이터베이스 이름 및 인증 변수 재정의에 해당하는 초기화된 Firebase 앱이 반환됩니다.

firebase.initializeTestApp({
  databaseName: "my-database",
  auth: { uid: "alice" }
});

initializeAdminApp({ databaseName: string }) => FirebaseApp

테스트용 상태를 설정할 관리자로 인증된 앱을 만들려면 이 메소드를 사용하세요.

옵션에 지정된 데이터베이스 이름에 해당하는 초기화된 관리자 Firebase 앱이 반환됩니다. 이 앱은 데이터베이스를 읽고 쓸 때 보안 규칙을 우회합니다.

firebase.initializeAdminApp({ databaseName: "my-database" });

loadDatabaseRules({ databaseName: string, rules: Object }) => Promise

데이터베이스 규칙을 설정하려면 이 메소드를 사용하세요.

로컬에서 실행 중인 데이터베이스에 규칙이 전송됩니다. 'databaseName'과 'rules'를 문자열로 지정하는 옵션 객체를 선택하세요.

firebase
      .loadDatabaseRules({
        databaseName: "my-database",
        rules: "{'rules': {'.read': false, '.write': false}}"
      });

apps() => [FirebaseApp]

현재 초기화된 모든 테스트 및 관리자 앱이 반환됩니다.

테스트 간에 또는 테스트 후에 앱을 정리하려면 이 메소드를 사용합니다. 활성 리스너가 포함된 초기화된 앱이 있으면 자바스크립트가 종료되지 않습니다.

 Promise.all(firebase.apps().map(app => app.delete()))

assertFails(pr: Promise) => Promise

입력이 성공하면 거부된 프라미스가 반환되고, 입력이 거부되면 성공한 프라미스가 반환됩니다.

데이터베이스 읽기 또는 쓰기가 실패했다고 알리는 어설션을 만들려면 이 메소드를 사용합니다.

firebase.assertFails(app.database().ref("secret").once("value"));

assertSucceeds(pr: Promise) => Promise

입력이 성공하면 성공한 프라미스가 반환되고, 입력이 거부되면 거부된 프라미스가 반환됩니다.

데이터베이스 읽기 또는 쓰기가 성공했다고 알리는 어설션을 만들려면 이 메소드를 사용합니다.

firebase.assertSucceeds(app.database().ref("public").once("value"));