简体   繁体   English

如何确保覆盖线程代码

[英]How can I ensure coverage of threaded code

I am trying to write a unit test that can hit a piece of threaded code 100% of the time for code coverage. 我正在尝试编写一个单元测试,该测试可以100%地命中一段线程代码来覆盖代码。 The code can ONLY be reached in the context of a threaded application, and is engineered to be hit only once for every object instance in order to minimize lock time expense. 该代码只能在线程应用程序的上下文中访问,并且设计为每个对象实例仅被命中一次,以最大程度地减少锁定时间。

As a simplified example: 作为简化示例:

public class Example
{
  private readonly object lockObject = new object();
  private int? objectToInit = null;

  public void EnsureObjectInit()
  {
    //To minimize hitting the lock code, the object is checked first.
    if (!objectToInit.HasValue)
    {
      lock (lockObject)
      {
        //Then it is checked once more to ensure that it wasn't initiazlized
        //before the lock was hit.
        if (objectToInit.HasValue)
        {
          //This block can only be executed if a second thread is able to
          //get to the lock before the first can initialize the object.

          return; 
        }

        objectToInit = 0;
      }
    }
  }
}

To get code coverage to hit the code inside the second if statement, I've tried code like this: 为了获得覆盖第二个if语句中代码的代码,我尝试了如下代码:

[TestClass]
public class ExampleTest
{
  [Test Method]
  public void async MyTest()
  {
    Example example = new Example();

    void runTask()
    {
      example.EnsureObjectInit();
    }

    //I've tried increasing the number of threads, but it doesn't make
    //it hit the noted code any more consistently.
    List<Task> tasks = new List<Task>(2);
    tasks.Add(Task.Run(runTask));
    tasks.Add(Task.Run(runTask));

    await Task.WhenAll(tasks);
    ... perform extra validation ...
  }
}

But code coverage fails to reach the inner if block at least 50% of the time. 但是,如果至少有50%的时间阻塞,则代码覆盖率无法到达内部。

Is there any way to force the unit tested code to stop the first thread before initializing the object so that the second thread can get into the first "if" block? 有什么方法可以强制经过单元测试的代码在初始化对象之前停止第一个线程,以便第二个线程可以进入第一个“ if”块?

It's a bit of a hack, but you could use reflection to get the lockObject from the Example class instance. 有点lockObject ,但是您可以使用反射从Example类实例获取lockObject Then lock it manually in the ExampleTest method. 然后将其手动锁定在ExampleTest方法中。 NOTE: this is a highly couple test. 注意:这是一个高度耦合的测试。 If you change the name of the lock the test will fail. 如果更改锁的名称,则测试将失败。

    private class LockExample
    {
        private readonly object lockObject = new object();

        public void TestLock()
        {
            lock(lockObject)
            {
                //Do something
            }
        }
    }

    private class LockTest
    {
        public void Test()
        {
            var example = new LockExample();
            var lockOjbect = typeof(LockExample).GetField("lockObject", BindingFlags.NonPublic|BindingFlags.Instance).GetValue(example);
            lock (lockOjbect)
            {
                var task = Task.Run((Action)example.TestLock);
                task.Wait(1);   //allow the other thread to run
            }
        }
    }

With a slight design change you can make your code easier testable: Extract the access to objectToInit.HasValue into a helper method like hasObjectToInitValue() . 有轻微的设计变更可以使你的代码更可测试:提取访问objectToInit.HasValue成一个辅助方法类似hasObjectToInitValue() In your test, you can then override that method and can then test the scenario that the helper method on first call returns false and on second returns true . 在测试中,您可以覆盖该方法,然后可以测试以下情况:助手方法在第一次调用时返回false ,在第二次调用时返回true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对代码覆盖率进行单元测试? - How can I unit test code coverage? 如何获取CSLA调用的代码的代码覆盖率信息? - How can I get code coverage info on code called by CSLA? 如何确保在多线程环境中对StringBuilder对象进行GC? (鉴于我不能使用using关键字)? - How do I ensure that the StringBuilder object is GCed in a multi-threaded environment? (Given that I can't use the using Keyword)? 如何确保完整的单元测试范围? - How do I ensure complete unit test coverage? 如何测量后台程序的代码覆盖率? - How can I measure code coverage for background program? 如何从多个项目获得代码覆盖率 - How can I get code coverage from multiple projects 如何从代码覆盖率中排除属性中的 lambda 函数? - How can I exclude lambda functions in properties from code coverage? 我如何做一个线程客户端套接字 - How can I do a threaded Client socket 如何从开发机器上观察新代码的代码覆盖率 - How can I observe the code coverage on new code from the development machine 如何确保在Visual Studio中完全覆盖本地化资源文件? - How do I ensure full coverage of a localization resource file in Visual Studio?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM