rickgaribay.net

Space shuttles aren't built for rocket scientists, they're built for astronauts. The goal isn't the ship, its the moon.
posts - 303, comments - 180, trackbacks - 35

My Links

News

Where's Rick?


AgileAlliance deliver:Agile 2019- 4/29
Desert Code Camp, PHX - 10/11
VS Live Austin, TX - 6/3
VS Live SF - 6/17


About Me
Hands on leader, developer, architect specializing in the design and delivery of distributed systems in lean, agile environments with an emphasis in continuous improvement across people, process and technology. Speaker and published author with 18 years' experience leading the delivery of large and/or complex, high-impact distributed solutions in Retail, Intelligent Transportation, and Gaming & Hospitality.

I'm currently a Principal Engineer at Amazon, within the North America Consumer organization leading our global listings strategy that enable bulk and non-bulk listing experiences for our WW Selling Partners via apps, devices and APIs.

Full bio

Note: All postings on this site are my own and don’t necessarily represent the views of my employer.



Check out my publications on Amazon Kindle!





Archives

Post Categories

Published Works

Take Me with You! Ensuring Team Build Brings Dependencies Along for the Ride

As part of an automated build at a client, we currently have over 150 unit tests that run as part of each automated build. Some of the tests are also integration tests which serve to automatically smoke test the freshly compiled application code.

One of our apps makes use of an XML file that allows the ability to dynamically change behavior of a component without requiring an app domain recycle. A static method uses a FileWatcher to detect a change and applies the configuration changes at runtime accordingly. But I digress…

When Team Build executes your unit tests, it creates a special directory on the build agent called TestResults.The TestResults folder includes a .trx file that captures the build results in XML along with a folder for each build/run which isolates all required test assemblies and other dependant assemblies for execution. The App.config file will automatically be copied over and renamed to AssemblyName.dll.config. This is fine and dandy, but what about other dependencies like the XML file?

The answer is different depending on whether you are running your tests locally from Visual Studio or if Team Build is running your tests as part of an automated build, but you must be familiar with both techniques to accomplish a consistent and repeatable means for taking the XML file along for the ride under both scenarios which you will undoubtedly need to understand because chances are you are (or at least should be) running all unit tests locally before checking into source control, right? Right?

Local Dependencies

When running and debugging unit tests using Visual Studio and a just-in-time test runners like TestDriven.NET that have an external dependency such as an XML file, you must ensure the dependency is in the binary root relative to the executing assembly. This is also true when using other unit testing frameworks like NUnit, which I talk about here.

Right click the resource in the test project, click properties and set “Copy to Output Directory” to “Copy Always”:

image

This will ensure that the dependency is copied to the bin directory just as other dependencies like DLLs and App.Config/Web.Config are automatically.

At this point, the XML file can be referenced in the root of the bin which is relative to the executing assembly.

Team Build Dependencies

As I mentioned earlier, when Team Build executes unit tests, it moves all required assemblies and assembly dependencies to a TestResults folder. While this includes App.config and Web.config files, other dependencies are not copied regardless of whether you specify “Copy to Output Directory” to “Copy Always” as shown above. This makes sense, because when Team Build runs, the unit test project is no longer located with the rest of the source- instead it is copied to the TestResults folder and prepped for execution.

There are two ways to address this.

The first option is to mark each test method with a DeploymentItem attribute. This is documented here, so I won’t go into much into it. The basic usage is to mark you test method with the DeploymentItem attribute, providing a parameter with the path and filename of the dependency:

   1:  [TestMethod]
   2:          [DeploymentItem("../../MyExternalDependency.xml")]
   3:          public void FooShouldReturnBar()
   4:          {  
   5:   
   6:             //...
   7:   
   8:          }

When the assembly that includes the test class loads, the attribute is reflected and the dependent file is copied to the TestResults folder. You can also add the attribute at the test class level and it will have the same effect.

The draw back of this approach is that it requires that you apply this attribute to the test class and it is really quite noisy because it is only used when running tests with Team Build or the Test List Editor.

To keep things cleaner, I prefer to make these dependencies configuration driven. So, similarly to setting the “Copy to Output Directory” to “Copy Always” for just-in-time testing, you can determine dependencies that should be copied to the TestResults folder using a global configuration setting that will apply to all tests: Test Run Configuration.

Go to Test, “Edit Test Run Configuration” and click on the configuration file as shown below:

 

image

Now, click on the Deployment option on the left, ensure “Enable Deployment” is checked, and either click “Add File” to add a specific file, or “Add Directory” to include the entire contents of a directory:

 

image

 

The localtestrun.testrunconfig file will be configured with the dependencies specified and this file will be consulted just prior to kicking off a test run to ensure that all dependencies are copied to the TestResults folder.

That’s really all there is to it. Thanks to Brendon Birdoes for turning me on to the DeploymentItem attribute which I was not familiar with.

Print | posted on Thursday, August 27, 2009 8:05 PM | Filed Under [ Processs Visual Studio Continuous Integration TDD ]

Comments have been closed on this topic.

Powered by: