我正在将几个重要的解决方案从Visual Studio 2010升级到Visual Studio 2012.现在我想删除单元测试的.vsmdi文件。我想使用新的TestCategory属性。
是否可以在vsmdi文件的列表中生成测试方法上方的测试类别?所以在示例中我有“Shoppingcart”和“Nightly”列表,如果测试在vsmdi列表中,则类别设置在方法之上。
一个简单的查找替换(每个列表多次?)也是一个很好的解决方案。问题是我们有几千个测试,其中应该放置一个或多个类别。
感谢
答案 0 :(得分:2)
我刚刚经历过这个。我们的VSMDI定义了几个列表并涵盖了大约2500个测试。遗憾的是,我找不到一站式实用程序,但我确实设法通过一个快速而肮脏的控制台应用程序结合现有的测试列表迁移工具来完成它:http://testlistmigration.codeplex.com/
此扩展将从vsmdi生成测试播放列表,这是一个带有完整测试名称的smiple 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());
}
}
}
}
}
}
}