2014-09-20 5 views
17

ऐसा लगता है कि मैं समाधान में मेरे सारे परीक्षण कमांड लाइन से एक ही बार में MSTest का उपयोग कर अगर मैं/testmetadata ध्वज का उपयोग के रूप में यहाँ वर्णित चला सकते हैं: http://msdn.microsoft.com/en-us/library/ms182487.aspxसमाधान में सभी परीक्षण चलाने के लिए कैसे

मैं विजुअल स्टूडियो 2013 में SQL सर्वर डीबी यूनिट परीक्षण चला रहा है, जिसमें मुझे एक बनामडीडी फ़ाइल नहीं लगती है, और मैं एक को जोड़ने का कोई तरीका नहीं ढूंढ पा रहा हूं। मैंने एक testettings फ़ाइल बनाने की कोशिश की, लेकिन जब मैं एमएसटीएस्ट का आह्वान करता हूं तो यह किसी भी परीक्षण ("चलाने के लिए कोई परीक्षण नहीं" दिखाता है)।

क्या कोई तरीका है कि मैं अपने सभी परीक्षणों को वीएस2013 समाधान में चला सकता हूं?

उत्तर

12

मैं इस खुले प्रश्न को बंद करना चाहता था। मेरा इरादा हडसन सीआई सर्वर से बाहर जाने के सभी परीक्षणों को चलाने के लिए था, इसलिए मैंने समाधान फ़ोल्डर के अंदर सभी डीएलएल फाइलों पर एमएसटीएस्ट को खोजने और आमंत्रित करने के लिए एक बुनियादी कंसोल ऐप लिखा था। परियोजना को रिहाई मोड में बनाया जाने के बाद यह ऐप निष्पादित किया जाता है।

string execId = null; 
string className = null; 
string testName = null; 
string testResult = null; 
string resultLine = null; 
List<string> results = new List<string>(); 
XmlDocument resultsDoc = new XmlDocument(); 
XmlNode executionNode = null; 
XmlNode testMethodNode = null; 

// Define the test instance settings 
Process testInstance = null; 
ProcessStartInfo testInfo = new ProcessStartInfo() 
{ 
    UseShellExecute = false, 
    CreateNoWindow = true, 
}; 

// Fetch project list from the disk 
List<string> excluded = ConfigurationManager.AppSettings["ExcludedProjects"].Split(',').ToList(); 
DirectoryInfo assemblyPath = new DirectoryInfo(Assembly.GetExecutingAssembly().Location); 
DirectoryInfo[] directories = assemblyPath.Parent.Parent.Parent.Parent.GetDirectories(); 

// Create a test worklist 
List<string> worklist = directories.Where(t => !excluded.Contains(t.Name)) 
            .Select(t => String.Format(ConfigurationManager.AppSettings["MSTestCommand"], t.FullName, t.Name)) 
            .ToList(); 

// Start test execution 
Console.WriteLine("Starting Execution..."); 
Console.WriteLine(); 

Console.WriteLine("Results    Top Level Tests"); 
Console.WriteLine("-------    ---------------"); 

// Remove any existing run results 
if (File.Exists("UnitTests.trx")) 
{ 
    File.Delete("UnitTests.trx"); 
} 

// Run each project in the worklist 
foreach (string item in worklist) 
{ 
    testInfo.FileName = item; 
    testInstance = Process.Start(testInfo); 
    testInstance.WaitForExit(); 

    if (File.Exists("UnitTests.trx")) 
    { 
     resultsDoc = new XmlDocument(); 
     resultsDoc.Load("UnitTests.trx"); 

     foreach (XmlNode result in resultsDoc.GetElementsByTagName("UnitTestResult")) 
     { 
      // Get the execution ID for the test 
      execId = result.Attributes["executionId"].Value; 

      // Find the execution and test method nodes 
      executionNode = resultsDoc.GetElementsByTagName("Execution") 
             .OfType<XmlNode>() 
             .Where(n => n.Attributes["id"] != null && n.Attributes["id"].Value.Equals(execId)) 
             .First(); 

      testMethodNode = executionNode.ParentNode 
              .ChildNodes 
              .OfType<XmlNode>() 
              .Where(n => n.Name.Equals("TestMethod")) 
              .First(); 

      // Get the class name, test name and result 
      className = testMethodNode.Attributes["className"].Value.Split(',')[0]; 
      testName = result.Attributes["testName"].Value; 
      testResult = result.Attributes["outcome"].Value; 
      resultLine = String.Format("{0}    {1}.{2}", testResult, className, testName); 

      results.Add(resultLine); 
      Console.WriteLine(resultLine); 
     } 

     File.Delete("UnitTests.trx"); 
    } 
} 

// Calculate passed/failed test case count 
int passed = results.Where(r => r.StartsWith("Passed")).Count(); 
int failed = results.Where(r => r.StartsWith("Failed")).Count(); 

// Print the summary 
Console.WriteLine(); 
Console.WriteLine("Summary"); 
Console.WriteLine("-------"); 
Console.WriteLine("Test Run {0}", failed > 0 ? "Failed." : "Passed."); 
Console.WriteLine(); 

if (passed > 0) 
    Console.WriteLine("\tPassed {0,7}", passed); 

if (failed > 0) 
    Console.WriteLine("\tFailed {0,7}", failed); 

Console.WriteLine("\t--------------"); 
Console.WriteLine("\tTotal {0,8}", results.Count); 

if (failed > 0) 
    Environment.Exit(-1); 
else 
    Environment.Exit(0); 

मेरे App.config फ़ाइल:

<appSettings> 
    <add key="ExcludedProjects" value="UnitTests.Bootstrap,UnitTests.Utils" /> 
    <add key="MSTestCommand" value="&quot;c:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\MSTest.exe&quot; /testcontainer:&quot;{0}\bin\Release\{1}.dll&quot; /nologo /resultsfile:&quot;UnitTests.trx&quot;" /> 
</appSettings> 
0

अपने स्वयं के लिंक में सावधानी बरतें। यह अब VST 2012 में आपके द्वारा किए जाने वाले तरीके से समर्थित नहीं है।

हो सकता है कि इस अद्यतन संस्करण में मदद कर सकते हैं: http://msdn.microsoft.com/en-us/library/ms182490.aspx

5

MSTest "पदावनत" दृश्य स्टूडियो 2013 यह अभी भी परीक्षण के कुछ प्रकार के लिए प्रयोग किया जाता है की कसौटी पर ढांचे की तरह है, लेकिन अन्य परीक्षण के कई किया जा सकता है निष्पादित अब नए एग्इल टेस्ट रनर में रहते हैं। अब एसक्यूएल डाटाबेस यूनिट टेस्ट अभी भी "कुछ प्रकार" श्रेणी में हैं और उन्हें MsTest.exe के माध्यम से निष्पादित करने की आवश्यकता है।

/TestContainer commandline switch का उपयोग करने का सबसे आसान तरीका है और अपनी परीक्षण परियोजनाओं के लिए नामकरण पैटर्न का उपयोग करना है। इस तरह आप सभी विधानसभाओं को एक विशिष्ट नामकरण पैटर्न के साथ जल्दी से पकड़ सकते हैं और फिर उन्हें एमएसटेस्ट को खिला सकते हैं। सरल पावरहेल कमांड का उपयोग उन सभी फ़ाइलों को पकड़ने के लिए किया जा सकता है जो आपके पैटर्न का पालन करते हैं और फिर उन्हें कमांडलाइन पर खिलाते हैं।

बनामडीडी अभी भी विजुअल स्टूडियो 2013 में काम करेगा, लेकिन संपादक को टूल से हटा दिया गया है, इसके अलावा अब इसके लिए कोई टेम्पलेट नहीं है। तो इसका उपयोग करना बहुत मुश्किल है। यह माइक्रोसॉफ्ट क्या VSDMI के बारे में क्या कहना है:

सावधानी टेस्ट सूचियों नहीं रह गया है पूरी तरह से दृश्य स्टूडियो 2012 में समर्थित हैं:

  • आप नए परीक्षण सूचियां नहीं बना सकते।
  • आप विजुअल स्टूडियो के भीतर से टेस्ट सूची परीक्षण नहीं चला सकते हैं।
  • यदि आपने विजुअल स्टूडियो 2010 से अपग्रेड किया है, और आपके समाधान में परीक्षण सूची है, तो आप इसे विजुअल स्टूडियो में संपादित करना जारी रख सकते हैं।
  • ऊपर वर्णित अनुसार, आप कमांड लाइन से mstest.exe का उपयोग करके परीक्षण सूची जारी रखना जारी रख सकते हैं।
  • यदि आप अपनी बिल्ड परिभाषा में एक परीक्षण सूची का उपयोग कर रहे थे, तो आप इसका उपयोग जारी रख सकते हैं।

मूल रूप से वे इस तकनीक का इस्तेमाल रोकने के लिए और परीक्षण समूहों पर अमल करने के लिए आसान बनाने के लिए TestCategory के के संयोजन का उपयोग करने के लिए आपको बता रहे हैं।

आप परीक्षण कंटेनरों के लिए एक से अधिक पैरामीटर जोड़ सकते हैं के रूप में, आप सभी समूह उन्हें एक कॉल में कर सकते हैं:

/testcontainer:[file name]  Load a file that contains tests. You can 
            Specify this option more than once to 
            load multiple test files. 
            Examples: 
            /testcontainer:mytestproject.dll 
            /testcontainer:loadtest1.loadtest 

MsTest /testcontainer:assemblyone.dll /testcontainer:assemblytwo.dll /testcontainer:assembly3.dll 

ही बार में कई विधानसभाओं पर MSTest चलाने के लिए। और (अभी तक) XUnit .NET या NUnit का उपयोग न करें, क्योंकि इन्हें नए एग्इल परीक्षण धावक पर स्विच किए बिना एक रिपोर्ट में जोड़ा नहीं जा सकता है।

+0

हां। लेकिन मुझे 1 रिपोर्ट चाहिए। – Nahum

+0

-1 देने वाले लोगों के लिए, क्या आप इस कारण पर टिप्पणी कर सकते हैं ताकि मुझे जवाब में सुधार करने का मौका मिले? – jessehouwing

+0

मुझे डर है कि वे सिर्फ बक्षीस के लिए लड़ते हैं। मैंने पहले इस व्यवहार को देखा था। – Nahum

2

मुझे नहीं पता कि यह आपकी मदद करेगा या नहीं, लेकिन मैं Invoke-MsBuild का उपयोग करता हूं। यह एक पावरशेल मॉड्यूल है जो आपको वही करना चाहिए जो आपको चाहिए। मुझे नहीं पता कि क्या आप पावरशेल समाधान की तलाश में थे या नहीं, लेकिन यह बहुत अच्छा काम करता है!

इसमें एमएसबिल्ड के बजाय एमएसटेस्ट चलाने के लिए एक बहन स्क्रिप्ट, Invoke-MsTest भी है।

2

बस पूर्णता के लिए, मैं अक्सर सांत्वना आवेदन के रूप में परीक्षण चलाने के लिए, बस क्योंकि मैं इसे बहुत आसान किसी कारण से इस डिबग करने के लिए लगता है चाहते हैं ... सालों से मैंने कुछ छोटे परीक्षण सहायकों को मेरी मदद करने के लिए बनाया है; मुझे लगता है कि आप उन्हें अपने सीआई समाधान के साथ आसानी से उपयोग कर सकते हैं।

मुझे समझ में आता है कि यह आपका प्रश्न पूरी तरह से नहीं है; हालांकि, चूंकि आप सीआई समाधान की तलाश में हैं और दृश्य स्टूडियो का जिक्र करते हैं, इसलिए इसे काफी अच्छी तरह से हल करना चाहिए।

बस आपको यह बताने के लिए, मेरा छोटा ढांचा इस से थोड़ा बड़ा है, लेकिन जो चीजें गायब हैं, उन्हें जोड़ने में काफी आसान है। मूल रूप से जो मैंने छोड़ा वह लॉगिंग के लिए सब कुछ है और तथ्य यह है कि मैं विभिन्न ऐप डोमेन (संभावित डीएलएल संघर्ष और राज्य के कारण) में विभिन्न असेंबली का परीक्षण करता हूं। उस पर और अधिक।

ध्यान देने योग्य एक बात यह है कि मुझे नीचे दी गई प्रक्रिया में कोई अपवाद नहीं है। मेरा मुख्य फोकस समस्या निवारण के दौरान आपके एप्लिकेशन को डीबग करना आसान बनाता है। मेरे पास सीआई के लिए एक अलग (लेकिन समान) कार्यान्वयन है जो मूल रूप से नीचे टिप्पणी बिंदुओं पर प्रयास/पकड़ जोड़ता है।

इस विधि के लिए केवल एक ही पकड़ है: विजुअल स्टूडियो आपके द्वारा संदर्भित सभी असेंबली की प्रतिलिपि नहीं करेगा; यह केवल उन विधानसभाओं की प्रतिलिपि बनाएगा जिन्हें आप कोड में उपयोग करते हैं। इसके लिए एक सरल कामकाज एक विधि (जिसे कभी नहीं कहा जाता है) पेश करना है जो आपके द्वारा परीक्षण किए जा रहे डीएलएल में एक प्रकार का उपयोग करता है। इस तरह, आपकी असेंबली की प्रतिलिपि बनाई जाएगी और सब कुछ अच्छी तरह से काम करेगा।

static class TestHelpers 
{ 
    public static void TestAll(this object o) 
    { 
     foreach (MethodInfo meth in o.GetType().GetMethods(). 
      Where((a) => a.GetCustomAttributes(true). 
       Any((b) => b.GetType().Name.Contains("TestMethod")))) 
     { 
      Console.WriteLine(); 
      Console.WriteLine("--- Testing {0} ---", meth.Name); 
      Console.WriteLine(); 

      // Add exception handling here for your CI solution. 
      var del = (Action)meth.CreateDelegate(typeof(Action), o); 
      del(); 

      // NOTE: Don't use meth.Invoke(o, new object[0]); ! It'll eat your exception! 

      Console.WriteLine(); 
     } 
    } 

    public static void TestAll(this Assembly ass) 
    { 
     HashSet<AssemblyName> visited = new HashSet<AssemblyName>(); 
     Stack<Assembly> todo = new Stack<Assembly>(); 
     todo.Push(ass); 

     HandleStack(visited, todo); 

    } 

    private static void HandleStack(HashSet<AssemblyName> visited, Stack<Assembly> todo) 
    { 
     while (todo.Count > 0) 
     { 
      var assembly = todo.Pop(); 

      // Collect all assemblies that are related 
      foreach (var refass in assembly.GetReferencedAssemblies()) 
      { 
       TryAdd(refass, visited, todo); 
      } 

      foreach (var type in assembly.GetTypes(). 
       Where((a) => a.GetCustomAttributes(true). 
        Any((b) => b.GetType().Name.Contains("TestClass")))) 
      { 
       // Add exception handling here for your CI solution. 
       var obj = Activator.CreateInstance(type); 
       obj.TestAll(); 
      } 
     } 
    } 

    public static void TestAll() 
    { 
     HashSet<AssemblyName> visited = new HashSet<AssemblyName>(); 
     Stack<Assembly> todo = new Stack<Assembly>(); 

     foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
     { 
      TryAdd(assembly.GetName(), visited, todo); 
     } 

     HandleStack(visited, todo); 
    } 

    private static void TryAdd(AssemblyName ass, HashSet<AssemblyName> visited, Stack<Assembly> todo) 
    { 
     try 
     { 
      var reference = Assembly.Load(ass); 

      if (reference != null && 
       !reference.GlobalAssemblyCache &&   // Ignore GAC 
       reference.FullName != null && 
       !reference.FullName.StartsWith("ms") &&  // mscorlib and other microsoft stuff 
       !reference.FullName.StartsWith("vshost") && // visual studio host process 
       !reference.FullName.StartsWith("System")) // System libraries 
      { 
       if (visited.Add(reference.GetName()))  // We don't want to test assemblies twice 
       { 
        todo.Push(reference);     // Queue assembly for processing 
       } 
      } 
     } 
     catch 
     { 
      // Perhaps log something here... I currently don't because I don't care... 
     } 
    } 
} 

कैसे इस कोड का उपयोग करने के लिए: सभी विधानसभाओं, संदर्भित विधानसभाओं, परोक्ष रूप से संदर्भित विधानसभाओं, परीक्षण करने के लिए

  1. आप बस TestHelpers.TestAll() कॉल कर सकते हैं आदि यह शायद क्या है

    कोड यह आप सीआई में करना चाहते हैं।

  2. आप सभी संदर्भित असेंबली के साथ एक असेंबली का परीक्षण करने के लिए TestHelpers.TestAll(assembly) पर कॉल कर सकते हैं। यह तब उपयोगी हो सकता है जब आप एकाधिक असेंबली और/या जब आपका डिबगिंग में परीक्षण विभाजित कर रहे हों।
  3. आप एक ही ऑब्जेक्ट में सभी परीक्षणों को आमंत्रित करने के लिए new MyObject().TestAll() पर कॉल कर सकते हैं। डिबगिंग करते समय यह विशेष रूप से सहायक होता है।

यदि आप मेरे जैसे एपडोमेन का उपयोग कर रहे हैं, तो आपको एक डीएलएल के लिए एक एकल एपडोमेन बनाना चाहिए जो आप किसी फ़ोल्डर से गतिशील रूप से लोड करते हैं और उस पर TestAll का उपयोग करते हैं। साथ ही, यदि आप स्क्रैच फ़ोल्डर का उपयोग करते हैं, तो आप परीक्षणों के बीच खाली करना चाहेंगे। इस तरह, एकाधिक परीक्षण फ्रेमवर्क संस्करण और एकाधिक परीक्षण एक दूसरे के साथ बातचीत नहीं करेंगे।विशेष रूप से यदि आपके परीक्षण राज्य (उदा। स्थिर चर) का उपयोग करते हैं, तो यह एक अच्छा अभ्यास हो सकता है। CreateInstanceAndUnwrap ऑनलाइन के लिए कई उदाहरण हैं जो आपको इससे मदद करेंगे।

ध्यान देने योग्य एक बात यह है कि मैं method.Invoke के बजाय एक प्रतिनिधि का उपयोग करता हूं। इसका मूल रूप से मतलब है कि आपकी अपवाद वस्तु प्रतिबिंब द्वारा नहीं खाई जाएगी, जिसका अर्थ है कि आपका डीबगर टूटा नहीं जाएगा। यह भी ध्यान रखें कि मैं नाम से गुणों की जांच करता हूं, जिसका अर्थ यह है कि यह अलग-अलग ढांचे के साथ काम करेगा - जब तक विशेषता नाम मेल खाते हैं।

एचटीएच

संबंधित मुद्दे

 संबंधित मुद्दे