Benefits of BooUnit.

Imagine you need to test a simple BizTalk solution which takes records from a source database, process them using an Orchestration and write these processed record in a destination database.
If any error is raised during message processing Orchestration is able to write records back to the source database annotating informations about the error.

To test this solution we need to implement a test with the following steps:
  1. Just for test sake, we need to clear EventLog before launching the test.
  2. Ensure source and destination databases are empty (deleting present records if needed).
  3. We need to populate source database with a predefined set of records (let's say 100 records).
  4. We need to ensure that source database has been correctly populated.
  5. For each send port (we have two, Send & SendBack) we need to enlist and start.
  6. For each orchestration (let's say we just have one main orchestration) we need to invoke start
  7. For each receive port (we have just one in this example) we need to enable locations
  8. We have to wait a time sufficient to allow records to be processed
  9. For each receive port (we have just one in this example) we need to disable locations
  10. For each orchestration (we just have one main orchestration in this example) we need to invoke stop.
  11. For each send port (we have two, Send & SendBack) we need to stop and, probably, unenlist.
  12. We need to count data transported to destination database (expected 100)
  13. We need to count data written back to the source database (expected 0)
  14. To leave environment in a clean state we need to delete records from source and destination databases

Here a BizUnit test implementing this simple testcase.

The same test case written in BooUnit is reported below (in fact BizUnit test linked above was generated automatically from BooUnit using the following script):

#Declaring Variables
MachineName = "ASCOTTO"
#Declaring source/destination databases
ConnectionStringSOURCESYSTEM = "Data Source=SOURCESYSTEM;User Id=SOURCE;Password=SOURCE;"
ConnectionStringDESTINATIONSYSTEM = "Data Source=DESTINATIONSYSTEM;User Id=DESTINATION;Password=DESTINATION;"
SourceTable = "SRC_TABLE";
DestTable = "DST_TABLE";
SourceDataSet = "DBTable.xml"
#Declaring SendPort array
SendPortNames = ("SendTo_DESTINATIONSYSTEM","SendBackTo_SOURCESYSTEM")
#Declaring ReceiveLocations
ReceiveLocationNames = ("ReceiveLocation_SOURCESYSTEM_Oracle",)
ReceivePortName = "ReceivePort_SOURCESYSTEM"
#Declaring Orchestrations
AssemblyName = "Orchestrations"
OrchestrationNames = ("Orchestrations.Main",)
TestFolder = "C:\\";

BizUnitTest "GRP Test":
	Setup:
		#Clear EventViewer
		EventLogClearStep MachineName,"Application";
		#Clean Databases
		OracleDatabaseDeleteStep ConnectionStringSOURCESYSTEM,SourceTable,"1=1";
		OracleDatabaseDeleteStep ConnectionStringDESTINATIONSYSTEM,DestTable,"1=1";
		#Populate source database with test data
		OracleImportDatasetToDBStep 
			"0",
			ConnectionStringSOURCESYSTEM,
			System.IO.Path.Combine(TestFolder,"DBTableSchema.xml"),
			System.IO.Path.Combine(TestFolder,SourceDataSet),
			"5";
		#Check that all 100 rows have been correctly loaded
		OracleDatabaseRowCountStep ConnectionStringSOURCESYSTEM,SourceTable,"1=1","100"
	Execution:
		#Activate Send Ports
		for snd in SendPortNames:
			SendPortConductorStep "0", snd, "Enlist"
			SendPortConductorStep "0", snd, "Start"
		#Activate Orchestrations
		for orch in OrchestrationNames:
			OrchestrationConductorStep "0", AssemblyName , orch,"Start"
		#Activate Receive Ports
		for rln in ReceiveLocationNames:
			ReceivePortConductorStep "0", ReceivePortName, rln,"Enable"
		#Wait Delay (in milliseconds)
		DelayStep "10000"
		#Deactivate ReceiveLocations
		for rln in ReceiveLocationNames:
			ReceivePortConductorStep "0", ReceivePortName, rln, "Disable"
		#Deactivate Orchestrations
		for orch in OrchestrationNames:
			OrchestrationConductorStep "0", AssemblyName , orch,"Stop"
		#Deactivate SendPorts
		for snd in SendPortNames:
			SendPortConductorStep "0", snd, "Stop"
			SendPortConductorStep "0", snd, "UnEnlist"
		#Count records in destination database (Expected 100)
		OracleDatabaseRowCountStep ConnectionStringDESTINATIONSYSTEM,DestTable,"1=1","100"
		#Count records written back to source database (Expected 0)
		OracleDatabaseRowCountStep ConnectionStringSOURCESYSTEM,SourceTable,"1=1","0"
	Cleanup:
		#Clean source and destination databases
		OracleDatabaseDeleteStep ConnectionStringSOURCESYSTEM,SourceTable,"1=1";
		OracleDatabaseDeleteStep ConnectionStringDESTINATIONSYSTEM,DestTable,"1=1";


Even if in this wiki page boo code is written without syntax-highlighting, the code above should result clearer than xml counterpart for a lot of developers.


Without considering that, being boo code, script above contains a lot of language constructs that can't implement in the xml counterpart, for example:
  • Variables: MachineName, ConnectionStringSOURCESYSTEM, ConnectionStringDESTINATIONSYSTEM, etc are language variables and therefore are declared once and used several times in the script, this mechanism could be obtained in BizUnit using Context Object but boo syntax is IMHO cleaner and simpler.
  • .NET Keywords: Being a .NET language, boo is able to consume .NET Framework: invoking methods and using objects; in the script above, for example, OracleImportDatasetToDBStep has parameters calculated invoking System.IO.Path.Combine method, this is impossible to obtain using normal BizUnit scripts.
  • Flow control: Since in this solution we have two send ports we need to enlist and start both of them, instead of cut&paste xml block to enlist a send port, wwe can use for keyword to iterate through all declared send port as done, in the above code, to enable ReceiveLocations, Orchestrations and SendPorts.

Last edited May 1, 2008 at 6:16 PM by KidFashion, version 10

Comments

No comments yet.