Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

SebastianOsinski/GRDBSnapshotTesting

Repository files navigation

This project has been superseded by the official GRDBSnapshotTesting library

GRDBSnapshotTesting

Swift 5.2 Pod version License

SnapshotTesting plug-in for testing GRDB database migrations.

It allows you to easily test if your database schema and data are migrated correctly.

Features

GRDBSnapshotTesting creates snapshot files which represent your database schema and data.

Snapshot files contain:

  • table definitions
  • index definitions (if any exists)
  • trigger definitions (if any exists)
  • view definitions (if any exists)
  • all data from all tables

Example snapshot file:

======== TABLES ========

CREATE TABLE "author" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT
  "name" TEXT NOT NULL
  "country" TEXT NOT NULL
  "lastUpdate" DATETIME
)

CREATE TABLE "book" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT
  "title" TEXT NOT NULL
  "authorId" INTEGER NOT NULL REFERENCES "author"("id") ON DELETE CASCADE
  "lastUpdate" DATETIME
)

======== DATA ========

## author
(1, "J.K. Rowling", "UK", NULL)
(2, "J.R.R. Tolkien", "UK", NULL)

## book
(1, "Harry Potter and the Philosopher\'s Stone", 1, NULL)
(2, "Harry Potter and the Chamber of Secrets", 1, NULL)
(3, "Harry Potter and the Prisoner of Azkaban", 1, NULL)
(4, "The Hobbit", 2, NULL)
(5, "The Fellowship of the Ring", 2, NULL)

Usage

import XCTest
import SnapshotTesting
import GRDB
import GRDBSnapshotTesting

class DatabaseMigrationTests: XCTestCase {
  func testInitialMigration() throws {
    let db = DatabaseQueue()
    
    var migrator = DatabaseMigrator()
    migrator.registerMigration("v1", migrate: Migrations.firstMigration)
  
    try migrator.migrate(db)
    
    assertSnapshot(matching: db, as: .dbDump)
  }
}

On first run, above test will create reference snapshot file with your database schema and contents.

On subsequent runs it will check if just created snapshot matches prerecorded reference.

GRDBSnapshotTesting also contains some extensions for GRDB which allow testing your migrations on prerecorded database files without overwriting them:

class DatabaseMigrationTests: XCTestCase {
  func testSecondMigration() throws {
    // V1DatabaseWithData.sqlite is added to the testing target
    let path = Bundle(for: Self.self).path(forResource: "V1DatabaseWithData", ofType: "sqlite")!

    let db = DatabaseQueue.inMemoryDatabase(fromPath: path)
    
    var migrator = DatabaseMigrator()
    migrator.registerMigration("v2", migrate: Migrations.secondMigration)
  
    try migrator.migrate(db)
    
    assertSnapshot(matching: db, as: .dbDump)
  }
}

DatabaseQueue.inMemoryDatabase(fromPath:) creates in-memory database with the same schema and data as the database file at given path.

That way you can create multiple database files with edge-case data and test your migrations thoroughly.

Installation

CocoaPods

Add the pod to your testing target in Podfile:

target 'MyAppTests' do
  pod 'GRDBSnapshotTesting', '~> 0.2'
end

Swift Package Manager

Add the package to your testing target in Package.swift:

 let package = Package(
     dependencies: [
+        .package(url: "https://github.com/SebastianOsinski/GRDBSnapshotTesting.git", ...)
     ],
     targets: [
         .testTarget(
             dependencies: [
+                "GRDBSnapshotTesting"
             ])
     ]
 )