你学会测试了吗(2):测试语法之属性介绍

前言

这个简短的系列一一讲解一下.Net下测试的相关知识,希望对初学者有所帮助。

上一篇中我向大家介绍了几个测试工具,推荐使用TestDriven.NET。至本文完稿官方提供了TestDriven.NET-2.14.2190 Beta版(直接下载)和TestDriven.NET-2.13.2184正式版(直接下载)。此文为这个系列的第二篇,我将使用这个工具,介绍TestDriven.NET所支持的一些重要的属性。

属性

TestDriven.NET支持多种单元测试框架,像NUnit,MbUnit,MS Team System,这里我选择了最为经典的NUnit单元测试框架来介绍TestDriven.NET所支持的一些重要的属性。TestDriven.NET其实已经支持大部分NUnit的属性,但是有些属性现在还不支持。

在我们使用TestDriven.NET测试前,项目必须引用框架的程序集,即nunit.framework.dll,并且在每个包含测试的源文件中必须使用using语句引用该程序集,像这样:using NUnit.Framework; 在NUnit中,所有的属性都包含在Nunit.Framework命名空间里。

首先我们依次熟悉一下这些属性。

1.TestFixtureAttribute

这个属性用来修饰测试类,表示这个类包含了测试方法。注意一下使用这个属性修饰类有一些限制:这个类必须是public,必须有一个缺省的构造函数。

using System;
using NUnit.Framework;

namespace TestDrivenNET
{
    [TestFixture]
    public class YJingLeeFixture
    {
        //......
    }
}

2.TestAttribute

这个属性标记类的某一方法为一个测试方法,此类已经标记为一个TestFixture。一个测试方法的签名定义如下:

[Test]
public void TestMethod()
{
}

注意这个方法必须没有参数。如果程序员将测试方法标记为不正确的签名,它不会运行。

3.SetUpAttribute

这个属性用来修饰方法,修饰后这个方法在每个测试方法被调用之前运行的,我们可以用它来重新设置一些变量,在每个方法运行之前赋值。

[SetUp]
public void Init()
{
}

4.TearDownAttribute

这个属性用来修饰方法,说明这个方法是在每个测试方法被调用完之后运行的,我们可以用来释放一些暂存的变量。

[TearDown]
public void Dispose()
{
}

5.SetUpFixtureAttribute

这个属性这个属性用来修饰类,这个类包含了SetUpAttribute或者TearDownAttribute属性,必须是public和一个缺省的构造函数。只要使用这个属性,在其命名空间下,运行测试则首先运行其中SetUpAttribute修饰的方法,在运行测试结束则运行其中TearDownAttribute修饰的方法。注意一个命名空间下只有一个SetUpFixtureAttribute,如果这个属性在整个程序集下定义,则在整个程序集下有效。我们常常用它来设置全局的条件。

[SetUpFixture]
public class MySetUpClass
{
    [SetUp]
    public void RunBeforeAnyTests()
    {
    }
    [TearDown]
    public void RunAfterAnyTests()
    {
    }
}

6.TestFixtureSetUpAttribute

这个属性用来修饰方法,修饰后这个方法在fixture任何测试执行之前运行,我们常常用来初始化一些对象等,类似于类中的构造函数。

[TestFixtureSetUp]
public void FixtureInit()
{
}

7.TestFixtureTearDownAttribute

这个属性用来修饰方法,修饰后这个方法在fixture任何测试执行之后运行,我们常常用来释放一些资源。

[TestFixtureTearDown]
public void FixtureDispose()
{
}

8.ExpectedExceptionAttribute

使用这个属性表明这个方法会抛出一个预期的异常。用这种方法来指出这个测试执行时会抛出的异常。Type,为期望的异常的精确类型。 第二个是一个期望的异常全名的字符串。 不管是哪一种,在执行测试时,如果它抛出了指定的异常,那么测试通过。如果抛出一个不同的异常,测试就失败。如果抛出了一个由期望异常继承而来的异常,这也是成功的。

[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void ExpectAnExceptionByType()
{
}
[Test]
[ExpectedException("System.InvalidOperationException")]
public void ExpectAnExceptionByName()
{
}

9.PlatformAttribute

平台属性用于指定测试方法测试方法或测试Fixture运行的平台。平台选择包括了各种操作系统和.NET Framework版本。使用无大小写之分的字符串来指定平台,也通过使用Include或Exclude属性包含或排除运行的平台。也可以指定PlatformAttribute参数。不管是哪一种情况,都可以用多个逗号分隔字符串。

TestFixture语法

[TestFixture]
[Platform("NET-2.0")]
public class YJingLeeFixture
{
}

Test语法

[Test]
[Platform(Exclude = "WinXP")]
public void SomeTest()
{
}

平台指定值:Win系列、Unix、Linux、 Net、Net-1.0、Net-1.1、Net-2.0、NetCF等。它们可以平台指定值:Win系列、Unix、Linux、 Net、Net-1.0、Net-1.1、Net-2.0、NetCF等。它们可以为大写,小写或者混合的。

10.CategoryAttribute

这个属性可以将某些测试方法或测试Fixture指定为属于某个特定的分类。当使用分类时,仅选择的类别可以测试。没有选择的类别测试是不会运行的。 例如我们有些测试需要运行很长的时间,肯定不希望每次都去运行它。你就可以把这些测试归到某个类别中,然后在NUnit的GUI中将它排除在测试范围之外。注意这个属性在TestDriven.NET中不支持。

TestFixture语法

[TestFixture]
[Category("LongRunning")]
public class YJingLeeFixture
{
}

Test语法

[Test]
[Category("VeryLong")]
public void VeryLongTest()
{
}

11.ExplicitAttribute

这个属性会忽略一个测试方法或测试Fixture,直到它被显式的选择运行。如果你指定了它(比如你把鼠标放在这个方法上,然后选择RunTest)这个测试方法就会运行。我们常常用于暂时避免的测试方法。

TestFixture语法

[TestFixture,Explicit]
public class YJingLeeFixture
{
}

Test语法

[Test, Explicit]
public void ExplicitTest()
{
}

12.SuiteAttribute

Suite属性用来定义基于用户偏好的集合。在测试中不常用,因为框架提供了动态创建机制。

13.IgnoreAttribute

这个属性表明这个测试方法或测试Fixture会被忽略掉。一段时间内不会运行这个方法或测试Fixture。我们可以将测试方法或Fixture标记为Ignore属性,运行测试时,就不会执行。 例如我们常常使用这个属性标记暂时不运行测试或者重构软件时需要保留的测试来代替使用注释或重命名的方法,这样做,测试代码会和有这个标记的代码一起编译,在运行时不会运行标记的测试代码,这样保证不会忘记过去测试。

TestFixture语法

[TestFixture]
[Ignore("Ignore a fixture")]
public class YJingLeeFixture
{
}

Test语法

[Test]
[Ignore("Ignore a test")]
public void IgnoredTest()
{
}

在TestDriven.NET中,如果使用这个属性,测试显示结果如下:
测试样例

好了,有关NUnit单元测试框架的属性就介绍这么多了,TestDriven.NET测试工具支持了这里大多数属性,我们完全可以使用这个工具完成我们的测试工作。下篇我继续为大家介绍断言的基本语法,接下来以一个实例实战一下测试技巧。


作者:李永京YJingLee's Blog
出处:http://lyj.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted @ 2008-09-03 21:48 李永京 阅读(2869) 评论(30)  编辑 收藏 网摘 所属分类: TDD

  回复  引用  查看    
#1楼2008-09-03 21:56 | TerryLee      
有关TestDriven.NET属性就介绍这么多了
——————————————————————
这些似乎跟TestDriven.NET没有什么关系,都是NUnit提供的:)

  回复  引用  查看    
#2楼[楼主]2008-09-03 22:03 | 李永京      
@TerryLee
谢谢TerryLee大哥指出错误,我马上改正一下。
有关NUnit单元测试框架的属性就介绍这么多了,TestDriven.NET测试工具支持了这里大多数属性,我们完全可以使用这个工具完成我们的测试工作。

  回复  引用  查看    
#3楼2008-09-03 23:18 |       
TestDriven.net的精髓在于 鼠标右键运行这个方法!

不需要重启整个项目就可以直接测试这个方法,并且支持单步debug!

不用testdriven.net的,还是原始人。

  回复  引用  查看    
#4楼[楼主]2008-09-03 23:28 | 李永京      
@辰
这就是和VS集成方便之处。 你说不用testdriven.net的,还是....这还有点勉强啊,呵呵。说实在的,现在还有很多朋友不知道有关测试工具及知识,特别很多学校的应届生,往届生刚刚踏上初学之路的人和一些初学者.....这正是我想继续写这个系列的原因,相隔第一篇有2个多月间隔咯~~

  回复  引用  查看    
#5楼2008-09-04 00:35 | 水言木      
很期待这一系列。
建议楼主在之后的相应文章中讲范例时可以同时拿个简单的和复杂的例子来示范,这样效果或许更好:)

  回复  引用  查看    
#6楼2008-09-04 09:43 | 朝晖的.net      
@李永京

楼主想弱弱的问一下,.net里面进行单元测试的必要性到底有多大啊?我就从来不做单元测试,主要是我不知道单元测试是什么,小白阿。

.net里面如果方法有错误编译都通不过阿,还有参数不正确返回值类型不匹配,我不太明白单元测试是测什么的,一般都是做完了扔给测试人员就直接功能测试了.

不知道这样做哪里有问题?

----单元测试小白 :^)

  回复  引用  查看    
#7楼[楼主]2008-09-04 10:16 | 李永京      
@水言木
好的,这一篇和接下来一篇以语法为主,两篇后说说单元测试,之后有一个实例,我想或者结合NHibernate来做测试实例。

  回复  引用  查看    
#8楼[楼主]2008-09-04 10:20 | 李永京      
@朝晖的.net
单元测试简单的说就是测试你写的方法是否正确,正确后就可以在以后编写中调用正确的方法。否则的话,你调用这个方法,只有在调试整个工程才知道是否正确,或者错误需要找。

  回复  引用  查看    
#9楼2008-09-04 10:26 | 朝晖的.net      
@李永京

明白单元测试的目的,但是我一直都忽略了这个问题......

看来得强制自己做单元测试了.

  回复  引用  查看    
#10楼2008-09-04 10:58 | 簡簡單單..      
支持一下..
  回复  引用  查看    
#11楼[楼主]2008-09-04 13:22 | 李永京      
@朝晖的.net
呵呵,不是强制,根据TDD标准,做测试的必要的环节。

  回复  引用  查看    
#12楼[楼主]2008-09-04 13:22 | 李永京      
@簡簡單單..
谢谢支持了:-)

  回复  引用  查看    
#13楼2008-09-04 14:12 | 昨日有约      
测试的地位不容忽视,完善的测试才能保证正确率.
  回复  引用  查看    
#14楼[楼主]2008-09-04 14:58 | 李永京      
@昨日有约
说的好:-)

  回复  引用  查看    
#15楼2008-09-05 09:10 | 朝晖的.net      
@李永京

楼主昨天看完你的贴,看了下nunit的介绍和demo,为什么只能测试无参数无返回值的方法啊?

如果要是测试带参数的方法的话用什么办法?把参数提取成全局变量?返回值是不是要用Assert.Equals()这种方法判断阿?

看了你的贴才让我去认识nunit,不熟悉,小白的问题。:^)

  回复  引用  查看    
#16楼2008-09-05 09:37 | 毁于随      
SetUp:在每个测试方法执行前执行.--引用--------------------------------------------------
朝晖的.net: @李永京

楼主昨天看完你的贴,看了下nunit的介绍和demo,为什么只能测试无参数无返回值的方法啊?

如果要是测试带参数的方法的话用什么办法?把参数提取成全局变量?返回值是不是要用Assert.Equals()这种方法判断阿?

看了你的贴才让我去认识nunit,不熟悉,小白的问题。:^)
--------------------------------------------------------
因为这是测试用例,测试用例就是要把你测试的东西所需要的数据,在你编写的测试用例中传进去,So,必需是无参,无返回值.

  回复  引用  查看    
#17楼2008-09-05 09:44 | 毁于随      
晕了.这个系统用Bug哦.我修改了我的评论成功后,又引用了其它人的评论,再提交,我刚才的评论居然又被成修改前的了.
  回复  引用  查看    
#18楼[楼主]2008-09-05 11:43 | 李永京      
我这里用一个简单例子说明:
有一个方法:按firstname和lastname查询Customer,这个方法返回IList<Customer>。
public IList<Customer> GetCustomersByFirstnameAndLastname(string firstname, string lastname)
{
return _session.CreateQuery("select from Customer c where c.Firstname=:fn and c.Lastname=:ln")
.SetString("fn", firstname)
.SetString("ln", lastname)
.List<Customer>();
}
我们的测试用例可以这样写:
[Test]
public void CanGetCustomerByFirnameAndLastname()
{
IList<Customer> customers = _select.GetCustomersByFirstnameAndLastname("Y", "JingLee");
Assert.AreEqual(1, customers.Count);//断言列表数量是否为1.
}

  回复  引用  查看    
#19楼2008-09-05 11:50 | 朝晖的.net      
@李永京
@毁于随

明白了。呵呵,thanks !

楼主用nhibernate + oracle啊~~

  回复  引用  查看    
#20楼[楼主]2008-09-05 11:57 | 李永京      
@朝晖的.net
nhibernate + sql2005打算单元测试实例用这个说,直接查询数据库测试。

  回复  引用  查看    
#21楼2008-09-05 19:43 | Selfocus      
期待你的下一篇文章
  回复  引用  查看    
#22楼[楼主]2008-09-07 21:53 | 李永京      
@Selfocus
你学会测试了吗(3):测试语法之断言介绍
http://www.cnblogs.com/lyj/archive/2008/09/07/1286372.html" target="_new">http://www.cnblogs.com/lyj/archive/2008/09/07/1286372.html

  回复  引用  查看    
#23楼2008-09-08 13:11 | Confach      
原来是讲NUnit的,发现NUnit多了好多功能呀
  回复  引用  查看    
#24楼[楼主]2008-09-08 15:21 | 李永京      
@Confach
呵呵,我就是选择了这个框架来说测试语法的~~~~

  回复  引用    
#25楼2008-09-08 20:05 | 开始学习[未注册用户]
请问:[TestFixtureSetUp] [SetUp] [TearDown] [TestFixtureTearDown ]这四个属性运行的先后顺序是怎样的啊????
  回复  引用  查看    
#26楼[楼主]2008-09-08 20:27 | 李永京      
@开始学习

执行时就是这个顺序,开始运行TestFixtureSetUp,类运行后TestFixtureTearDown运行。当测试某一方法之前运行SetUp,然后运行Test,方法结束使用TearDown来清理变量。

  回复  引用    
#27楼2008-09-09 08:44 | 开始学习[未注册用户]
但我怎么在测试中发现类中的【TestFixtureTearDown】属性在setup之前执行?
我的示例:
[TestFixtureSetUp]
public void AllSetup()
{
Console.WriteLine("this is TestFixtureSetUp!");
}

[SetUp]
public void setup()
{
Console.WriteLine("this is setup");
}


[Test]
public void Go()
{
Console.WriteLine("this is test");
}

[TearDown]
public void Depoerd()
{
Console.WriteLine("this is TearDown!");
}

[TestFixtureTearDown]
public void EndDown()
{
Console.WriteLine("this is TestFixtureTearDown!");
}
测试结果(类):
this is TestFixtureSetUp!
this is TestFixtureTearDown!
this is setup
this is test
this is TearDown!

这是为什么? 望指点,谢谢!!!

  回复  引用  查看    
#28楼[楼主]2008-09-09 18:45 | 李永京      
@开始学习

你在添加一个test方法,再试一试。执行时开始运行TestFixtureSetUp,然后使用TestFixtureTearDown。当测试某一方法之前运行SetUp,然后运行Test,方法结束使用TearDown来清理变量,应该就是这个顺序。。

  回复  引用    
#29楼2008-09-25 15:17 | moplay[未注册用户]
回复楼上的,我去试验了,

最后执行的是testfixture类中的teardown方法

  回复  引用  查看    
#30楼[楼主]2008-09-26 20:20 | 李永京      
@moplay
Thanks~~

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1283390




相关文章:

相关链接: