Respawn – usuwanie danych z bazy

Wprowadzenie

W poprzednim wpisie pokazałem Ci, jak użyć Sql Server Snapshots do resetowania stanu bazy w automatycznych testach. Innym podejściem, które możemy wykorzystać podczas pracy, jest po prostu usuwanie z bazy danych, które zostały dodane podczas wykonywania testów. Tytułowa biblioteka Respawn umożliwia realizację czegoś takiego w bardzo prosty sposób, ale ma również niestety swoje wady. Zobacz, co umożliwia i gdzie może Ci się ona przydać.

Respawn

Respawn (https://github.com/jbogard/Respawn) jest prostą biblioteką, która ułatwia usuwanie danych. Jak podaje sam autor biblioteki, jest to inteligentne narzędzie do oczyszczania bazy danych do testów integracyjnych. „Inteligentne” oznacza tutaj, że biblioteka w pierwszej kolejności analizuje schemat bazy danych, aby na jej podstawie zdecydować o kolejności usuwania danych z bazy. Dzięki temu nie musimy na przykład zdejmować ograniczeń dla kluczy obcych w bazie, ponieważ biblioteka w pierwszej kolejności usunie rekordy zależne, a później rekord główny.

Już tutaj widać potencjalnie największy problem biblioteki, który może zadecydować, czy postanowisz jej użyć, czy nie. Jest nim to, że biblioteka usuwa wszystkie dane z tabel, które nas interesują. Jest to duża różnica w stosunku do migawek ze Sql Servera – tam wracaliśmy do określonego stanu bazy, gdzie w tabelach mogły znajdować się wcześniej przygotowane dane. W przypadku Respawn reset bazy oznacza po prostu usunięcie danych z tabel.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 20 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Respawn w akcji

Na potrzeby dzisiejszego wpisu przygotowałem prostą aplikację konsolową (https://github.com/danielplawgo/RespawnTests), w której znajduje się prosta struktura bazy z relacją jeden do wielu oraz wiele do wielu. Użyłem Entity Framework z podejściem Code First, a w aplikacji znajdują się następujące klasy modelu:

Klasa BaseModel zawiera podstawowe właściwości, które chce mieć w każdej klasie modelu. Klasa Category jest powiązana relacją jeden do wielu z klasą Book, a następnie klasa Book jest powiązana relacją wiele do wielu z klasą Person.

W przykładzie dodałem jeszcze prostą metodę SeedData, która wrzuca do bazy dane wygenerowane przez bibliotekę NBuilder. W późniejszym kroku dane te będą usuwane przez Respawn. Tutaj we wpisie nie będę już wklejał kodu tej metody, bo nie jest on istotny w kontekście omawiania biblioteki Respawn.

Samo użycie biblioteki Respawn jest dość proste i wygląda tak:

Na początku definiujemy instancję klasy Checkpoint, w której określamy konfigurację. W kodzie widać najczęściej używaną właściwość TablesToIgnore, w której określamy tabele, z których biblioteka nie usunie danych podczas resetu bazy. W moim przykładzie nie chcę, aby biblioteka usuwała dane z tabeli z migracjami Entity Framework.

Samo usunięcie danych odbywa się poprzez wywołanie metody Reset na obiekcie klasy Checkpoint i przekazaniu connection stringa do bazy w parametrze metody. Warto zauważyć, że metoda jest asynchroniczna (zwraca obiekt klasy Task), więc w tym przypadku dodałem jeszcze wywołanie metody Wait.

W efekcie wykonywania powyższego kodu Respawn wygenerowało i wykonało takiego sqla usuwającego dane z bazy:

Widać, że kolejność usuwania danych jest poprawna. W tym sensie, że najpierw usuwane są dane z tabeli PersonBooks, która jest elementem relacji wiele do wielu, a na samym końcu są usuwane dane z tabeli Categories, która nie zależy od innych tabel.

Natomiast pobranie metadanych o bazie tuż przed usunięciem danych wykonało takiego sqla:

Konfiguracja Respawn

Poza pokazanym wcześniej użyciem właściwości TablesToIgnore możemy ustawić w klasie Checkpoint jeszcze kilka innych właściwości:

  • TablesToInclude – ręczne określenie tabel, z których ma nastąpić usunięcie danych,
  • SchemasToInclude oraz SchemasToExclude – określamy usunięcie danych lub nie na podstawie schematu w bazie,
  • WithReseed – resetuje autonumerowanie dla kluczy w tabelach, dzięki czemu dodanie nowych rekordów do bazy po resecie spowoduje, że klucze będą ponownie generowane od wartości startowej (na ogół 1).

Myślę, że na ogół najsensowniejszą opcją jest skorzystanie z dwóch właściwości. W TablesToIgnore określamy tabele, z których nie chcemy usuwać danych (np. tabele z migracjami Entity Framework). Drugą właściwością jest WithReseed ustawione na true, aby dodawane rekordy do bazy miały zawsze ten sam klucz.

Przykład

Na githubie (https://github.com/danielplawgo/RespawnTests) już tradycyjnie znajdziesz przykład, którego użyłem do pracy nad tym wpisem. Po jego pobraniu należy w app.config ustawić connection stringa do testowej bazy danych.

Podsumowanie

Respawn jest ciekawą alternatywą dla Sql Server Snapshots w kwestii resetowania bazy do znanego stanu. Jak podaje sam autor (https://jimmybogard.com/respawn-vs-sql-server-snapshots/), użycie Respawn jest dużo bardziej efektywne (testy wykonują się szybciej) niż użycie migawek. Więc w sytuacji, gdy czyszczenie danych nie jest problemem w Twoich scenariuszach testowych, myślę, że Respawn jest ciekawą alternatywą.

Osobiście obecnie zostaję przy użyciu migawek. W swoich testach WebApi bardzo często zakładam, że w bazie na starcie znajdują się określone dane i użycie Respawna bardzo by mi utrudniło pisanie testów. Jednak próbuję pozmieniać kod samej biblioteki Respawn, który jest na githubie, aby bardziej selektywnie usuwać dane. Jak coś ciekawego mi z tego wyjdzie, to z chęcią się kiedyś podzielę tym na blogu.

4 thoughts on “Respawn – usuwanie danych z bazy

  • Pingback: dotnetomaniak.pl
  • A nie latwiej po prostu uruchomic test w transakcji (TestInitialize) i na koniec zrobic rollback (TestCleanup) ?
    Jakos nie za bardzo wyobrazam sobie ta biblioteke + duze bazy danych.

  • Dzięki za wpis. Całkiem niedawno w projekcie rozważaliśmy czego użyć do czyszczenia bazy SQL Server po skończonych automatycznych testach UI. Pierwszy wybór padł na snapshoty. Jednak szybko okazało się, że Azure SQL tego nie wspiera. Ostatecznie napisaliśmy skrypt SQL, który robi truncate na odpowiednich tabelach. Jednak na wspomnianą bibliotekę Respawn nie trafiliśmy, wiec dzieki za wpis – może przyda się w przyszłości 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *