私はちょうどこれを経験しました。私たちの VSMDI はいくつかのリストを定義し、約 2500 のテストをカバーしました。残念ながら、ワンストップ ユーティリティを見つけることができませんでしたが、既存のテスト リスト移行ツールと組み合わせて、すばやく汚れたコンソール アプリを使用してなんとかやり遂げることができました: http://testlistmigration.codeplex.com/
この拡張機能は、完全なテスト名を持つ smiple XML 構造である vsmdi からテスト プレイ リストを生成します。私のユーティリティは、再生リストの XML を HeapSet に読み込み、ディレクトリ内の各テスト ファイルを反復処理し、[TestMethod] で始まる各メソッドを解析し、再生リストで参照されているかどうかを確認し、参照されている場合はテスト カテゴリ属性を追加します。醜いですが、うまくいき、約1時間で書きました。
これが 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());
}
}
}
}
}
}
}