How to: Create a Diagnostic Data Adapter

To create a diagnostic data adapter, you create a class library using Microsoft Visual Studio 2010, and then add the Diagnostic Data Adapter APIs provided by Microsoft Visual Studio 2010 Premium to your class library. Send any information that you want as a stream or a file to the DataCollectionSink provided by the framework, when handling the events that are raised during the test run. The streams or files sent to the DataCollectionSink are stored as attachments to the test results when your test finishes. If you create a bug from these test results or when you use Test Runner, the files are also linked to the bug.

You can create a diagnostic data adapter that affects the machine where your tests are run, or a machine that is part of the environment you are using to run your application under test. For example, collecting files on your test machine where the tests are run, or collecting files on the machine serving in the Web server role for your application.

You can give your diagnostic data adapter a friendly name that displays when you create your test settings using Test Manager or using Microsoft Visual Studio 2010. Test settings enable you to define which machine role will run specific diagnostic data adapters in your environment when you run your tests. You can also configure your diagnostic data adapters when you create your test settings. For example, you may create a diagnostic data adapter that collects custom logs from your Web server. When you create your test settings, you can select to run this diagnostic data adapter on the machine or machines that are performing this Web server role and you can modify the configuration for your test settings to collect only the last three logs that were created. For more information about test settings, see Setting Up Machines and Collecting Diagnostic Information Using Test Settings.

Events are raised when you run your tests so that your diagnostic data adapter can perform tasks at that point in the test.

Important

These events may be raised on different threads, especially when you have tests running on multiple machines. Therefore, you must be aware of possible threading issues and not inadvertently corrupt the internal data of the custom adapter. Make sure your diagnostic data adapter is thread safe.

The following is a partial list of key events that you can use when you create your diagnostic data adapter. For a complete list of diagnostic data adapter events, see the abstract DataCollectionEvents class.

Event

Description

SessionStart

Start of your test run

SessionEnd

End of your test run

TestCaseStart

Start of each test in the test run

TestCaseEnd

End of each test in the test run

TestStepStart

Start of each test step in a test

TestStepEnd

End of each test step in a test

Note

When a manual test is completed, no more data collection events are sent to the diagnostic data adapter. When a test is rerun, it will have a new test case identifier. If a user resets a test during a test (which raises the TestCaseReset event), or changes a test step outcome, no data collection event is sent to the diagnostic data adapter, but the test case identifier remains the same. To determine whether a test case has been reset, you must track the test case identifier in your diagnostic data adapter.

Use the following procedure to create diagnostic data adapter that collects a data file that is based on information that you configure when you create your test settings.

For a complete example diagnostic data adapter project, including a custom configuration editor, see Sample Project for Creating a Diagnostic Data Adapter.

Creating and Installing a Diagnostic Data Adapter

To create and install a diagnostic data adapter

  1. Create a new class library.

    1. On the File menu, click New, and then point to New Project.

    2. From Project types, select the language to use.

    3. From Visual Studio installed templates, select Class Library.

    4. Type a name for your Diagnostic Data Adapter.

    5. Click OK.

  2. Add the assembly Microsoft.VisualStudio.QualityTools.ExecutionCommon.

    1. In Solution Explorer, right-click References and click the Add Reference command.

    2. Click .NET and locate Microsoft.VisualStudio.QualityTools.ExecutionCommon.dll.

    3. Click OK.

  3. Add the assembly Microsoft.VisualStudio.QualityTools.Common.

    1. In Solution Explorer, right-click References and select the Add Reference command.

    2. Click /.NET, locate Microsoft.VisualStudio.QualityTools.Common.dll.

    3. Click OK.

  4. Add the following using statements to your class file:

    using Microsoft.VisualStudio.TestTools.Common;
    using Microsoft.VisualStudio.TestTools.Execution;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System;
    
  5. Add the DataCollectorTypeUriAttribute to the class for your diagnostic data adapter to identify it as a diagnostic data adapter, replacing Company, Product, and Version with the appropriate information for your Diagnostic Data Adapter:

    [DataCollectorTypeUri("datacollector://Company/Product/Version")]
    
  6. Add the DataCollectorFriendlyNameAttribute attribute to the class, replacing the parameters with the appropriate information for your Diagnostic Data Adapter:

    [DataCollectorFriendlyName("Collect Log Files", false)]
    

    This friendly name is displayed in the test settings activity.

    Note

    You can also add the DataCollectorConfigurationEditorAttribute to specify the Type of your custom configuration editor for this data adapter, and to optionally specify the help file to use for the editor.

    You can also apply the DataCollectorEnabledByDefaultAttribute to specify that it should always be enabled.

  7. Your diagnostic data adapter class must inherit from the DataCollector class as follows:

    public class MyDiagnosticDataAdapter : DataCollector
    
  8. Add the local variables as follows:

    private DataCollectionEvents dataEvents;
    private DataCollectionLogger dataLogger;
    private DataCollectionSink dataSink;
    private XmlElement configurationSettings;
    
  9. Add the Initialize method and a Dispose method. In the Initialize method, you initialize the data sink, any configuration data from test settings, and register the event handlers you want to use as follows:

    public override void Initialize(
        XmlElement configurationElement, 
        DataCollectionEvents events, 
        DataCollectionSink sink, 
        DataCollectionLogger logger, 
        DataCollectionEnvironmentContext environmentContext)
    {
           dataEvents = events;  // The test events
           dataLogger = logger;  // The error and warning log
           dataSink = sink;      // Saves collected data
           // Configuration from the test settings
           configurationSettings = configurationElement;
    
           // Register common events for the data collector
           // Not all of the events are used in this class
        dataEvents.SessionStart += 
            new EventHandler<SessionStartEventArgs>(OnSessionStart);
        dataEvents.SessionEnd += 
            new EventHandler<SessionEndEventArgs>(OnSessionEnd);
        dataEvents.TestCaseStart += 
            new EventHandler<TestCaseStartEventArgs>(OnTestCaseStart);
        dataEvents.TestCaseEnd += 
            new EventHandler<TestCaseEndEventArgs>(OnTestCaseEnd);
    }
    
    public override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Unregister the registered events
            dataEvents.SessionStart -= 
                new EventHandler<SessionStartEventArgs>(OnSessionStart);
            dataEvents.SessionEnd -= 
                new EventHandler<SessionEndEventArgs>(OnSessionEnd);
            dataEvents.TestCaseStart -= 
                new EventHandler<TestCaseStartEventArgs>(OnTestCaseStart);
            dataEvents.TestCaseEnd -= 
                new EventHandler<TestCaseEndEventArgs>(OnTestCaseEnd);
        }
    }
    
  10. Use the following event handler code and private method to collect the log file generated during the test:

    public void OnTestCaseEnd(sender, TestCaseEndEventArgs e)
    {
        // Get any files to be collected that are
        // configured in your test settings
        List<string> files = getFilesToCollect();
    
        // For each of the files, send the file to the data sink
        // which will attach it to the test results or to a bug
        foreach (string file in files)
        {
            dataSink.SendFileAsync(e.Context, file, false);
        }
    }
    
    // A private method that returns the file names
    private List<string> getFilesToCollect()
    {
        // Get a namespace manager with our namespace
        XmlNamespaceManager nsmgr =
            new XmlNamespaceManager(
                configurationSettings.OwnerDocument.NameTable);
        nsmgr.AddNamespace("ns", 
            "http://MyCompany/schemas/MyDataCollector/1.0");
    
        // Find all of the "File" elements under our configuration
        XmlNodeList files =
            configurationSettings.SelectNodes(
                "//ns:MyDataCollector/ns:File");
    
        // Build the list of files to collect from the 
        // "FullPath" attributes of the "File" nodes.
        List<string> result = new List<string>();
        foreach (XmlNode fileNode in files)
        {
            XmlAttribute pathAttribute = 
                fileNode.Attributes["FullPath"];
            if (pathAttribute != null &&
                !String.IsNullOrEmpty(pathAttribute.Value))
            {
                result.Add(pathAttribute.Value);
            }
        }
    
        return result;
    }
    

    These files are attached to the test results. If you create a bug from these test results or when you use Test Runner, the files are also attached to the bug.

    If you want to use your own editor to collect data to use in your test settings, see How to: Create a Custom Editor for Data for Your Diagnostic Data Adapter.

  11. To collect a log file when a test finishes based on what the user configured in test settings, you must create an App.config file and add it to your solution. This file has the following format and must contain the URI for your diagnostic data adapter to identify it. Substitute real values for the "Company/ProductName/Version".

    Note

    If you do not need to configure any information for your diagnostic data adapter, then you do not need to create a configuration file.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <section name="DataCollectorConfiguration" 
          type="Microsoft.VisualStudio.TestTools.Execution.DataCollectorConfigurationSection, 
          Microsoft.VisualStudio.QualityTools.ExecutionCommon, 
          Version=4.0.0.0, Culture=neutral, 
          PublicKeyToken=b03f5f7f11d50a3a" />
      </configSections>
      <DataCollectorConfiguration 
        xmlns="https://microsoft.com/schemas/VisualStudio/TeamTest/2010">
        <DefaultConfiguration>
          <!-- Your default config settings -->
            <File FullPath="C:\temp\logfile1.txt"/>
            <File FullPath="C:\temp\logfile2.txt"/>
        </DefaultConfiguration>
      </DataCollectorConfiguration>
    </configuration> 
    

    Note

    The default configuration element can contain any data that you require. If the user does not configure the diagnostic data adapter in test settings, then the default data will be passed to your diagnostic data adapter when it is executed. Because the XML you add to the <DefaultConfigurations> section is not likely to be part of the declared schema, you can ignore any XML errors it generates.

    There are other examples of configuration files in the following path based on your installation directory: Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\DataCollectors.

    For more information about how to configure your test settings to use an environment when you run your tests, see Create Test Settings for Manual Tests or Create Test Settings for Automated Tests as Part of a Test Plan.

    For more information about installing the configuration file, see How to: Install a Custom Diagnostic Data Adapter

  12. Build your solution to create your diagnostic data adapter assembly.

  13. For information about installing your custom editor, see How to: Install a Custom Diagnostic Data Adapter.

  14. For more information about how to configure your test settings to use an environment when you run your tests, see Create Test Settings for Manual Tests or Create Test Settings for Automated Tests as Part of a Test Plan.

  15. To select your diagnostic data adapter, you must first select an existing test settings or create a new one from Microsoft Test Manager or Microsoft Visual Studio 2010. The adapter is displayed on the Data and Diagnostics tab of your test settings with the friendly name that you assigned to the class.

  16. If you are running your tests from Microsoft Test Manager, you can assign these test settings to your test plan before you run your tests, or use the Run with Options command to assign test settings and override test settings. For more information about test settings, see Setting Up Machines and Collecting Diagnostic Information Using Test Settings.

    If you are running your tests from Microsoft Visual Studio 2010, you must set these test settings to be active. For more information about test settings, see Create Test Settings to Run Automated Tests from Visual Studio.

  17. Run your tests using the test settings with your diagnostic data adapter selected.

    The data file that you specified is attached to your test results.

See Also

Tasks

Create Test Settings to Run Automated Tests from Visual Studio

Create Test Settings for Automated Tests as Part of a Test Plan

Create Test Settings for Manual Tests

Reference

DataCollectorConfigurationEditorAttribute

DataCollectionEvents

DataCollector

[T:Microsoft.VisualStudio.TestTools.Execution.DataCollectionSinkT:Microsoft.VisualStudio.TestTools.Execution.DataCollectorTypeUriAttribute]

DataCollectorFriendlyNameAttribute

DataCollectorEnabledByDefaultAttribute

Concepts

Setting Up Machines and Collecting Diagnostic Information Using Test Settings

How to: Create a Custom Editor for Data for Your Diagnostic Data Adapter