English 中文(简体)
标准 .Net TDD 内存测试
原标题:
  • 时间:2009-02-20 20:37:34
  •  标签:

编写标准化的TDD[测试]方法以显示常见的内存问题是否有用? (Biānxíe biāozhǔnhuà de TDD [cèshì] fāngfǎ yǐ xiǎnshì chángjiàn de nèicún wèntí shìfǒu yǒuyòng?)

这套测试能够轻松、快速地应用于某个方法,能够检测出经典的.NET内存问题并标为红色——不符合标准,同时也能够通过经典解决方案,并标为绿色——符合标准。

For example common memory issues could be : too much relocation by the garbage collector ; allocating too much ; too many garbage collections ( classic example prefer StringBuilder over string reallocs ); holding on to memory for too long (classic example call dispose and do not reling on finalizers ); objects inappropriately reaching g1, g2, LOH ; little leaks that add up to something significant over time, … and others.

也许代码看起来像这样...

[Test]
public void Verify_MyMethodUnderTest_Is_Unlikely_To_Have_Common_Memory_Problem()
{

//-Setup
var ExpectationToleranceA = ...
var ExpectationToleranceB = ...
...

//-Execute
var MeasurementA = MyClassUnderTest.MyMethodUnderTest( dependancyA ) ; 
var MeasurementB = MyClassUnderTest.MyMethodUnderTest( dependancyB ) ; 
…

//-Verfiy
Assert.That(  MeasurementA  , Is.WithinTolerance( ExpectationToleranceA  ) ) ;
Assert.That(  MeasurementB  , Is.WithinTolerance( ExpectationToleranceB  ) ) ;

}

这里有其他关于内存压力问题的帖子,但这里的想法是可以快速将标准测试指向一个方法,测试会在常见/经典内存压力问题下变为红色失败,但在常见解决方案下变为绿色通过。然后可以指示开发人员审核失败的代码,可能修复泄漏,更改容差甚至删除TDD内存压力测试。

这个想法有潜力吗?

这里有一个相关的问题是针对C++应用程序的,在运行单元测试时检测内存泄漏,这是一个类似的问题但不完全相同。Twk的问题是指在所有测试运行后检查内存...

My idea here is for .NET to 1) unit test each method for common memory issues 2) fail the classic memory issues 3) pass the classic fixes to classic common memory issues 4) be able to quickly throw a quick standard test at a function to see whether it exhibits classic symptoms 5) be able to upgrade the Standard TDD .Net Memory Pressure Test applied in the unit test. This implies a refactor of the above code so that upgrades to the standard test will change upgrade the memory tests applied throughout the Nunit test suite for a project.

(p.s. I know there is no Is.WithinTolerance call but I was just demonstrating an idea. ) cheers ...

最佳回答

好的单元测试应该指向小的代码片段。理想情况下,它们应该是可重复的,但当垃圾回收器参与时,情况就不是这样了。

然而,您可以使用单元测试框架设施进行非单元测试(功能测试,回归测试,压力测试等)。但是您需要意识到,您并没有进行真正的单元测试。因此,请不要在某些自动构建中使用它们,并且不要强制其他开发人员在其提交测试中包含此类测试。真正的单元测试可能不会受到非单元测试的影响!

如果您想要做类似的事情,请考虑在测试您想要测试的操作之前和之后调用GC.Collect()函数。连续多次调用可以更容易地感知内存消耗的增长。建议将此类测试添加到独立的隔夜构建中(与真实的单元测试分开),因为这可能会耗费时间。请在一个您可以完全控制的单独的机器上运行这些测试(在测试期间打开一个带有一些Flash动画或病毒扫描器的浏览器可能会破坏您的结果)。请将内存消耗的数据存储在某个地方以供日后查看。这将使您在长时间的开发周期中了解到内存消耗的缓慢增长。

问题回答

单元测试通常最适合用于测试小块功能。您想要测试的似乎更像是集成测试,它测试整个系统的行为和性能。

我看到这种方法的问题是,您系统中的任何一个单元都可能不会生成这些与内存相关的错误。因此,即使您可以让这种方法工作,也无法保证一旦您的单元作为整体运行时不会出现内存问题。

因此,我的建议是在多种状态下进行集成测试。测试系统在不同负载水平下,并查看是否有任何内存问题。这种类型的测试对您会更有利。

我认为这是一个不好的想法。如果您想编写测试来“验证”垃圾收集器的某些行为,那么您基本上是在“测试”您无法控制的代码。垃圾收集器的确切行为是当前CLR的实现细节。它可能会在未来发生变化,从而导致您的测试“失败”。在大多数情况下,您可能无法更改代码中的任何内容以“修复”测试,因此您被迫更改测试以反映新实现。在我看来,这具有有限的用途。

应使用单元测试验证自己代码的意图,以便在更改破坏现有代码时得到通知。使用它们来帮助开发和维护自己的代码。

根据我的经验,最好的结果是确保单元测试没有依赖关系。执行您所描述的测试意味着测试将具有许多依赖关系,包括硬件和运行时系统。

只是我的五分钱。





相关问题
热门标签