Deploying Composite Projects through a Database Unit Test Run
A customer asked me the other day how they could deploy Composite Projects as a part of a Database Unit Test run. They are using the Composite Project to segment their Database Projects into 2 projects for maintainability and deployment reasons. 1 schema is for a database they ship to customers as part of a BI application and the other is a superset schema that includes the shipped version, but also some additional schema for a hosted version of the same application. They are running unit tests through their database projects and needed to test the hosted version of their application.
Database Unit Test Projects provide the ability to deploy a database project and run data generation on a target database that can be used by the tests all in one test run. What is unique for Database Unit Tests is that you can define your tests using the language of the target and in this case it is T-SQL. The configuration of the unit test project only allows you to select one project as can be seen in the following:
You could define additional tests for each project, but that adds additional overhead and challenges to maintainability. I asked Jamie Laflen, a senior developer on my team, alternatives to use and he showed me a nifty approach that works really well and can be used for other customization of test runs if necessary. You can subclass the Database Test service. It’s pretty straight forward to implement. Replace the code in your DatabaseSetup class [DatabaseSetup.cs in the Unit Test Project] and set the relative paths to the projects in your solution you want to deploy. One thing to note is that you want to deploy them in the order of inner-most to outer-most based on how the references are setup.
Below is the code to subclass the test service and call deploy on database projects in your solution. Enjoy!
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Data.Schema.UnitTesting;
using Microsoft.Data.Schema.UnitTesting.Configuration;
namespace DBTestProject
{
[TestClass()]
public class DatabaseSetup
{
[AssemblyInitialize()]
public static void IntializeAssembly(TestContext ctx)
{
//Comment out the original call to deploy the database project
//DatabaseTestClass.TestService.DeployDatabaseProject();
//New up your own class and call your method to deploy the composite projects
MyDBTestService MyDatabaseTestService = new MyDBTestService();
MyDatabaseTestService.DeployProjects();
DatabaseTestClass.TestService.GenerateData();
}
}
class MyDBTestService : DatabaseTestService
{
public void DeployProjects()
{
DeployDatabaseProject(@"..\..\..\TestDBInner\TestDBInner.dbproj", "Debug", "System.Data.SqlClient", GetConnectionString());
DeployDatabaseProject(@"..\..\..\TestDBOuter\TestDBOuter.dbproj", "Debug", "System.Data.SqlClient", GetConnectionString());
}
private static string GetConnectionString()
{
DatabaseUnitTestingSection dbConfig =
(DatabaseUnitTestingSection)ConfigurationManager.GetSection("DatabaseUnitTesting");
return dbConfig.ExecutionContext.ConnectionString;
}
}
}