1

我正在将几个大型解决方案从 Visual Studio 2010 升级到 Visual Studio 2012。现在我想删除用于单元测试的 .vsmdi 文件。我想使用新的 TestCategory 属性。

是否可以根据 vsmdi 文件中的列表生成测试方法上方的测试类别?因此,在示例中,我有列表“Shoppingcart”和“Nightly”,如果测试在该 vsmdi 列表中,则类别设置在方法上方。

一个简单的查找替换(每个列表多次?)也是一个很好的解决方案。问题是我们有几千个测试应该放置一个或多个类别。

谢谢

4

1 回答 1

3

我刚刚经历了这个。我们的 VSMDI 定义了几个列表并涵盖了大约 2500 个测试。不幸的是,我找不到一站式实用程序,但我确实设法通过一个快速而肮脏的控制台应用程序结合现有的测试列表迁移工具来完成它:http: //testlistmigration.codeplex.com/

此扩展将从 vsmdi 生成测试播放列表,vsmdi 是一个带有完整测试名称的简单 XML 结构。我的实用程序将播放列表 XML 读入 HeapSet,然后迭代目录中的每个测试文件,解析以 [TestMethod] 开头的每个方法,检查它是否在播放列表中被引用,如果是,则添加测试类别属性。它很丑,但它有效,我在大约一个小时内写了它。

这是 C# 代码……请记住,它是仓促编写的,不考虑美学或最佳实践。它解决了我的问题,如果不是因为这篇文章,它会被扔掉:)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using TestListMigration.Properties;

namespace TestListMigration
{
    class Program
    {
        static void Main(string[] args)
        {
            HashSet<string> tests = new HashSet<string>();
            XmlDocument doc = new XmlDocument();
            doc.Load(Settings.Default.Playlist);
            XmlElement root = doc.DocumentElement;
            XmlNodeList nodes = root.SelectNodes("Add");
            foreach (XmlNode node in nodes)
            {
                tests.Add(node.Attributes["Test"].Value);
            }
            DirectoryInfo di = new DirectoryInfo(Settings.Default.TestPath);
            foreach (FileInfo file in di.GetFiles("*.cs",SearchOption.AllDirectories))
            {
                var testFileReader =file.OpenText();
                string fileContent = testFileReader.ReadToEnd();
                testFileReader.Close();
                bool dirty = false;
                var namespaceMatch = Regex.Match(fileContent, @"namespace ([a-zA-Z\.]*)");
                if (namespaceMatch.Success){
                    string namespaceName = namespaceMatch.Groups[1].Value;
                    var classNameMatch = Regex.Match(fileContent, @"[\n\r\t ]*(public|internal|public sealed) class ([a-zA-Z0-9\.]*)");
                    if (classNameMatch.Success)
                    {
                        string className = classNameMatch.Groups[2].Value;
                        StringBuilder newFile = new StringBuilder();
                        StringReader reader = new StringReader(fileContent);
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            newFile.AppendLine(line);
                            if (line.Contains("[TestMethod]") || line.Contains("[TestMethod()]"))
                            {
                                bool methodLineRead = false;
                                StringBuilder buffer = new StringBuilder();
                                while (!methodLineRead)
                                {
                                    line = reader.ReadLine();
                                    buffer.AppendLine(line);
                                    if (line.Contains("void")){
                                        methodLineRead=true;
                                        var testNameMatch = Regex.Match(line, @"[\n\r\t ]*public void ([a-zA-Z\._0-9]*)\(\)");
                                        if (testNameMatch.Success)
                                        {
                                            string fullName = namespaceName + "." + className + "." + testNameMatch.Groups[1].Value;
                                            if (tests.Contains(fullName) && !buffer.ToString().Contains("\t\t[TestCategory(Category." + Settings.Default.Category + ")]"))
                                            {
                                                newFile.AppendLine("\t\t[TestCategory(Category." + Settings.Default.Category + ")]");
                                                dirty = true;
                                            }
                                        }
                                    }
                                }
                                newFile.Append(buffer.ToString());
                            }
                        }
                        if (dirty)
                        {
                            File.WriteAllText(file.FullName, newFile.ToString());
                        }
                    }
                }
            }
        }
    }
}
于 2013-08-30T21:46:59.447 回答