【问题标题】:How to run the same testmethods while only changing the dependencies?如何在仅更改依赖项的同时运行相同的测试方法?
【发布时间】:2011-01-08 13:52:43
【问题描述】:

我有 5 个测试方法来测试 PasswordManager 对象的功能。我使用 Visual Studio 2008 的内置测试引擎。该管理器可以使用两个依赖项:XMLStorageManager 或 DbStorageManager。依赖项在 Passwordmanager 的构造函数中设置。我如何才能运行两次测试,唯一的区别是我使用的 StorageManager 类型?

(我知道,我知道,这些不是单元测试......)

【问题讨论】:

    标签: .net visual-studio-2008 testing dependencies


    【解决方案1】:

    我不是 MSTest 用户,但您可能有一些选择。通常对于 NUnit,我会使用通用或参数化的夹具,但我不确定 MSTest 是否具有类似的功能。鉴于此,这就是我使用 NUnit 执行此操作的方法,其形式应该可以通过 template method pattern 使用任何单元测试框架重现。

    步骤:

    • 定义一个抽象基类 里面的所有测试
    • 放入一个 抽象方法称为 返回的 CreateStorageManager() 一个 IStorageManager (或其他 接口两个依赖项 实施)
    • 两次子类化夹具 并提供一个实现 CreateStorageManager() 返回您希望用于运行测试的具体类型。

    这是等效 NUnit 版本的代码;我相信你可以推断。 注意: MSTest 的继承规则可能与我习惯的略有不同。如果它不起作用,您可以尝试将基类标记为测试夹具。

    public abstract class PasswordManagerFixtureBase
    {
         protected abstract IStorageManager CreateStorageManager();
    
         // all tests go in this fixture
         [Test]
         public void SomeTestOrOther()
         { 
             var passwordManager = CreatePasswordManager();
    
             // do test logic
    
         }
    
         private PasswordManager CreatePasswordManager()
         { 
              // calls into subclass implementation to get instance of storage
              IStorageManager storage = CreateStorageManager();
              return new PasswordManager(storage);
         }   
    }
    
    // Runs the tests in the fixture base using XmlStorageManager
    [TestFixture]
    public class PasswordManager_XMLStorageManagerImplTests
    {
          protected override IStorageManager CreateStorageManager()
          {
              return new XMLStorageManager();
          }
    }
    
    // Runs the tests in the fixture base using DbStorageManager
    [TestFixture]
    public class PasswordManager_DbStorageManagerImplTests
    {
          protected override IStorageManager CreateStorageManager()
          {
              return new DbStorageManager();
          }
    }
    

    使用 MSTest 可能有更优雅的方法来执行此操作,但这应该可行。

    【讨论】:

    • 这应该是正确的方法,但是来自基类的测试没有运行。
    • 尝试将基类标记为测试夹具,看看是否可行:o MSTest 中的继承规则总是有可能与 NUnit 不同,因为即使 NUnit 本身在版本之间也改变了其行为。
    • 我只是在原始测试之前添加了abstract关键字,然后让VS构造一个新的空测试类,然后我将其继承基类。这应该具有基类中的测试运行的效果。但他们没有。我现在可以做的当然是使用 base.Test1() 等调用测试。这确实节省了一些空间,但当然仍然是复制和粘贴。
    • 我过去曾使用过类似的东西,并且效果很好,但我不记得细节了。
    • 你用 NUnit 2.5.3 试过了吗?请参阅发行说明:nunit.org/index.php?p=releaseNotes&r=2.5.3
    【解决方案2】:

    如果 PasswordManager 具有像 IStorageManager 这样的依赖项,它正在被注入(DI、IoC 等),那么模拟这个接口而不是使用具体实现就足够了,因此不需要测试 @987654323 @ 用于 XML 和 Db 实现,可以与 PasswordManager 分开测试。

    【讨论】:

    • 谢谢,这就是它在纯单元测试中的完成方式。我仍然有兴趣按照我的要求对其进行测试。
    【解决方案3】:

    只是一个想法,但您也许可以创建一个有序的测试并添加两次相同的测试:一次添加所有测试,然后以相同的顺序再次添加所有测试。在您的测试上下文中,记录每个测试已运行的次数。我相信上下文是静态的,所以它应该只创建一次,然后在运行更多测试时重用。在测试设置中,如果测试计数为偶数,则使用 XmlStorageManager;如果该测试的测试计数为奇数,则使用 DbStorageManager

    【讨论】:

      猜你喜欢
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多