Bei diesem Vorgehen werden die Testfälle gegen eine eigene Testdatenbank ausgeführt, die erst zur Laufzeit gemountet und angesprochen wird. Als Voraussetzung benötigt man eine gefüllte Datenbankdatei und den MS SQL Server Express.
Ihm kann man im ConnectionString über den Befehl "AttachDBFilename" eine Datenbankdatei mitgeben, die er dann mountet. Leider wird der Platzhalter |DataDirectory| nur in ASP.Net Applikationen richtig gefüllt, da hier der Paramater in der AppDomain überhaupt gefüllt ist. Man könnte diese per Code setzen, was nicht so sauber ist.
- AppDomain.CurrentDomain.SetData("DataDirectory", …);
Ich empfehle dringend während des Testlaufs eine Kopie der Datei zu mounten, denn Veränderungen über SQL werden persistiert! Ich habe mich in meinem Beispiel dafür entschieden die Datei nach C:Temp zu kopieren und sie von dort zu mounten.
Erstellung und Bearbeitung der Testdaten
Zum Erstellen oder Befüllen der Datenbankdatei kann man Visual Studio zur Hilfe nehmen. Bei einer neuen Datenbank muss man unbedingt für den aktuellen Login einen User auf der Datenbank erstellen. Ansonsten kommt es beim späteren Mounten zu einem Fehler. Der MS SQL Server Express wirft dann eine nichts sagende "Datei korrupt" Fehlermeldung.
Sobald man alle Testdaten erstellt hat könnte man die Datenbankdatei sogar in ein Source Control System einchecken. Sie ist ein Teil des Projektes. Auch hier enthält die Datenbank alle Testdaten. Man könnte sogar für jedes Testszenario eine eigene Datenbank verwenden. Dies wäre nur sehr aufwendig.
Testablauf am Beispiel der Referenzanwendung
- Die Testdatenbankdatei wird kopiert.
- Eine Verbindung zum MS SQL Server Express wird geöffnet, dabei ist im ConnectionString der Pfad zur Testdatenbankdatei enthalten.
- Es wird davon ausgegangen dass die Daten in der Tabelle [dbo].[Source] zum 1.1.2014 vorliegen.
- Die Tabelle [dbo].[Target_Sum] wird gelöscht.
- [dbo].[Delete_Target_Sum_ByCalcDate]
- Die Tabelle [dbo].[Target_Sum] wird befüllt.
- [dbo].[Insert_Target_ByCalcDate]
- Es wird geprüft ob die Daten wie erwartet in der Tabelle [dbo].[Target_Sum] vorliegen.
- Die Daten werden vom Test in eine Datei exportiert.
- Die Datei wird mit einer erwarteten Datei verglichen.
[TestInitialize]
public void Init()
{
//AppDomain.CurrentDomain.SetData("DataDirectory", ...);
//Was ist richtig(er)?
//Environment.CurrentDirectory;
//AppDomain.CurrentDomain.BaseDirectory;
// Achtung: Wenn Shadowcopy aktiv wird es komliziert. In NUnit standardmäßig aktiviert!
//(typeof(UnitTest1)).Assembly.CodeBase // wird mit file:/// geliefert
//(typeof(UnitTest1)).Assembly.Location
}
[TestMethod]
public void DALTest_MountDB()
{
DBManagerTarget mgr = new DBManagerTarget();
DateTime calcDate = new DateTime(2014, 01, 01);
mgr.DeleteTargetSum(calcDate);
mgr.FillTarget(calcDate);
DBManager testDatenmanger = new DBManager("DB", false);
string filename = "DALTest_MountDB_UnitTest1.txt";
testDatenmanger.ReadToFile(
DIRTARGET + filename,
"SELECT * FROM dbo.Target_Sum WHERE CalcDate='2014-01-01';");
CompareHelper.AssertAreEual(DIRSOURCE + filename, DIRTARGET + filename);
}
<connectionStrings>
<clear/>
<!--add name="DB" connectionString="Server=(localdb)Projects;AttachDbFilename=|DataDirectory|DBDBTesting.mdf..."/ -->
<add name="DB" connectionString="Server=(localdb)Projects;AttachDbFilename=C:TEMPDBTesting.mdf;Database=DBTesting;Trusted_Connection=Yes;" .../>
</connectionStrings>
Ergebnis: Erfolgreich
SELECT * FROM dbo.Target_Sum WHERE CalcDate='2014-01-01';
CalcDate(datetime),ID(int),Value(float)
01.01.2014 00:00:00,1,10
01.01.2014 00:00:00,2,20
01.01.2014 00:00:00,3,30
01.01.2014 00:00:00,4,40
Sollte jedoch die Tabelle [dbo].[Target_Code] schon mit anderen Werten befüllt sein, so wären abweichende technische IDs das Ergebnis und der Testfall wäre nicht erfolgreich.
Vorteile
- Daten sind exakt auf die Tests zugeschnitten
- Entwicklungsdaten werden nicht geändert
- Sogar IDENTITY Spalten können exakt getestet werden
- Testdaten (Datenbankdatei) kann mit in einem Source Control System abgelegt werden
- Nachvollziehbarkeit steigt
- Einfache Verteilung der Testfälle für alle Entwickler
- MS SQL Server Express ist in der Standardinstallation vom Visual Studio enthalten
- Pro Testszenarien eigene Datenbankdatei möglich
- Test läuft komplett lokal ab
Nachteile
- Weitere Umgebung die aktuell gehalten werden muss
- MS SQL Server Express ist kein MS SQL Server, dessen Dateien können nicht im MS SQL Server gehostet werden
- Abweichendes Feature Set
- Abweichende Verarbeitung (Performance)
- Aufwand steigt mit Anzahl der in Datenbankdateien separierten Testszenarien
Bei der Verwendung von nur einer Datenbankdatei gibt es kaum Vorteile zum vorherigen Vorgehen. Lediglich das hier die Datei unter Source Code Verwaltung gestellt werden kann. Jedoch können durch die Verwendung mehre Datenbankdateien verschiedene Testszenarien getrennt werden und sich so gegenseitig nicht mehr beeinflussen.