Michael Stephenson

keeping your feet on premise while your heads in the cloud
posts - 358 , comments - 427 , trackbacks - 11

My Links

News

View Michael Stephenson's profile on BizTalk Blog Doc View Michael Stephenson's profile on LinkedIn

Twitter












Archives

Post Categories

Image Galleries

BizTalk

Mates

BDD and BizUnit 2 – Not as cool as combining BizUnit 4 & SpecFlow but still works ok

I've been back working with BizTalk 2006 R2 for a customer recently and I've become such a fan of the BDD style acceptance tests I've done in the past with BizTalk 2010 that its quite frustrating working back in Visual Studio 2005 and not being able to use Specflow alongside BizUnit 4 like I described in the recent videos on these subjects

 

In BizTalk 2006 development your back to the older style xml bizunit tests and we were looking at some old tests written a long time ago and frankly it's hard to remember what they were supposed to do. This is where the separation between intention and implementation of the test is so important. Since there isn't a great deal we can do about this in terms of upgrading the technology we took the very simple approach of annotating the BizUnit tests using the Gherkin style so that before each test step or group of test steps there was something to explain what was intended to happen. The other benefit is it really encourages the TDD approach.

In the first example below you can see when writing a new test we have simply used the Gherkin syntax Given/When/Then to record the requirements and definition of what needs to happen in this test.

<TestCase testName="VAU.CardChanges">

<TestSetup>

<!-- GIVEN: The test event queue is clean-->

<!-- GIVEN: The test folder is empty - Acquirer folders -->

<!-- GIVEN: The test folder is empty - CardSystem folders -->

<!-- GIVEN: The test folder is empty - CRM folders -->

<!-- GIVEN: The acquirer file generation numbers are zero -->

</TestSetup>

<TestExecution>

<!-- WHEN: TWS calls BizTalk to trigger the validation of payments -->

<!-- THEN: The response will indicate that validation has started -->

<!-- THEN: BizTalk will start the batch processing orchestration -->

<!-- THEN: BizTalk will send the batch to the acquirer -->

<!-- THEN: The acquirer will find the batch in their input folder -->

<!-- THEN: The acquirer will put the response in their output folder -->

<!-- THEN: BizTalk will recieve an acknowledgement from the acquirer -->

<!-- THEN: BizTalk will recieve a response file from the acquirer -->

<!-- THEN: BizTalk will process any card updates -->

<!-- THEN: The card will be updated in CARDSYSTEM-->

<!-- THEN: The validation batch will be updated in CARDSYSTEM-->

<!-- THEN: The card will be updated in CRM-->

<!-- THEN: Biztalk will have completed processing the validation batch response -->

<!-- THEN: The card update received by CRM will be valid -->

<!-- THEN: The card update received by CARDSYSTEM will be valid -->

</TestExecution>

<TestCleanup>

<!—Clean Test Folders -->

</TestCleanup>

</TestCase>

 

The fully completed and implemented test looks like the below example. Now hopefully you can clearly see how important this simple documentation around the tests are for people who may look at this in the future.

 

<TestCase testName="VAU.CardChanges">

<TestSetup>

<!-- GIVEN: The test event queue is clean-->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.CleanEvents">

</TestStep>

<!-- GIVEN: The test folder is empty - Acquirer folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerRequest</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerResponse</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<!-- GIVEN: The test folder is empty - CardSystem folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CardSystemWS</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<!-- GIVEN: The test folder is empty - CRM folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CRMWS</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<!-- GIVEN: The acquirer file generation numbers are zero -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.DBExecuteNonQueryStep">

<DelayBeforeExecution>1</DelayBeforeExecution>

<ConnectionString>Persist Security Info=False;Integrated Security=SSPI;Server=localhost;Database=PaymentCardServices</ConnectionString>

<SQLQuery>

<RawSQLQuery>UPDATE FileNumber SET FileNumber = 1 WHERE ID = 'NextFGN'</RawSQLQuery>

</SQLQuery>

</TestStep>

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.DBExecuteNonQueryStep">

<DelayBeforeExecution>1</DelayBeforeExecution>

<ConnectionString>Persist Security Info=False;Integrated Security=SSPI;Server=localhost;Database=PaymentCardServices</ConnectionString>

<SQLQuery>

<RawSQLQuery>UPDATE FileNumber SET FileNumber = 1 WHERE ID = 'ActiveFGN'</RawSQLQuery>

</SQLQuery>

</TestStep>

</TestSetup>

<TestExecution>

<!-- WHEN: TWS calls BizTalk to trigger the validation of payments -->

<TestStep assemblyPath="Acme.BizTalk.Fx.Testing.dll" typeName="Acme.BizTalk.Fx.Testing.BizUnit.Wse2WebServicesClientProtocolStep">

<WebServiceUrl>http://localhost/Acme.CardProcessing.Secure/CardService.ashx</WebServiceUrl>

<ProxyTypeName>Acme.CardProcessing.Utilities.Testing.TestProxies CardService, Acme.CardProcessing.Utilities</ProxyTypeName>

<ProxyMethodName>SubmitBatchValidation</ProxyMethodName>

<ExpectingError>false</ExpectingError>

<InputMessageTypeName>Acme.CardProcessing.Utilities.Testing.TestProxies.CardValidationBatch, Acme.CardProcessing.Utilities</InputMessageTypeName>

<MessagePayloadPath>..\..\..\Acme.CardProcessing.AcceptanceTests\Features\BatchValidation\TestData\CardChanges.Input.xml</MessagePayloadPath>

<!-- THEN: The response will indicate that validation has started -->

<ValidationStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.XmlValidationStep">

<XPathList>

<XPathValidation query="/ValidationBatchesReturn/Return">0</XPathValidation>

</XPathList>

</ValidationStep>

</TestStep>

<!-- THEN: BizTalk will start the batch processing orchestration -->

<TestStep assemblyPath="Acme.CardProcessing.AcceptanceTests.dll" typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Batch validation started</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: BizTalk will send the batch to the acquirer -->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Batch sent to acquirer</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: The acquirer will find the batch in their input folder -->

<TestStep assemblyPath="Acme.BizTalk.Fx.Testing.dll" typeName="Acme.BizTalk.Fx.Testing.BizUnit.FileExistsStep">

<Timeout>60</Timeout>

<DirectoryPath>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerRequest</DirectoryPath>

<SearchPattern>*.*</SearchPattern>

<ExpectedNoOfFiles>1</ExpectedNoOfFiles>

</TestStep>

<!-- THEN: The acquirer will put the response in their output folder -->

<TestStep assemblyPath="Acme.CardProcessing.AcceptanceTests.dll" typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.ProcessAcquirerFileStep">

<DirectoryPath>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerRequest</DirectoryPath>

<SearchPattern>INZET.DANG.MDNDMDM</SearchPattern>

<ResponsesXmlFileName>..\..\..\Acme.CardProcessing.AcceptanceTests\GenericTestData\HSBCDefaultBatchResponse.xml</ResponsesXmlFileName>

<SchemaFileName>..\..\..\Acme.CardProcessing.AcceptanceTests\GenericTestData\BatchResponses.xsd</SchemaFileName>

<CreationPath>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerResponse</CreationPath>

<InvalidResponse></InvalidResponse>

<MultipleResponse>false</MultipleResponse>

</TestStep>

<!-- THEN: BizTalk will recieve an acknowledgement from the acquirer -->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Acknowledgement received from acquirer</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: BizTalk will recieve a response file from the acquirer -->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Acquirer response received</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: BizTalk will process any card updates -->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Processing card updates</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: The card will be updated in CARDSYSTEM-->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>CardServicesStub.CardServices.UpdatePaymentCards Called</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: The validation batch will be updated in CARDSYSTEM-->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>CardServicesStub.CardServices.UpdateValidationBatch Called</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: The card will be updated in CRM-->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>CRMApplicationStub.FinanceRefService.UpdateCreditCardDetails Called</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: Biztalk will have completed processing the validation batch response -->

<TestStep

assemblyPath="Acme.CardProcessing.AcceptanceTests.dll"

typeName="Acme.CardProcessing.AcceptanceTests.BizUnitSteps.TestEvents.EventExists">

<Action>Batch validation completed</Action>

<RemoveEventFromQueue>true</RemoveEventFromQueue>

<SecondsToWait>30</SecondsToWait>

</TestStep>

<!-- THEN: The card update received by CRM will be valid -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileValidateStep">

<Timeout>6000</Timeout>

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CRMWS</Directory>

<SearchPattern>*.*</SearchPattern>

<DeleteFile>false</DeleteFile>

<ValidationStep assemblyPath="Acme.CardProcessing.Utilities.dll" typeName="Acme.CardProcessing.Utilities.Testing.BizUnit.XmlComparisonValidationStep">

<CompareTo>CardChanges.CRM.UpdateCards.xml</CompareTo>

</ValidationStep>

</TestStep>

<!-- THEN: The card update received by CARDSYSTEM will be valid -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileMultiValidateStep">

<Timeout>6000</Timeout>

<DirectoryPath>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CardSystemWS</DirectoryPath>

<SearchPattern>*.*</SearchPattern>

<ValidationStep assemblyPath="Acme.CardProcessing.Utilities.dll" typeName="Acme.CardProcessing.Utilities.Testing.BizUnit.XmlComparisonValidationStep">

<CompareTo>CardChanges.CardSystem.UpdateCards.xml</CompareTo>

</ValidationStep>

<ValidationStep assemblyPath="Acme.CardProcessing.Utilities.dll" typeName="Acme.CardProcessing.Utilities.Testing.BizUnit.XmlComparisonValidationStep">

<CompareTo>CardChanges.UpdateBatch.xml</CompareTo>

</ValidationStep>

</TestStep>

</TestExecution>

<!-- Clear out all test folders -->

<TestCleanup>

<!-- Acquirer folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerRequest</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\AcquirerResponse</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<!—Card App folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CardSystemWS</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

<!-- CRM folders -->

<TestStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.FileDeleteMultipleStep">

<Directory>..\..\..\Acme\CardProcessing\Stubs\DropFolders\CRMWS</Directory>

<SearchPattern>*.*</SearchPattern>

</TestStep>

</TestCleanup>

</TestCase>

 

Print | posted on Friday, November 4, 2011 10:40 AM | Filed Under [ BizTalk BizTalk Testing ]

Feedback

No comments posted yet.
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: