【问题标题】:How do I write a "pre-test" for more than one sql unit-test in Visual Studio 2013?如何在 Visual Studio 2013 中为多个 sql 单元测试编写“预测试”?
【发布时间】:2014-06-06 12:13:07
【问题描述】:

目前一个 sql 单元测试由 5 个部分组成:

- Pre-Initialise
- Pre-Test
- Test
- Post-Test
- Post-Cleanup

对于我的一些测试,“预测试”部分是相同的,我必须多次复制粘贴预测试代码,重复代码是个坏主意......所以我的问题是是否有如何只在某处编写一次预测试并通过调用单元测试项目中的函数来运行它?

我的测试用例后面的当前 C# 文件示例:

[TestClass()]
public class SqlServerUnitTestAssignUserToAssignment : SqlDatabaseTestClass
{
  private TransactionScope trans;

  public SqlServerUnitTestAssignUserToAssignment()
  {
    InitializeComponent();
  }

  [TestInitialize()]
  public void TestInitialize()
  {
    trans = new TransactionScope();
    base.InitializeTest();
  }
  [TestCleanup()]
  public void TestCleanup()
  {
    base.CleanupTest();
    trans.Dispose();
  }

  // generated code below:

  Designer support code

  Additional test attributes

  [TestMethod()]
  public void core_AssignUserToAssignmentTest()...

  private Sql DatabaseTestActions core_AssignUserToAssignmentTestData
}

【问题讨论】:

    标签: sql sql-server visual-studio unit-testing


    【解决方案1】:

    拼图的两个部分是:

    • 每类“通用脚本”:如果您需要在给定测试类中的所有测试之前或之后运行通用代码,只需将 SQL 放入 使用设计器的该类的通用脚本。

    • 基类测试初始化​​器:如果您需要在给定项目(或解决方案)中的所有测试之前或之后运行通用代码, 像这样创建一个新的基类,并使每个测试类派生自 它。

    -

    public class MySqlTestsBase : SqlDatabaseTestClass
    {
        [TestInitialize]
        public void TestInitialize()
        {
            PrivilegedContext = TestService.OpenPrivilegedContext();
    
            CleanupTables();
    
            //"Common Scripts" are run
            base.InitializeTest(); 
        }
    
        [TestCleanup]
        public void TestCleanup()
        {
            CleanupTables();
    
            base.CleanupTest();
        }
    
        /// <summary>
        /// Deletes data from all tables that tests might have affected.
        /// </summary>
        private void CleanupTables()
        {
            TestService.Execute(PrivilegedContext, PrivilegedContext, new SqlDatabaseTestAction
            {
                SqlScript = @"
                    DELETE CustomerOrder
                    DELETE Customer
                    DELETE Order
                "
            });
        }
    }
    

    【讨论】:

    • 好答案...如果从这个基类派生,子类也应该摆脱 TestInitialize 和 TestCleanup 方法
    【解决方案2】:

    这是一个很好的例子,说明您如何listen to your tests,并让它们影响您的系统设计。 (所以我希望我能做到公正。)

    你说:

    所以我的问题是,是否有任何方法可以只在某处编写一次预测试并通过调用单元测试项目中的函数来运行它?

    想象一下,您能够将此预测试代码整合到一个辅助函数中,然后您可以从测试项目中调用该函数。这解决了您的测试问题……但是您的代码的其他使用者呢?他们不会也从这种整合中受益吗?

    将我们的测试视为我们代码的常规消费者是有帮助的。在this post about TDD,“鲍勃叔叔”马丁说(强调我的):

    您是否曾经将第三方库集成到您的项目中?你有一本很大的手册,里面有很多很好的文档。最后有一个薄薄的例子附录。你读过哪两个?当然是例子!这就是单元测试!它们是文档中最有用的部分。 它们是如何使用代码的活生生的例子。

    如果您的测试告诉您他们需要 boilerplate code 才能开始,他们是在告诉您每个人都需要这个样板代码。

    在您将此重复代码重构为一个(或多个)正式类后,这些测试可以使用该代码执行必要的初始化/清理 - 就像您最初的目标一样。但现在系统的其余部分也从这项工作中受益。

    【讨论】:

    • 虽然您提出了很好的观点,但您没有提供任何示例或如何在 VS SQL 单元测试框架中实际完成这项工作。我们当然想重用代码,但发布问题的人可能意味着他们不知道如何做到这一点,需要这个特定框架的帮助。
    • @Chad 感谢您的反馈。我没有包含有关如何在框架内进行这项工作的示例,因为这样做与我的回答精神背道而驰。我知道测试框架旨在从我们的测试中卸载繁琐的任务,但有时这种卸载隐藏了我们 API 设计中的缺点。我的观点是,当这种情况发生时,应该以它为契机,收集关于我们API使用的新观点,并做出相应的调整。 (IME,“预测试”代码比“清理”代码更常见,这就是我选择解决它的原因。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多