ตรวจสอบว่าโค้ดทำงานเป็นส่วนหนึ่งของการทดสอบหน่วยหรือไม่


105

ฉันมีการทดสอบหน่วย (nUnit) หลายชั้นที่เรียกซ้อนกันวิธีการจะล้มเหลวหากทำงานผ่านการทดสอบหน่วย

ตามหลักการแล้วคุณจะใช้บางอย่างเช่นการเยาะเย้ยเพื่อตั้งค่าวัตถุที่วิธีนี้ขึ้นอยู่กับ แต่นี่เป็นรหัสของบุคคลที่สามและฉันไม่สามารถทำได้โดยไม่ต้องทำงานมาก

ฉันไม่ต้องการตั้งค่าวิธีการเฉพาะ nUnit - ที่นี่มีหลายระดับเกินไปและเป็นวิธีที่ไม่ดีในการทดสอบหน่วย

แต่สิ่งที่ฉันต้องการจะทำคือเพิ่มสิ่งนี้ให้ลึกลงไปใน call stack

#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
   {
   // Do some setup to avoid error
   }
#endif

มีแนวคิดเกี่ยวกับวิธีการเขียน IsRunningInUnitTest อย่างไร?

ปล. ฉันรู้อยู่เต็มอกว่านี่ไม่ใช่การออกแบบที่ยอดเยี่ยม แต่ฉันคิดว่ามันดีกว่าทางเลือกอื่น


5
คุณไม่ควรทดสอบโค้ดของบุคคลที่สามทั้งทางตรงและทางอ้อมในการทดสอบหน่วย คุณควรแยกวิธีการของคุณภายใต้การทดสอบจากการใช้งานของบุคคลที่สาม
Craig Stuntz

14
ใช่ - ฉันรู้ว่า - ในโลกแห่งความคิด แต่บางครั้งเราก็ต้องจริงจังกับสิ่งที่ไม่ใช่?
Ryan

9
กลับมาที่ความคิดเห็นของ Craig - ไม่แน่ใจว่าเป็นความจริง หากวิธีการของฉันอาศัยไลบรารีของบุคคลที่สามที่ทำงานในลักษณะหนึ่งสิ่งนี้ไม่ควรเป็นส่วนหนึ่งของการทดสอบหรือไม่? หากแอปของบุคคลที่สามเปลี่ยนแปลงฉันต้องการให้การทดสอบล้มเหลว หากคุณใช้การทดสอบเยาะเย้ยกับวิธีที่คุณคิดว่าแอปของบุคคลที่สามทำงานไม่ใช่วิธีการจริง
ไรอัน

2
Ryan คุณสามารถทดสอบสมมติฐานเกี่ยวกับพฤติกรรมของบุคคลที่สามได้ แต่นั่นเป็นการทดสอบแยกต่างหาก คุณต้องทดสอบรหัสของคุณเองแยกต่างหาก
Craig Stuntz

2
ฉันเข้าใจในสิ่งที่คุณพูด แต่สำหรับอะไรก็ได้ แต่เป็นตัวอย่างที่ไม่สำคัญที่คุณจะพูดถึงงานจำนวนมาก (มหาศาล) และไม่มีอะไรที่จะทำให้มั่นใจได้ว่าสมมติฐานที่คุณตรวจสอบในการทดสอบของคุณจะเหมือนกับสมมติฐานของคุณในวิธีการจริงของคุณ . อืม - ถกเถียงกันเรื่องโพสต์บล็อกฉันคิดว่าฉันจะยิงอีเมลถึงคุณเมื่อฉันมีความคิดร่วมกัน
Ryan

คำตอบ:


80

ฉันเคยทำสิ่งนี้มาก่อน - ฉันต้องกลั้นจมูกในขณะที่ทำ แต่ฉันทำไปแล้ว ลัทธิปฏิบัตินิยมเอาชนะความเชื่อทุกครั้ง แน่นอนถ้ามีเป็นวิธีที่ดีที่คุณสามารถ refactor จะหลีกเลี่ยงมันว่าจะดี

โดยพื้นฐานแล้วฉันมีคลาส "UnitTestDetector" ซึ่งตรวจสอบว่ามีการโหลดแอสเซมบลี NUnit framework ใน AppDomain ปัจจุบันหรือไม่ จำเป็นต้องทำเพียงครั้งเดียวจากนั้นแคชผลลัพธ์ น่าเกลียด แต่เรียบง่ายและมีประสิทธิภาพ


ตัวอย่างใด ๆ เกี่ยวกับ UnitTestDetector? และคล้ายกันสำหรับ MSTest?
Kiquenet

4
@Kiquenet: ฉันคิดว่าฉันแค่ใช้AppDomain.GetAssembliesและตรวจสอบชุดประกอบที่เกี่ยวข้อง - สำหรับ MSTest คุณต้องดูว่ามีการโหลดชุดประกอบใดบ้าง ดูคำตอบของ Ryan เป็นตัวอย่าง
Jon Skeet

นี่ไม่ใช่แนวทางที่ดีสำหรับฉัน ฉันกำลังเรียกใช้เมธอด UnitTest จากแอปคอนโซลและคิดว่าเป็นแอป UnitTest
Bizhan

1
@ บิซาน: ฉันขอแนะนำให้คุณอยู่ในสถานการณ์ที่ค่อนข้างพิเศษและคุณไม่ควรคาดหวังคำตอบทั่วไปในการทำงาน คุณอาจต้องการถามคำถามใหม่พร้อมข้อกำหนดเฉพาะทั้งหมดของคุณ (ตัวอย่างเช่น "การเรียกรหัสของคุณจากแอปพลิเคชันคอนโซล" และ "นักวิ่งทดสอบ" แตกต่างกันอย่างไรคุณต้องการแยกความแตกต่างระหว่างแอปพลิเคชันคอนโซลของคุณกับนักวิ่งทดสอบที่ใช้คอนโซลอื่น ๆ อย่างไร)
Jon Skeet

74

แนวคิดของจอนนี่คือสิ่งที่ฉันคิดขึ้นมา -

using System;
using System.Reflection;

/// <summary>
/// Detect if we are running as part of a nUnit unit test.
/// This is DIRTY and should only be used if absolutely necessary 
/// as its usually a sign of bad design.
/// </summary>    
static class UnitTestDetector
{

    private static bool _runningFromNUnit = false;      

    static UnitTestDetector()
    {
        foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies())
        {
            // Can't do something like this as it will load the nUnit assembly
            // if (assem == typeof(NUnit.Framework.Assert))

            if (assem.FullName.ToLowerInvariant().StartsWith("nunit.framework"))
            {
                _runningFromNUnit = true;
                break;
            }
        }
    }

    public static bool IsRunningFromNUnit
    {
        get { return _runningFromNUnit; }
    }
}

บีบลงที่ด้านหลังพวกเราทุกคนตัวโตพอที่จะรับรู้เมื่อเราทำบางสิ่งที่เราไม่ควรทำ


2
+1 คำตอบที่ดี สิ่งนี้สามารถทำให้ง่ายขึ้นได้เล็กน้อยดูด้านล่าง: stackoverflow.com/a/30356080/184528
cdiggins

โครงการเฉพาะที่ฉันเขียนสิ่งนี้คือ (และยังคงเป็น!) NET 2.0 ดังนั้นจึงไม่มี linq
Ryan

การใช้งานนี้ได้ผลสำหรับฉัน แต่ดูเหมือนว่าชื่อชุดประกอบจะเปลี่ยนไปตั้งแต่นั้นมา ฉันเปลี่ยนไปใช้โซลูชันของ Kiquenet
The_Black_Smurf

ฉันต้องปิดการบันทึกสำหรับการสร้าง travis ci มันทำให้ทุกอย่างแข็ง
jjxtra

ได้ผลสำหรับฉันฉันต้องแฮ็กจุดบกพร่อง. NET core 3 ด้วยมีดโกนที่เกิดขึ้นในการทดสอบหน่วยเท่านั้น
jjxtra

62

ดัดแปลงมาจากคำตอบของ Ryan อันนี้ใช้สำหรับกรอบการทดสอบหน่วย MS

เหตุผลที่ฉันต้องการเพราะฉันแสดง MessageBox เกี่ยวกับข้อผิดพลาด แต่การทดสอบหน่วยของฉันยังทดสอบรหัสการจัดการข้อผิดพลาดและฉันไม่ต้องการให้กล่องข้อความปรากฏขึ้นเมื่อเรียกใช้การทดสอบหน่วย

/// <summary>
/// Detects if we are running inside a unit test.
/// </summary>
public static class UnitTestDetector
{
    static UnitTestDetector()
    {
        string testAssemblyName = "Microsoft.VisualStudio.QualityTools.UnitTestFramework";
        UnitTestDetector.IsInUnitTest = AppDomain.CurrentDomain.GetAssemblies()
            .Any(a => a.FullName.StartsWith(testAssemblyName));
    }

    public static bool IsInUnitTest { get; private set; }
}

และนี่คือการทดสอบหน่วยสำหรับมัน:

    [TestMethod]
    public void IsInUnitTest()
    {
        Assert.IsTrue(UnitTestDetector.IsInUnitTest, 
            "Should detect that we are running inside a unit test."); // lol
    }

8
ฉันมีวิธีที่ดีกว่าในการแก้ปัญหา MessageBox ของคุณและทำให้แฮ็คนี้เป็นโมฆะและมอบกรณีทดสอบหน่วยเพิ่มเติม ฉันใช้คลาสที่ใช้อินเทอร์เฟซที่ฉันเรียกว่า ICommonDialogs คลาสการใช้งานจะแสดงกล่องโต้ตอบป๊อปอัปทั้งหมด (กล่องข้อความกล่องโต้ตอบไฟล์ตัวเลือกสีกล่องโต้ตอบการเชื่อมต่อฐานข้อมูล ฯลฯ ) คลาสที่ต้องแสดงกล่องข้อความยอมรับ ICommonDiaglogs เป็นพารามิเตอร์ตัวสร้างที่เราสามารถจำลองในการทดสอบหน่วยได้ โบนัส: คุณสามารถยืนยันการโทร MessageBox ที่คาดไว้ได้
Tony O'Hagan

1
@ โทนี่ไอเดียดี นั่นเป็นวิธีที่ดีที่สุดอย่างชัดเจน ฉันไม่รู้ว่าตอนนั้นฉันคิดอะไรอยู่ ฉันคิดว่าการฉีดพึ่งพายังใหม่สำหรับฉันในเวลานั้น
dan-gph

3
ผู้คนอย่างจริงจังเรียนรู้เกี่ยวกับการฉีดพึ่งพาและประการที่สองวัตถุล้อเลียน Dependency injection จะปฏิวัติการเขียนโปรแกรมของคุณ
dan-gph

2
ฉันจะใช้ UnitTestDetector.IsInUnitTest เป็น "return true" และการทดสอบหน่วยของคุณจะผ่านไป ;) หนึ่งในเรื่องตลกที่ดูเหมือนจะเป็นไปไม่ได้ที่จะทดสอบหน่วย
Samer Adra

1
Microsoft.VisualStudio.QualityTools.UnitTestFramework ไม่ทำงานสำหรับฉันอีกต่อไป เปลี่ยนเป็น Microsoft.VisualStudio.TestPlatform.TestFramework ซึ่งใช้งานได้อีกครั้ง
Alexander

22

การทำให้โซลูชันของ Ryan ง่ายขึ้นคุณสามารถเพิ่มคุณสมบัติคงที่ต่อไปนี้ให้กับคลาสใดก็ได้:

    public static readonly bool IsRunningFromNUnit = 
        AppDomain.CurrentDomain.GetAssemblies().Any(
            a => a.FullName.ToLowerInvariant().StartsWith("nunit.framework"));

2
ค่อนข้างเหมือนกับคำตอบของ dan-gph (แม้ว่าจะกำลังมองหาชุดเครื่องมือ VS ไม่ใช่แม่ชี)
Ryan

18

ฉันใช้วิธีการคล้าย ๆ กับ tallseth

นี่คือรหัสพื้นฐานที่สามารถแก้ไขได้อย่างง่ายดายเพื่อรวมแคช ความคิดที่ดีอีกประการหนึ่งคือการเพิ่มตัวตั้งค่าIsRunningInUnitTestและเรียกUnitTestDetector.IsRunningInUnitTest = falseไปยังจุดเริ่มต้นหลักของโครงการของคุณเพื่อหลีกเลี่ยงการเรียกใช้โค้ด

public static class UnitTestDetector
{
    public static readonly HashSet<string> UnitTestAttributes = new HashSet<string> 
    {
        "Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute",
        "NUnit.Framework.TestFixtureAttribute",
    };
    public static bool IsRunningInUnitTest
    {
        get
        {
            foreach (var f in new StackTrace().GetFrames())
                if (f.GetMethod().DeclaringType.GetCustomAttributes(false).Any(x => UnitTestAttributes.Contains(x.GetType().FullName)))
                    return true;
            return false;
        }
    }
}

ฉันชอบแนวทางนี้มากกว่าคำตอบที่ได้รับการโหวตสูงกว่า ฉันไม่คิดว่ามันปลอดภัยที่จะคิดว่าชุดประกอบการทดสอบหน่วยจะถูกโหลดในระหว่างการทดสอบหน่วยเท่านั้นและชื่อกระบวนการอาจแตกต่างกันไปในแต่ละนักพัฒนา (เช่นบางคนใช้ตัวทดสอบ R #)
EM0

วิธีนี้ใช้ได้ผล แต่จะมองหาแอตทริบิวต์เหล่านั้นทุกครั้งที่เรียกIsRunningInUnitTest getter อาจมีบางกรณีที่อาจส่งผลต่อประสิทธิภาพ การตรวจสอบAssemblyNameถูกกว่าเพราะทำเพียงครั้งเดียว แนวคิดกับตัวตั้งค่าสาธารณะเป็นสิ่งที่ดี แต่ในกรณีนี้ควรวางคลาสUnitTestDetectorไว้ในแอสเซมบลีที่ใช้ร่วมกัน
Sergey

13

อาจมีประโยชน์ตรวจสอบ ProcessName ปัจจุบัน:

public static bool UnitTestMode
{
    get 
    { 
        string processName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

        return processName == "VSTestHost"
                || processName.StartsWith("vstest.executionengine") //it can be vstest.executionengine.x86 or vstest.executionengine.x86.clr20
                || processName.StartsWith("QTAgent");   //QTAgent32 or QTAgent32_35
    }
}

และควรตรวจสอบฟังก์ชั่นนี้โดย unittest:

[TestClass]
public class TestUnittestRunning
{
    [TestMethod]
    public void UnitTestRunningTest()
    {
        Assert.IsTrue(MyTools.UnitTestMode);
    }
}

ข้อมูลอ้างอิง:
Matthew Watson ในhttp://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/


|| processName.StartsWith("testhost") // testhost.x86สำหรับ VS 2019
Kiquenet

9

ในโหมดการทดสอบน่าจะเป็นAssembly.GetEntryAssembly()null

#IF DEBUG // Unit tests only included in debug build 
  if (Assembly.GetEntryAssembly() == null)    
  {
    // Do some setup to avoid error    
  }
#endif 

โปรดทราบว่าถ้าAssembly.GetEntryAssembly()เป็นnull,Assembly.GetExecutingAssembly()ไม่ได้

เอกสารกล่าวว่า: ในGetEntryAssemblyวิธีการที่จะสามารถกลับมาnullเมื่อมีการจัดการชุมนุมได้รับการโหลดจากโปรแกรมประยุกต์ที่ไม่มีการจัดการ


8

บางแห่งในโครงการที่กำลังทดสอบ:

public static class Startup
{
    public static bool IsRunningInUnitTest { get; set; }
}

ที่ไหนสักแห่งในโครงการทดสอบหน่วยของคุณ:

[TestClass]
public static class AssemblyInitializer
{
    [AssemblyInitialize]
    public static void Initialize(TestContext context)
    {
        Startup.IsRunningInUnitTest = true;
    }
}

สวยหรูไม่มี. แต่ตรงไปตรงมาและรวดเร็ว AssemblyInitializerใช้สำหรับการทดสอบ MS ฉันคาดหวังว่ากรอบการทดสอบอื่น ๆ จะมีคุณสมบัติเทียบเท่า


1
หากโค้ดที่คุณกำลังทดสอบสร้าง AppDomains เพิ่มเติมIsRunningInUnitTestจะไม่ได้รับการตั้งค่าเป็นจริงใน AppDomains เหล่านั้น
Edward Brey

แต่สามารถแก้ไขได้อย่างง่ายดายโดยการเพิ่มแอสเซมบลีที่ใช้ร่วมกันหรือประกาศIsRunningInUnitTestในแต่ละโดเมน
Sergey

3

ฉันใช้สิ่งนี้เท่านั้นสำหรับการข้ามตรรกะที่ปิดใช้งาน TraceAppenders ทั้งหมดใน log4net ระหว่างการเริ่มต้นเมื่อไม่มีดีบักที่แนบมา สิ่งนี้ช่วยให้การทดสอบหน่วยล็อกไปยังหน้าต่างผลลัพธ์ Resharper แม้ว่าจะทำงานในโหมดไม่แก้ไขจุดบกพร่องก็ตาม

วิธีการที่ใช้ฟังก์ชันนี้เรียกว่าเมื่อเริ่มต้นแอปพลิเคชันหรือเมื่อเริ่มการติดตั้งทดสอบ

คล้ายกับโพสต์ของ Ryan แต่ใช้ LINQ ลดความต้องการ System.Reflection ไม่แคชผลลัพธ์และเป็นแบบส่วนตัวเพื่อป้องกันการใช้ผิดวัตถุประสงค์ (โดยไม่ได้ตั้งใจ)

    private static bool IsNUnitRunning()
    {
        return AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.FullName.ToLowerInvariant().StartsWith("nunit.framework"));
    }

3

การอ้างอิงถึง nunit framework ไม่ได้หมายความว่าการทดสอบกำลังทำงานอยู่ ตัวอย่างเช่นใน Unity เมื่อคุณเปิดใช้งานโหมดเล่นการทดสอบการอ้างอิงแม่ชีจะถูกเพิ่มเข้าไปในโปรเจ็กต์ และเมื่อคุณเรียกใช้เกมการอ้างอิงจะมีอยู่ดังนั้น UnitTestDetector จะทำงานไม่ถูกต้อง

แทนที่จะตรวจสอบการชุมนุมของแม่ชีเราสามารถขอให้แม่ชี api ตรวจสอบว่าเป็นรหัสที่ดำเนินการทดสอบตอนนี้หรือไม่

using NUnit.Framework;

// ...

if (TestContext.CurrentContext != null)
{
    // nunit test detected
    // Do some setup to avoid error
}

แก้ไข:

ระวังว่าTestContext อาจถูกสร้างขึ้นโดยอัตโนมัติหากจำเป็น


2
โปรดอย่าเพิ่งถ่ายโอนรหัสที่นี่ อธิบายว่ามันทำอะไร
nkr


1

ฉันไม่พอใจที่มีปัญหานี้เมื่อเร็ว ๆ นี้ ฉันแก้ไขด้วยวิธีที่แตกต่างกันเล็กน้อย ก่อนอื่นฉันไม่เต็มใจที่จะตั้งสมมติฐานว่ากรอบงานแม่ชีจะไม่ถูกโหลดนอกสภาพแวดล้อมการทดสอบ ฉันกังวลเป็นพิเศษเกี่ยวกับนักพัฒนาที่ใช้แอปบนเครื่องของพวกเขา เลยเดินกองโทรแทน ประการที่สองฉันสามารถตั้งสมมติฐานได้ว่ารหัสทดสอบจะไม่ถูกรันกับไบนารีรุ่นดังนั้นฉันจึงแน่ใจว่าไม่มีรหัสนี้ในระบบรีลีส

internal abstract class TestModeDetector
{
    internal abstract bool RunningInUnitTest();

    internal static TestModeDetector GetInstance()
    {
    #if DEBUG
        return new DebugImplementation();
    #else
        return new ReleaseImplementation();
    #endif
    }

    private class ReleaseImplementation : TestModeDetector
    {
        internal override bool RunningInUnitTest()
        {
            return false;
        }
    }

    private class DebugImplementation : TestModeDetector
    {
        private Mode mode_;

        internal override bool RunningInUnitTest()
        {
            if (mode_ == Mode.Unknown)
            {
                mode_ = DetectMode();
            }

            return mode_ == Mode.Test;
        }

        private Mode DetectMode()
        {
            return HasUnitTestInStack(new StackTrace()) ? Mode.Test : Mode.Regular;
        }

        private static bool HasUnitTestInStack(StackTrace callStack)
        {
            return GetStackFrames(callStack).SelectMany(stackFrame => stackFrame.GetMethod().GetCustomAttributes(false)).Any(NunitAttribute);
        }

        private static IEnumerable<StackFrame> GetStackFrames(StackTrace callStack)
        {
            return callStack.GetFrames() ?? new StackFrame[0];
        }

        private static bool NunitAttribute(object attr)
        {
            var type = attr.GetType();
            if (type.FullName != null)
            {
                return type.FullName.StartsWith("nunit.framework", StringComparison.OrdinalIgnoreCase);
            }
            return false;
        }

        private enum Mode
        {
            Unknown,
            Test,
            Regular
        }

ฉันพบว่าแนวคิดในการทดสอบเวอร์ชันดีบักในขณะที่จัดส่งเวอร์ชันเผยแพร่นั้นเป็นความคิดที่ไม่ดีโดยทั่วไป
Patrick M

1

ใช้งานได้เหมือนมีเสน่ห์

if (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName.ToLowerInvariant().StartsWith("nunit.framework")) != null)
{
    fileName = @"C:\Users\blabla\xxx.txt";
}
else
{
    var sfd = new SaveFileDialog
    {     ...     };
    var dialogResult = sfd.ShowDialog();
    if (dialogResult != DialogResult.OK)
        return;
    fileName = sfd.FileName;
}

.


1

การทดสอบหน่วยจะข้ามจุดเข้าใช้งาน อย่างน้อยสำหรับ wpf main()จะไม่มีการเรียกใช้โปรแกรม winforms และ console

หากเรียกเมธอดหลักเกินกว่าที่เราอยู่ในรันไทม์มิฉะนั้นเราจะอยู่ในโหมดทดสอบหน่วย :

public static bool IsUnitTest { get; private set; } = true;

[STAThread]
public static void main()
{
    IsUnitTest = false;
    ...
}

0

การพิจารณาโค้ดของคุณเป็นเรื่องปกติที่รันในเธรดหลัก (gui) ของแอ็พพลิเคชันฟอร์ม windows และคุณต้องการให้ทำงานแตกต่างกันในขณะที่รันในการทดสอบคุณสามารถตรวจสอบได้

if (SynchronizationContext.Current == null)
{
    // code running in a background thread or from within a unit test
    DoSomething();
}
else
{
    // code running in the main thread or any other thread where
    // a SynchronizationContext has been set with
    // SynchronizationContext.SetSynchronizationContext(synchronizationContext);
    DoSomethingAsync();
}

ฉันใช้สิ่งนี้สำหรับรหัสที่ฉันต้องการfire and forgotในแอปพลิเคชัน gui แต่ในการทดสอบหน่วยฉันอาจต้องการผลลัพธ์ที่คำนวณเพื่อการยืนยันและฉันไม่ต้องการยุ่งกับเธรดหลายชุดที่ทำงานอยู่

ใช้ได้กับ MSTest ข้อดีคือรหัสของฉันไม่จำเป็นต้องตรวจสอบกรอบการทดสอบเองและถ้าฉันต้องการพฤติกรรม async ในการทดสอบบางอย่างฉันสามารถตั้งค่า SynchronizationContext ของฉันเองได้

โปรดทราบว่านี่ไม่ใช่วิธีการที่เชื่อถือDetermine if code is running as part of a unit testได้ตามที่ OP ร้องขอเนื่องจากโค้ดอาจทำงานภายในเธรด แต่สำหรับบางสถานการณ์นี่อาจเป็นทางออกที่ดี (เช่น: หากฉันรันจากเธรดพื้นหลังอยู่แล้วอาจไม่จำเป็น เพื่อเริ่มต้นใหม่)


0

แอปพลิเคชันปัจจุบันเป็นโมฆะเมื่อทำงานภายใต้เครื่องทดสอบหน่วย อย่างน้อยสำหรับแอป WPF ของฉันโดยใช้ MS Unit tester นี่เป็นการทดสอบที่ง่ายหากจำเป็น นอกจากนี้สิ่งที่ควรคำนึงถึงเมื่อใช้แอปพลิเคชันปัจจุบันอยู่ในรหัสของคุณ


0

ฉันใช้สิ่งต่อไปนี้ใน VB ในโค้ดของฉันเพื่อตรวจสอบว่าเราอยู่ในการทดสอบหน่วยหรือไม่ โดยเฉพาะฉันไม่ต้องการให้การทดสอบเปิด Word

    If Not Application.ProductName.ToLower().Contains("test") then
        ' Do something 
    End If

0

วิธีการใช้การสะท้อนและสิ่งนี้:

var underTest = Assembly.GetCallingAssembly ()! = typeof (MainForm) .Assembly;

แอสเซมบลีการโทรจะเป็นกรณีทดสอบของคุณและเพียงแค่แทนที่ MainForm บางประเภทที่อยู่ในโค้ดของคุณที่กำลังทดสอบ


-3

มีวิธีง่ายๆเช่นกันเมื่อคุณกำลังทดสอบชั้นเรียน ...

เพียงแค่ให้คลาสที่คุณกำลังทดสอบคุณสมบัติเช่นนี้:

// For testing purposes to avoid running certain code in unit tests.
public bool thisIsUnitTest { get; set; }

ตอนนี้การทดสอบหน่วยของคุณสามารถตั้งค่าบูลีน "thisIsUnitTest" เป็นจริงได้ดังนั้นในโค้ดที่คุณต้องการข้ามให้เพิ่ม:

   if (thisIsUnitTest)
   {
       return;
   } 

ง่ายและเร็วกว่าการตรวจสอบชุดประกอบ ทำให้ฉันนึกถึง Ruby On Rails ที่คุณต้องการดูว่าคุณอยู่ในสภาพแวดล้อมการทดสอบหรือไม่


1
ฉันคิดว่าคุณถูกโหวตไม่ลงที่นี่เพราะคุณอาศัยการทดสอบเพื่อปรับเปลี่ยนพฤติกรรมของชั้นเรียน
Riegardt Steyn

1
นี่ไม่เลวร้ายไปกว่าคำตอบอื่น ๆ ทั้งหมดในที่นี่
DonO
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.