垃圾收集器如何与单元测试一起工作?

Dan*_*don 6 .net sql garbage-collection unit-testing

最近,我询问(并回答)一个关于StackOverflow的问题,关于为什么单元测试在单独运行时会起作用,然后在运行整批单元测试时偶尔失败.请参见此处:SQL Server和TransactionScope(使用MSDTC):偶尔无法获得连接

在一次运行一个单元测试时通过,然后在一起运行时失败是一个典型的迹象,表明代码严重错误.

我发现有一点资源泄漏.由于一个微妙的错误导致SQL服务器的连接无法释放,我的连接用完了,测试失败了.AFAIK,这几乎就像内存泄漏一样; 连接从连接池分配,永远不会释放,因为内存可以分配,然后不释放.

但是,这确实给我留下了一个令人费解的疑问?一次运行一个测试并将它们作为套件运行有什么区别?如果测试在一次运行一个测试时通过,然后在一起运行时失败,那么测试运行之间必须进行某种清理,只有在每次运行一个测试时才会发生.

我猜想这可能与.net垃圾收集器在测试之间做或不做的事情有关.在一种情况下,在测试之间释放连接; 在另一种情况下,他们不是.

我怎么解释这个?

更新:对于那些询问代码细节的人来说,这很简单.我TransactionScope在Setup方法中声明了一个新对象,并将其置于我的Teardown方法中.然而,问题测试是一个包含100个测试用例的数据驱动测试; 正在测试的代码SqlDataReader使用SqlHelper类从select语句填充了一个对象,然后没有调用close方法SqlDataReader.因为我使用SqlHelper类来获取SqlDataReader,所以我预计会为我处理连接.不是这样!

但要澄清一点,我不是在询问我的具体情况.我想知道的是:一般来说,测试之间如何释放资源?我想这会是垃圾收集器的一些应用.我想知道垃圾收集器是否仍然可以清理以前的测试,因为下一个测试运行(竞争条件?)

更新:我对单元测试垃圾收集的了解.根据我自己的好奇心,我拿出了因为连接被SqlDataReader对象打开而失败的单元测试.我尝试添加System.GC.Collect()到每个测试的结尾.这成功地释放了连接,但确实会造成约50%的性能损失.

Ste*_*dit 2

垃圾收集是一项周期性的后台任务。具体来说,有一个线程除了完成已被标记为死亡的对象之外什么也不做。通过一次运行一个测试,您就为该线程提供了完成对象以关闭连接的机会。