2015-06-11 57 views
7

我目前正在通过visual studio运行测试。在所有测试运行之前,我会自动创建一组具有已知凭证的用户,并在运行结束时删除这些用户。但是,有时我需要中途取消我的测试。在这些情况下,测试永远没有机会进行清理,这意味着测试运行中会留下假用户信息,并可能导致下一次测试运行崩溃(当它试图将用户信息添加到数据库时)。无论如何,即使测试被取消,强制visual studio/mstest运行清理方法吗?取消测试后清理

我知道一个选项是进行测试检查并确保用户信息不存在,并且在创建新用户之前删除它。但是这仍然不能解决取消的测试运行中留下不需要的测试数据的问题。

更新:

很抱歉的误解,但是在测试开始清理数据是不是一种选择。我对这个问题给出了一个非常简单的观点,但简单地说,我没有简单的方法来确保在测试开始时不存在测试数据。所有清理工作必须在测试结束时进行。

+1

我想订阅当你取消或当它完成自然,而在此情况做清理 – bill

+1

如果你在测试之前进行清理运行触发事件处理程序? – Matthew

+0

为什么不能在测试前删除数据?它是你唯一的选择,从调试器取消测试会停止所有执行 –

回答

5

在创建数据之前执行清理操作,这将确保您不会发生任何残留数据。当然,这只有在运行安装程序之前识别任何剩余数据的情况下才有可能。

7

我不是在测试结束时调用清理函数,而是在每次测试开始时调用我的函数来解决这个确切问题。

3

我想你应该在测试之前打开一个事务,创建数据并完成测试测试。但不要交易。这将确保测试不会影响您的数据库。

+0

这不提供问题的答案。一旦你有足够的[声誉](https://stackoverflow.com/help/whats-reputation),你将可以[对任何帖子发表评论](https://stackoverflow.com/help/privileges/comment);相反,[提供不需要提问者澄清的答案](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an- I-DO-代替)。 - [来自评论](/评论/低质量帖子/ 17989174) – manish

+0

仍然不知道为什么问题得到的投票没有任何评论解释为什么。我的问题的解决方案是将事务中的所有内容都包含在事务中,这可以防止将测试数据保存到数据库。仍然不知道为什么它不提供答案。 –

+0

您描述的OP不能以干净的方式回滚事务。根据我的经验,连接池的连接在应用程序进程停止后仍可能挂起一段时间。在这种情况下交易是否仍然在运行并持有锁定? –

2

因此Visual studio使用NUNIT,你可以使用TearDownAttribute。测试结束后应该运行,即使测试被取消。你可以写一个函数来清理你的数据。

请点击这里阅读参考文档:http://nunit.org/docs/2.2/teardown.html

+0

请不要用“U”缩写“你”。 StackOverflow旨在尽可能地保持专业和国际化。虽然可能很容易理解,但来自印尼的非母语人士可能会遇到问题。 –

+0

谢谢MechMK1。 – Shuvra

2

只是为了澄清更多关于NUNIT standrad。请按照测试类中的步骤:

[TestFixture] 
public class _TestClass 
{ 
     [TestFixtureSetUp] 
     public void Setup() 
     { 
      //Clearup can be here before start of the tests. But not Recommended 
     } 

     [Test] 
     public void _Test1() 
     { 
     } 
     [Test] 
     public void _Test2() 
     { 
     } 

     [TestFixtureTearDown] 
     public void CleanUp() 
     { 
      //I will recommend to clean up after all the tests complete 
     } 
} 

参考:http://nunit.org/docs/2.5/fixtureTeardown.html

7

那是不可能的。您最好找到一种替代解决方案,如使用单独的数据库进行测试,并在每次测试运行前清理所有数据,使用固定的测试用户集合或用一些标记标记测试数据。检查Isolating database data in integration tests Jimmy Bogard的文章。

没有内置的方法来更改MSTest默认行为。从理论上讲,您可以编写使用TestExecution.OnTestStopping事件的MSTest扩展,但这不是一个简单的过程,它需要注册表更改。而且,很多人抱怨说它不起作用。

还有MSTest V2,带有新的可扩展性点的MSTest的新版本。但是看起来你不能用这个点改变取消行为,只写属性修饰符。见Extending MSTest V2

您不能使用AppDomain.CurrentDomain.ProcessExitProcess.GetCurrentProcess().Exited事件,因为取消似乎会终止测试运行过程。

NUnit目前也不支持此功能。请参阅相关的NUnit测试适配器Run TearDowns on VS Cancel Test Run问题。

+0

感谢大家所有的新答案。很明显,有些人在特定情况下工作得很好,而不是在其他情况下工作。对于我目前的情况,这个答案与我目前需要的最接近。 –

3

有两种情况我们需要考虑在ATP中分配资源(资源可能是创建用户,连接数据库)。他们是

  • 每次测试后创建和删除资源。
  • 在一组测试后创建和删除资源。

资源的创建和删除每次测试后:

如果我们想的一个测试执行之前创建特定对象的实例,并要清理执行后,分配给该对象的内存那测试,那么我们使用NUnit的Test SetUpTest TearDown属性。在你的案例中,对象是用户数量的创建。

[SetUp]:该函数装饰有测试设置属性包含一段代码的任何测试执行之前执行。

[TearDown]:该函数装饰有测试TearDown中属性包含一段代码,任何测试的执行之后执行

实现:

[TestClass] 
    public class UnitTest1 
    { 
     [SetUp] 
     public void SetUP() 
     { 
      // Creating Users with proper credentials 
     } 

     [TestMethod] 
     public void TestMethod1() 
     { 
      //Write your ATP 
     } 

     [TearDown] 
     public void TearDown() 
     { 
      //Clean up 
     } 
    } 

创作和资源的删除组测试后:

现在,如果我们想创建一个对象的实例为测试集,并且希望在执行所有测试后清理内存,然后分别清理内存和[TestFixtureSetUp][TestFixureTearDown]以清理内存。再次在您的案例对象可以创建一组用户。

[TestFixtureSetUp]:用TestFixtureSetUp装饰的功能将执行一次之前执行测试组的执行。

[TestFixtureTearDown]:用TestFixtureTearDown装饰的功能将执行一次执行一组测试。

实施

[TestFixture] 
public class Tests 
{ 
     [TestFixtureSetUp] 
     public void Setup() 
     { 
      //Create users with credentials 
     } 

     [Test] 
     public void _Test1() 
     { 
      //Test_1 
     } 
     [Test] 
     public void _Test2() 
     { 
     //Test2 
     } 

     [TestFixtureTearDown] 
     public void CleanUp() 
     { 
      //Cleanup; Here you need to add code to Delete all users 
     } 
} 

注:我会建议你,如果你想创建和删除用户特定ATP然后用SetUpTearDown去。如果您尝试使用相同的一堆ATP,我会建议您使用TestFixtureSetUpTestFixtureTearDown

“如果你的测试获得通过或失败,安装和拆卸功能将执行”

参考文献:

4

的想法是,在测试开始之前一个交易被初始化。为了将数据保存到数据库中,事务必须被提交,但它不会被提交。在测试停止的情况下,如果测试成功或不成功完成,它就起作用。

在集成测试,我们使用的财产以后像这样(NUnit的)(它真正的生产代码)

public class RollbackAttribute : TestAttribute, ITestAction 
{ 
    private TransactionScope _transaction; 

    public void BeforeTest(ITest test) 
    { 
     _transaction = new TransactionScope(); 
    } 

    public void AfterTest(ITest test) 
    { 
     _transaction.Dispose(); 
    } 

    public ActionTargets Targets => ActionTargets.Test; 
} 

[TestFixture] 
public class SomeTestClass 
{ 
    [Rollback] //No need [Test] because Rollback is inherit it. 
    public void SomeTestMethod() 
    { 
    } 
} 

在MSTEST可以使财产以后类似的,但在这种情况下,你应该从基类继承,我希望有用。例如:

public class RollbackTestBase 
{ 
    private TransactionScope _transaction; 

    [TestInitialize] 
    public virtual void Setup() 
    { 
     _transaction = new TransactionScope(); 
    } 


    [TestCleanup] 
    public virtual void TearDown() 
    { 
     _transaction.Dispose(); 
    } 
} 

[TestClass] 
public class IntegrationTest : RollbackTestBase 
{ 
    [TestMethod] 
    public void TestDataBase() 
    { 
     Assert.IsTrue(true); 
    } 

    [TestInitialize] 
    public virtual void Init() 
    { 
    } 

    [TestCleanup] 
    public virtual void CleanUp() 
    { 
    } 
}