【问题标题】:How can I set the culture for individual MSTest test method(s)?如何为单个 MSTest 测试方法设置区域性?
【发布时间】:2015-09-03 18:21:34
【问题描述】:

最近发现一个错误是由于在将文本解析为数字时未指定InvariantCulture,我想加强我们的单元测试,以便他们能够发现问题。我编写了一个新测试,将当前文化更改为具有不同数字格式的文化,重新运行其中一种现有测试方法,然后将文化重新设置。不幸的是,文化变化也影响了其他测试方法。有没有办法做到这一点,使测试不交互?
我确实发现将文化设置测试放在文件的最后会“解决”问题,但我讨厌依赖测试顺序,因为它不能保证。 在以下示例中,如果系统文化为 "en-EN"TestMethod1TestMethod2,如果它们自己运行将成功。如果我同时运行所有方法,它们都会失败。

   [TestClass]
   public class UnitTest1
   {
      [TestMethod]
      public void TestMethodGerman()
      {
         var originalCulture = Thread.CurrentThread.CurrentCulture;
         Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
         TestMethod1();
         Thread.CurrentThread.CurrentCulture = originalCulture;
      }
      [TestMethod]
      public void TestMethod1()
      {
         double value = Double.Parse("3.00");
         Assert.AreEqual(value, 3.0);
      }

      [TestMethod]
      public void TestMethod2()
      {
         double value = Double.Parse("4.00");
         Assert.AreEqual(value, 4.0);
      }
   }

【问题讨论】:

    标签: c# unit-testing mstest cultureinfo


    【解决方案1】:
    [TestMethod]
    public void FooTest()
    {
        var foo = new Foo();
        var actual = ExecuteWithCulture(() => foo.Bar(), "en-US");
    }
    
    private T ExecuteWithCulture<T>(Func<T> methodFunc, string cultureName)
    {
        T result = default(T);
    
        var thread = new Thread(() =>
        {
            result = methodFunc();
        });
    
        thread.CurrentCulture = new CultureInfo(cultureName);
        thread.Start();
        thread.Join();
    
        return result;
    }
    

    【讨论】:

    • 为什么要为此使用任务?为什么要更改线程池线程的文化而不重置它?这可能会导致“有趣”的行为
    • 好点!你知道更好/更简单的线程方法吗?
    • 为什么要使用不同的线程?这不是关于多线程的问题
    • 如果单元测试是并行运行的,John 的回答是不够的。测试会间歇性地失败。使用线程是唯一可靠的方法。
    • 首先,没有人询问并行运行测试。其次,约翰的回答只是用 try/catch 包装了一个方法。测试运行程序将调用 wrapper。即使测试并行运行,该代码也可以工作,因为测试线程是相同的/添加另一个线程对此没有任何帮助。
    【解决方案2】:

    德国人对TestMethod1 的调用失败,这导致重置文化的行永远不会被执行。将该行放在 finally 块中,测试应该按预期执行:

    var originalCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
    try
    {
        TestMethod1();
    }
    finally
    {
        Thread.CurrentThread.CurrentCulture = originalCulture;
    }
    

    【讨论】:

    • 您肯定需要答案中提到的 try/finally 以确保重置文化,但我认为您可能仍然会遇到使用意外文化运行的测试的问题。 MSTest 并行运行测试,我很确定它不会为每个测试启动一个新线程,而是有一些方法可以在一个线程上分派多个测试。我想你将不得不尝试 try/finally 看看你的问题是否消失,但如果没有,我认为我提到的将是你问题的根源。据我所知,没有办法强制 MSTest 按顺序运行测试。
    • 我相信 MSTest 仅在您 explicitly enable it 时才并行运行,但要指出的是,这容易出错。最好分离另一个线程来完成这项工作,这样它就可以被隔离和控制。
    • 认为该链接包含来自 VS2010 的旧信息。在 VS2013(可能是 VS2015)中,它默认并行运行测试。我不确定配置设置事件是否仍然存在。
    • 据我所知,设置文件可能有所不同,但MSTest中并行测试的限制仍然存在。从今年 8 月开始有 cmets 对此用户语音请求:visualstudio.uservoice.com/forums/121579-visual-studio/…
    • try/finally 是我需要的,谢谢。至于并行运行任务,我不应该担心在其他线程上运行的测试,因为我只是为当前线程设置文化。即使测试是并行的并且不是每个测试运行一个线程(通常每个内核 1 个线程),我仍然希望每个线程在任何给定时间只运行一个测试。考虑到发明某种子线程调度以在一个线程上交错多个测试的工作量,以及如果他们这样做可能会中断的测试数量,我不希望微软这样做。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多