首先说一下Test Fixture,我不知道怎么样翻译这个Test Fixture,没能搜到一个翻译的比较合适的。让我气愤的是某人翻译的一本书中,直接把Test Fixture翻译成为测试夹具,这明显是什么词霸词典硬翻译出来的,我强烈鄙视这样不负责任的翻译行为。

The test fixture is everything we need to have in place to exercise the SUT

我觉得这是一个对Test Fixture的一个很清晰明了的定义,是运行被测软件所需要的一切东西,这个“东西”不单只是数据,同时还包括对被测软件的准备,例如实例化某个被测方法所在的类,准备数据库的ConnectionString等。通常来说,有三种方法来准备Test Fixture。

1. 内联方式:这种方式是直接在测试方法中编写准备Test Fixture的代码。用这种方法的缺点是很容易造成代码的重复,出现很多复制粘贴的代码。同时,如果这个SETUP的过程比较复杂,也会降低测试代码的可读性,可维护性。另外的一个问题是,这种方法很容易会带来测试数据Hard code的隐患。既然有那么多缺点,这种方法还有什么生命力呢?首先,可能对于初学者来说,这种方法是简单的;其次,在一些只需要准备简单的Test Fixture的场合中,这种方法还是给编写测试的人提供了便利。

2. 委托方式:简单来说是把Test Fixture的准备抽取为一个外部的方法,然后在需要的时候进行调用。这种方式的好处是使得测试代码可读性更强,并且这部分的SETUP代码可以重用。而且这种做法可以屏蔽对SETUP过程的认知,使得测试人员的关注点落在真正的测试代码上面,而不是如何SETUP。

3. 隐式方式:很多xUnit框架的实现都提供了不同的隐式SETUP和TEARDOWN。例如MSTEST里面的[TestInitialize]和 [TestCleanup]标签,提供了一种隐式准备Test Fixture的支持。是在每一个测试方法运行前,都会执行一次标有[TestInitialize]标签的方法。使用这种方法的好处是写一次能在各个测试中都实现了Test Fixture的准备,不用每次都显示地调用一个外部方法,不过缺点也不少:

可能会令测试比较难懂,因为这些隐式调用不是必须的,有可能会被遗漏掉。

不能使用哦本地变量来保存对象,只能用test class 里面的filed或者property变相地使用了全局变量。