SparkyTestHelpers: XML
Tags: csharp, dotnet, testing, unittesting
Published: 2020-02-26 01:40:33

> [NuGet package](https://www.nuget.org/packages/SparkyTestHelpers.Xml/) | [Source code](https://github.com/BrianSchroer/sparky-test-helpers/tree/master/SparkyTestHelpers.Xml) | [API documentation](https://github.com/BrianSchroer/sparky-test-helpers/blob/master/SparkyTestHelpers.Xml/api.md)

The SparkyTestHelpers.Xml NuGet package contains helpers to perform .config file XML transformations, and to test the resulting transformed XML (or actually any XML, whether it’s .config format or not).

> XML .config file transforms are a powerful tool, but have you ever had a bad transformation and accidentally deployed a .config file to production with development appSettings values, connection strings or service endpoints? Howzabout we unit test those things? Here’s how:

```csharp
using SparkyTestHelpers.Xml;
using SparkyTestHelpers.Xml.Config;
using SparkyTestHelpers.Xml.Transformation;
. . .
// In test setup/initialize method:
    TransformResults transformResults = 
        XmlTransformer
        .ForXmlFile("../../web.config")
        .TransformedByFile("web.release.config")
        .Transform();

    if (!transformResults.Successful)
    {
        Assert.Fail(transformResults.ErrorMessage);
    }

    _xmlTester = new XmlTester(transformResults.XDocument);
. . .
// In unit test method:
    _xmlTester.AssertAppSettingsValue("testKey", "expectedValue");
```

##SparkyTestHelpers.Xml.XmlTester

Helper class for testing XDocument values (from .config file or any XML source).

###Constructors
- *XmlTester* **XmlTester**(*string xml*)
- *XmlTester* **XmlTester**(*XDocument xDocument*)

###Methods
- void **AssertAttributeValue** (*string elementExpression, string attributeName, string expectedValue*) - Assert the element attribute has the expected value.
- void **AssertAttributeValues** (*string elementExpression, IEnumerable<KeyValuePair<string, string>> attributeNamesAndExpectedValues*) - Assert that attributes have expected values.
- void **AssertAttributeValueMatch** (*string elementExpression, string attributeName, string pattern*)
Assert the element attribute value matches regular expression pattern.
- void **AssertElementDoesNotExist** (*string elementExpression*)
Assert element does not exist for specified XPath expresion.
- void **AssertElementDoesNotHaveAttribute** (*string elementExpression, string attributeName*)
Assert that element exists, but does not have the specified attribute.
- XElement **AssertElementExists** (*string elementExpression*)
Assert element exists for specified XPath expression.
- void **AssertElementText** (*string elementExpression, string expectedText*)
Assert the element contains an expected text value.
- void **AssertAttributeValueIsWellFormedUrl** (*string elementExpression, string attributeName*)
Assert element/attribute value is a well-formed URI string.
- void **AssertNoDuplicateElements** (*string elementExpression, string keyAttributeName, string[] ignoreKeys*)
Assert no duplicate elements found for element / key attribute combination.
- string **GetAttributeValue** (*XElement elem, string attributeName*)
Get XElement attribute value.
- XElement **GetElement** (*string elementExpression*)
Get first element matching XPath expression.
- IEnumerable<XElement> **GetElements** (*string expression*)
Get elements matching XPath expression.

###Properties and Fields
- XDocument **XDocument**
The XDocument being tested.

##SparkyTestHelpers.Xml.Config.XmlTesterConfigExtensions

XmlTester extension methods for testing app.config / web.config XML files:

- void **AssertAppSettingsKeyDoesNotExist** (*string key*) - Assert that specified configuration/appSettings key doesn’t exist.
- void **AssertAppSettingsValue** (*string key, string expectedValue*) - Assert expected value for configuration/appSettings key.
- void **AssertAppSettingsValueMatch** (*string key, string regExPattern*) - Assert that value for configuration/appSettings key matches RegEx pattern.
- void **AssertAppSettingsValues** (*IEnumerable<KeyValuePair<string, string>> keysAndValues*) - For specified dictionary of keys / expected values, verify that the actual appSetting values match.
- void **AssertClientEndpointAddressIsWellFormedUrl** (*string endpointName*) - Assert that ServiceModel client endpoint address is a well-formed URL.
- void **AssertClientEndpointAddressesAreWellFormedUrls** () - Assert that all ServiceModel client endpoint addresses are well-formed URLs.
- void **AssertCompilationDebugFalse** () - Assert that confirmation/system.web/compilation “debug” attribute has been removed or set to false.
- XElement **GetAppSettingsElement** (*string key*) - Get XElement for “appSettings” key.
- IEnumerable<XElement> **GetAppSettingsElements** () - Get appSettings XElements.
- string **GetAppSettingsValue** (*string key*) - Get value for “appSettings” key.
- string **GetClientEndpointAddress** (*string endpointName*) - Get “address” value for ServiceModel client endpoint.
- XElement **GetClientEndpointElement** (*string endpointName*) - Get XElement for ServiceModel client endpoint.
- IEnumerable<XElement> **GetClientEndpointElements** () - Get service client endpoint XElements.
- string **GetConnectionString** (*string name*) - Get connection string for name key.
- XElement **GetConnectionStringElement** (*string name*) - Get connection string XElement for name key.
- IEnumerable<XElement> **GetConnectionStringElements** () - Get connection string XElements.

##SparkyTestHelpers.Xml.Config.ConfigXPath

XPath string provider for XmlTester testing of .config XML files:

###Static Fields

- string **AnonymousAuthentication**
XPath string for anonymous authentication element:
`configuration/system.webServer/security/authentication/anonymousAuthentication`
- string **AppSettings**
XPath string for appSettings elements:
`configuration/appSettings/add`
- string **ConnectionStrings**
XPath string for connection string elements:
`configuration/connectionStrings/add`
- string **ClientEndpoints**
XPath string for service client endpoint elements:
`configuration/system.serviceModel/client/endpoint`
- string **SystemWebCompilation**
XPath string for system.web compilation element:
`configuration/system.web/compilation`
- string **WindowsAuthentication**
XPath string for Windows authentication element:
`configuration/system.webServer/security/authentication/windowsAuthentication`

###Static Methods

- string **AppSettingForKey** (*string key*) - Build XPath string for AppSettings key.
- string **ClientEndpointForName** (*string endpointName*) - Build XPath string for service client endpoint.
- string **ConnectionStringForName** (*string name*) - Build XPath string for connection string name key.

##SparkyTestHelpers.Xml.Transformation.XmlTransformer

XML .config file transformation test helper.

###Methods
- TransformResults **Transform** () - Perform XML transformation(s).

> To help speed up your unit testing, this method caches the TransformResults keyed by the specified ForXmlFile and TransformedByFile(s) combination, so the time-consuming actual transformation only happens once per file combination.

###Static Methods

An XmlTransformer instance is created starting with the static “fluent” ForXmlFile method:

```csharp
TransformResults transformResults = 
        XmlTransformer
        .ForXmlFile("../../web.config")
        .TransformedByFile("web.release.config")
        .Transform();
```

**ForXmlFile** takes a “params” array of relative file paths (relative to the unit test assembly file when tests are run), e.g.

```csharp
.ForXmlFile("../../web.config", "../../../web.config")
```

> It takes an array because the relative file locaion can differ depending on the test runner (Visual Studio / ReSharper / build on server, etc.). The **Transform** method resolves each specified possible path and uses the first one where a file is found.

**TransformedByFile** also takes a params string array, but one path will probably suffice because these paths are resolved relative to the file found by **ForXmlFile**, and it’s likely that your base .config and transform .config file(s) are in the same folder. (You can “dot together” multiple **TransformedByFile** clauses for multi-stage transformations.)

##SparkyTestHelpers.Xml.Transformation.TransformResults

XML transformation results returned by the **XmlTransformer.Transform** method.

###Properties and Fields
- boolean **Successful** - Was the transformation successful?
- XDocument **XDocument** - The transformed XDocument (if Successful; otherwise, null)
- string **TransformedXml** - The transformed XML string (if Successful; otherwise, null)
- string **ErrorMessage** - Error message (if Successful is false)
- string **Log** - Details about the files and transformation steps involved. Look here for details if not Successful.

- - -

Happy testing!