2015-06-12 11 views
6

Poszukuję szybkiego sposobu czyszczenia danych tabel wykonujących testy integracji z EF.Wadą korzystania z transakcji jest pozbywanie się z testowaniem integracji struktury encji

Każdy wydaje się zawijać transakcję wokół swojej metody testowej i pozbywać się transakcji po teście.

W ten sposób dane nigdy nie zostaną zapisane w tabeli.

Rzeczy takie jak nowe automatyczne identyfikatory do wstawek wciąż działają, ale zadaję sobie, że ta metoda jest naprawdę niezawodna w porównaniu do transakcji .commit().

Czy są jakieś wady korzystania z tego podejścia, które nie wydają się być test prawdziwa integracja jako baza danych nie jest dotykany ...

Albo innymi słowy zapytał czy są jakieś błędne scenariusze, które nie pojawiają jako wyjątki używając transakcja bez commit()?

UPDATE

public abstract class IntegrationTestsBase 
    { 
     protected TransactionScope TransactionScope; 

     public abstract void TestSetup(); 
     protected void InitTestSetupOnTable(string tableName) 
     { 
      TransactionScope = new TransactionScope(); 

      using (var context = new TGBContext()) 
      { 
       var cmdCommand = string.Format("DBCC CHECKIDENT ({0}, RESEED, 1)", tableName); 
       context.Database.ExecuteSqlCommand(cmdCommand); 
       context.SaveChanges(); 
      } 
     } 

     [TestCleanup] 
     public void TestCleanup() 
     { 
      TransactionScope.Dispose(); 
     } 
    } 

[TestClass] 
public class MyTests : IntegrationTestsBase 
{ 
     [TestInitialize] 
     public override void TestSetup() 
     { 
      base.InitTestSetupOnTable("MyTableName");   
     } 
} 
+0

Jedyna różnica polega na tym, że nie testuje się współbieżności. Kiedy będziesz potrzebować (i będziesz potrzebować!), Zmienisz podejście rozpoczęcia/wycofania transakcji. Ponadto przywróć kopię zapasową i upuść bazę danych jest kilka linii kodów na początku/końcu testu. – bubi

+0

@bubi Przywracanie bazy danych jest szybsze niż context.datebase.Create()? – Elisabeth

+0

Jeśli możesz rozpocząć testy z pustą bazą danych, możesz również użyć Create(). Nie wiem, czy to jest szybciej zależy prawdopodobnie od liczby tabel/pól/relacji/DBMS ... Ponadto może być tak, że jakiś dostawca EF nie obsługuje Create(). W moim przypadku używam Microsoft Access, aby przetestować EF, a dostawca obsługuje migracje codefirst, ale nie obsługuje Create() – bubi

Odpowiedz

2

jako baza danych nie jest dotykany

pewnością to dotknął. Wszystko, co dzieje się w ramach transakcji, dzieje się w bazie danych. Wartości i sekwencje tożsamości (jeśli są) są inkrementowane, wyzwalają ogień, sprawdzane są więzy referencyjne itp. Jedyne, co się dzieje, dzieje się w izolacji, a na końcu wszystko (z wyjątkiem przyrostowych tożsamości i sekwencji) zostaje odwrócone.

Czy są jakieś wady stosowania tego podejścia?

Niezupełnie. Używam tego podejścia szeroko w moim własnym kodzie i ma wielkie zalety. Zielone testy dają bardzo wysoki poziom pewności. Nigdy nie będę czuł się bezpiecznie z "prawdziwym" testem jednostkowym przy użyciu wyśmianych kontekstów i DbSet (chociaż używam testu jednostkowego dla wielu innych rzeczy).

Ale są pewne ograniczenia, o których powinieneś wiedzieć.

  • Wartości tożsamości/sekwencji nie są deterministyczne, więc nie można ich potwierdzić. Jak już powiedziałem, wartości te nie zostaną wycofane. Jeśli naprawdę potrzebujesz zapewnień w tym obszarze, możesz zresetować tożsamości/sekwencje po każdym teście.
  • Nie możemy nigdy przetestować problemów związanych z współbieżnością dzięki temu podejściu.
  • Nie można otworzyć połączenia z inną bazą danych lub nawet z tą samą bazą danych, jeśli jej ciąg połączenia różni się najdrobniejszymi szczegółami (np. Inna nazwa aplikacji lub inne ustawienie MARS), bez wywoływania kodu DTC. W aplikacji kod byłby możliwy, ponieważ te różne połączenia nie byłyby opakowane w TransactionScope. Być może nie wszystkie ścieżki aplikacji można łatwo przetestować w ten sposób.
  • Programiści powinni używać własnej kopii testowej bazy danych. Jeśli wielu programistów (i być może serwer kompilacji) uruchamia testy w tej samej bazie danych, mogą się one wzajemnie zakleszczać.
+0

Potem poczułem tożsamość, a nie zresetować pułapki. Moje testy sprawdzały się same, ale gdy je uruchomiłem, otrzymałem błędy współbieżności z powodu niewłaściwego identyfikatora. Muszę kazać każdemu testowi zacząć od nowa. W przeciwnym razie moje wielokrotne testy miałyby założenia, których nikt nie może odgadnąć, to byłaby zła zależność. Tak więc wielu użytkowników nie może popełnić żadnych błędów I przeprowadzić testy bez blokady? Ale to typowy scenariusz, jeśli mnie pytasz. Współbieżność nie odgrywa żadnej roli w tej aplikacji. – Elisabeth

+0

Dzieje się tak, ponieważ poziom izolacji TransactionScope i testy trwają stosunkowo długo, aby mogły wystąpić zakleszczenia. Zwykle nie zdarzyłoby się tak szybko. Dodatkową zaletą każdego dewelopera posiadającego własną bazę danych jest to, że mogą eksperymentować z nową zawartością db bez przeszkadzania innym. Jeśli potrzebujesz wartości tożsamości (których nie polecam, użyj klawiszy naturalnych), po każdym teście musisz uruchomić DBCC CHECKIDENT (reseed). –

+0

Och naturalne klucze kontra zastępcza dyskusja kluczy jest tak stara jak ludzkość ;-) – Elisabeth

Powiązane problemy