बस पूर्णता के लिए, मैं अक्सर सांत्वना आवेदन के रूप में परीक्षण चलाने के लिए, बस क्योंकि मैं इसे बहुत आसान किसी कारण से इस डिबग करने के लिए लगता है चाहते हैं ... सालों से मैंने कुछ छोटे परीक्षण सहायकों को मेरी मदद करने के लिए बनाया है; मुझे लगता है कि आप उन्हें अपने सीआई समाधान के साथ आसानी से उपयोग कर सकते हैं।
मुझे समझ में आता है कि यह आपका प्रश्न पूरी तरह से नहीं है; हालांकि, चूंकि आप सीआई समाधान की तलाश में हैं और दृश्य स्टूडियो का जिक्र करते हैं, इसलिए इसे काफी अच्छी तरह से हल करना चाहिए।
बस आपको यह बताने के लिए, मेरा छोटा ढांचा इस से थोड़ा बड़ा है, लेकिन जो चीजें गायब हैं, उन्हें जोड़ने में काफी आसान है। मूल रूप से जो मैंने छोड़ा वह लॉगिंग के लिए सब कुछ है और तथ्य यह है कि मैं विभिन्न ऐप डोमेन (संभावित डीएलएल संघर्ष और राज्य के कारण) में विभिन्न असेंबली का परीक्षण करता हूं। उस पर और अधिक।
ध्यान देने योग्य एक बात यह है कि मुझे नीचे दी गई प्रक्रिया में कोई अपवाद नहीं है। मेरा मुख्य फोकस समस्या निवारण के दौरान आपके एप्लिकेशन को डीबग करना आसान बनाता है। मेरे पास सीआई के लिए एक अलग (लेकिन समान) कार्यान्वयन है जो मूल रूप से नीचे टिप्पणी बिंदुओं पर प्रयास/पकड़ जोड़ता है।
इस विधि के लिए केवल एक ही पकड़ है: विजुअल स्टूडियो आपके द्वारा संदर्भित सभी असेंबली की प्रतिलिपि नहीं करेगा; यह केवल उन विधानसभाओं की प्रतिलिपि बनाएगा जिन्हें आप कोड में उपयोग करते हैं। इसके लिए एक सरल कामकाज एक विधि (जिसे कभी नहीं कहा जाता है) पेश करना है जो आपके द्वारा परीक्षण किए जा रहे डीएलएल में एक प्रकार का उपयोग करता है। इस तरह, आपकी असेंबली की प्रतिलिपि बनाई जाएगी और सब कुछ अच्छी तरह से काम करेगा।
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...
}
}
}
कैसे इस कोड का उपयोग करने के लिए: सभी विधानसभाओं, संदर्भित विधानसभाओं, परोक्ष रूप से संदर्भित विधानसभाओं, परीक्षण करने के लिए
- आप बस
TestHelpers.TestAll()
कॉल कर सकते हैं आदि यह शायद क्या है कोड यह आप सीआई में करना चाहते हैं।
- आप सभी संदर्भित असेंबली के साथ एक असेंबली का परीक्षण करने के लिए
TestHelpers.TestAll(assembly)
पर कॉल कर सकते हैं। यह तब उपयोगी हो सकता है जब आप एकाधिक असेंबली और/या जब आपका डिबगिंग में परीक्षण विभाजित कर रहे हों।
- आप एक ही ऑब्जेक्ट में सभी परीक्षणों को आमंत्रित करने के लिए
new MyObject().TestAll()
पर कॉल कर सकते हैं। डिबगिंग करते समय यह विशेष रूप से सहायक होता है।
यदि आप मेरे जैसे एपडोमेन का उपयोग कर रहे हैं, तो आपको एक डीएलएल के लिए एक एकल एपडोमेन बनाना चाहिए जो आप किसी फ़ोल्डर से गतिशील रूप से लोड करते हैं और उस पर TestAll का उपयोग करते हैं। साथ ही, यदि आप स्क्रैच फ़ोल्डर का उपयोग करते हैं, तो आप परीक्षणों के बीच खाली करना चाहेंगे। इस तरह, एकाधिक परीक्षण फ्रेमवर्क संस्करण और एकाधिक परीक्षण एक दूसरे के साथ बातचीत नहीं करेंगे।विशेष रूप से यदि आपके परीक्षण राज्य (उदा। स्थिर चर) का उपयोग करते हैं, तो यह एक अच्छा अभ्यास हो सकता है। CreateInstanceAndUnwrap
ऑनलाइन के लिए कई उदाहरण हैं जो आपको इससे मदद करेंगे।
ध्यान देने योग्य एक बात यह है कि मैं method.Invoke
के बजाय एक प्रतिनिधि का उपयोग करता हूं। इसका मूल रूप से मतलब है कि आपकी अपवाद वस्तु प्रतिबिंब द्वारा नहीं खाई जाएगी, जिसका अर्थ है कि आपका डीबगर टूटा नहीं जाएगा। यह भी ध्यान रखें कि मैं नाम से गुणों की जांच करता हूं, जिसका अर्थ यह है कि यह अलग-अलग ढांचे के साथ काम करेगा - जब तक विशेषता नाम मेल खाते हैं।
एचटीएच
हां। लेकिन मुझे 1 रिपोर्ट चाहिए। – Nahum
-1 देने वाले लोगों के लिए, क्या आप इस कारण पर टिप्पणी कर सकते हैं ताकि मुझे जवाब में सुधार करने का मौका मिले? – jessehouwing
मुझे डर है कि वे सिर्फ बक्षीस के लिए लड़ते हैं। मैंने पहले इस व्यवहार को देखा था। – Nahum