NUnit & Test Database

Posts   
 
    
Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 17-May-2006 21:47:13   

How does everyone populate your test database when you want to run NUnit? I like Ruby on Rails style, where they use fixtures, and before each test is run the test database is cleaned up and re-populated. I havn't found anything like this in .NET. I am curious what people are doing!

wvnoort
User
Posts: 96
Joined: 06-Jan-2005
# Posted on: 18-May-2006 09:46:07   

We let all unit test classes inherit from a base test class. The base class implements a standard teardown method. The testdb is populated by running a sqlscript (before the test is run), the teardown is also implemented using a sql script. Most of the scripts we generate using RedGate's SQLCompare tool. We use a second testdb that containts the data we need in all test to comare against.

I also want to know what other people are doing, since keeping the testdb in a proper state is complicated and labor intensive.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 18-May-2006 10:32:39   

I use 3 test databases: - northwind for fetches only - a unittest db for writes only (which are read back of course, but the tests focus on writes) - a database with inheritance for inheritance saves/reads

The inheritance database uses a couple of routines which insert a set of entities into the db first. This is per routine. So test starts: data is inserted, test runs, data is removed.

All unittests are targeted towards user-case scenario's: I have this piece of functionality, how should it be used and how would a user use it.

Frans Bouma | Lead developer LLBLGen Pro
Skeeterbug
User
Posts: 165
Joined: 21-May-2004
# Posted on: 19-May-2006 00:40:05   

I started thinking of some ways .NET could do what RoR does. If anyone doesn't know. Give this wiki a quick read: http://manuals.rubyonrails.com/read/chapter/26

My thoughts would be to write a schema, and use xml to create a fixture (RoR uses YAML for this).

Here is an example of what the XML could look like:


<?xml version="1.0" encoding="utf-8" ?>
<tables xmlns="http://tempuri.org/DBXML.xsd">
  <table name="SomeTable">
    <columns>
      <column name="test" dbType="int"/>
    </columns>
    <valueSets>
      <values>1</values>
    </valueSets>
  </table>
  <table name="Users">
    <columns>
      <column name="name" dbType="varchar"/>
      <column name="username" dbType="varchar"/>
    </columns>
    <valueSets>
      <values>jason,skeeterbug</values>
      <values>amber,amberlynn</values>
      <values>riley,bubba</values>
    </valueSets>
  </table>
</tables>

The idea would be to have a library that parses it and inserts your data based on the fixture. So in your Setup(), you can simply call the library to get your data fresh for each run. The library could also support properties and functions to get the data from the fixtures for dynamic testing, like the RoR fixtures (just not as dynamic as ruby). Let me know what your guys thoughts are on this. The schema can be re-worked, I am no XML expert wink

Here is the schema for the above XML:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="DBXML" targetNamespace="http://tempuri.org/DBXML.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/DBXML.xsd" xmlns:mstns="http://tempuri.org/DBXML.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="tableType">
    <xs:all>
      <xs:element name="columns" type="columns" />
      <xs:element name="valueSets" type="valueSet" maxOccurs="1" minOccurs="0" />
    </xs:all>
    <xs:attribute name="name" type="xs:string" />
  </xs:complexType>
  <xs:complexType name="columns">
    <xs:sequence>
      <xs:element name="column" type="columnType" maxOccurs="1000" minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="columnType">
    <xs:sequence>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" />
    <xs:attribute name="dbType" type="dbType" />
  </xs:complexType>
  <xs:element name="tables">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="table" type="tableType" minOccurs="0" maxOccurs="500" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="dbType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="int" />
      <xs:enumeration value="varchar" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="valueSet">
    <xs:sequence>
      <xs:element name="values" type="xs:string" maxOccurs="9000" minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>