一步一步学NUnit.docx

上传人:b****6 文档编号:6334605 上传时间:2023-01-05 格式:DOCX 页数:26 大小:607.80KB
下载 相关 举报
一步一步学NUnit.docx_第1页
第1页 / 共26页
一步一步学NUnit.docx_第2页
第2页 / 共26页
一步一步学NUnit.docx_第3页
第3页 / 共26页
一步一步学NUnit.docx_第4页
第4页 / 共26页
一步一步学NUnit.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

一步一步学NUnit.docx

《一步一步学NUnit.docx》由会员分享,可在线阅读,更多相关《一步一步学NUnit.docx(26页珍藏版)》请在冰豆网上搜索。

一步一步学NUnit.docx

一步一步学NUnit

一步一步学NUnit

  单元测试基础知识

  单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。

通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。

例如,你可能把一个很大的值放入一个有序list中去,然后确认该值出现在list的尾部。

或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。

  执行单元测试,是为了证明某段代码的行为确实和开发者所期望的一致。

  当编写项目的时刻,如果我们假设底层的代码是正确无误的,那么先是高层代码中使用了底层代码;然后这些高层代码又被更高层的代码所使用,如此往复。

当基本的底层代码不再可靠时,那么必需的改动就无法只局限在底层。

虽然你可以修正底层的问题,但是这些对底层代码的修改必然会影响到高层代码。

于是,一个对底层代码的修正,可能会导致对几乎所有代码的一连串改动,从而使修改越来越多,也越来越复杂。

从而使整个项目也以失败告终。

  而单元测试的核心内涵:

这个简单有效的技术就是为了令代码变得更加完美。

  NUnit介绍

  NUnit是一个免费开源的产品,它提供了一套测试框架和一个测试运行程序(testrunner)。

  注意:

testtunner知道如何寻找具有[TestFixture]属性的类和类中的[Test]方法。

  如何安装NUnit

  在官网下载NUnit,当前最新的版是2.4.8,我下的是NUnit-2.4.8-net-2.0.zip。

  NUnit第一个演示

  我们用VisualStudio2008新建一个NUnit项目:

  为了便于演示,我们把默认的Program.cs改成Calculator.cs,在Calculator类里,我们实现简单的加减乘除四个方法。

完整代码如下:

usingSystem;

namespaceNUnitTest

{

    publicclassCalculator

    {

        ///

        ///加法

        ///

        ///

        ///

        ///

        publicintAdd(inta,intb)

        {

            returna+b;

        }

        ///

        ///减法

        ///

        ///

        ///

        ///

        publicintMinus(inta,intb)

        {

            returna-b;

        }

        ///

        ///乘法

        ///

        ///

        ///

        ///

        publicintMultiply(inta,intb)

        {

            returna*b;

        }

        ///

        ///除法

        ///

        ///

        ///

        ///

        publicintDivide(inta,intb)

        {

            returna/b;

        }

        staticvoidMain(string[]args)

        {

            Calculatorcal=newCalculator();

            intresult=cal.Add(2,3);

            Console.WriteLine(result);

            Console.ReadKey(true);

        }

    }

}

        如果没有单元测试,我们普通的测试方法就像是Main方法一样,这样的测试是一个很邪恶的测试方法,花时间且很难得到我们想要的结果。

  那么,我们应该如何来用NUnit做单元测试呢?

  我们再新建一个项目:

  为这个NUnitTestTest引用“NUnitTest项目”和“nunit.framewor类库”。

我们再新建一个测试类,命名为“CalculatorTest.cs”。

并键入如下代码:

usingSystem;

usingNUnit.Framework;

usingNUnitTest;

namespaceNUnitTestTest

{

    [TestFixture]

    publicclassCalculatorTest

    {

        [Test]

        publicvoidTestAdd()

        {

            Calculatorcal=newCalculator();

            intexpected=5;

            intactual=cal.Add(2,3);

            Assert.AreEqual(expected,actual);

        }

    }

}

 

 这就是一个简单的单元测试方法了。

首先我们使用usingNUnit.Framework和usingNUnitTest,因为接下来的代码需要用到这两个命名空间。

在这里,我们要注意几点,NUnit测试用的类前面一定要加上[TestFixture],以表示这是NUnit测试类;测试方法一定是public的,且没有返回值。

这里的TestFixture和Test都是NUnit的Attribute,下表给出了NUnit常用的Attribute:

 

         Assert.AreEqual是断言,在测试框架中,断言是单元测试的核心,我们在测试中要对其程序断言。

如果某个断言失败,方法的调用不会返回值,并且会报告一个错误。

如果一个测试包含多个断言,那些紧跟失败断言的那些断言都不会执行,因此每个测试方法最好只有一个断言。

NUnit.Framework.Assert有23个重载方法,大部分的情况它都有考虑到,当然,不排除需要自己写一个复杂的断言方法。

  上面的代码中,intexpected=5;是指我们期望程序执行的结果是5,intactual=cal.Add(2,3);则执行Calculator.Add方法得到实际的值。

  顺便说一下,CalculatorTest(类名)还有TestAdd(方法名)并不是一定要这样写,你可以自由的命名你的名称,不过为了让你的代码可读性更好,请遵循一个命名规范,这个规范可以是公司定的也可以是网上主流的命名规则。

  对Add()方法的单元测试代码已经完成了,接下来我们运行下载解压后文件夹中的nunit.exe,程序界面如图:

 

  打开对话"File"/"OpenProject..."对话框,或者按"Ctrl+O",把第二个单元测试项目NUnitTestTest生成的NUnitTestTest.dll加载进来:

  我们点右边的"Run"按钮执行单元测试:

 

  太棒了,绿色!

通过!

Keepthebargreentokeepthecodeclean.

  一个简单的单元测试过程就是这样的。

我们再为除法写一个单元测试方法:

 [Test]

  publicvoidTestDivide()

  {

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Divide(25,5);

  Assert.AreEqual(expected,actual);

  }

  重新生成NUnitTestTest项目,NUnit会自动把TestDivide方法加进去。

  再点"Run",通过测试。

大家都知道除法中除数不能为0,如果这里除数是0呢?

会有什么样的结果?

 [Test]

  publicvoidTestDivide()

  {

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Divide(25,0);

  Assert.AreEqual(expected,actual);

  }

  生成项目并重新运行单元测试:

 

  测试没有通过“NUnitTestTest.CalculatorTest.TestDivide:

System.DivideByZeroException:

试图除以零。

”这时,我们要返回到Calculator类中修改Divide方法使之除数为0时返回其它的值。

  NUnit第一个简单示例就先到这里,在NUnit的官网也有简单教程,大家可以看看。

  在单元测试中,我们在做正面的测试的同时也要做一些反面测试,这样才能让我们的代码更健壮。

  在VisualStudio2008中打开上一章的示例,Calculator类有4个最简单的方法:

加、减、乘、除。

CalculatorTest类中的四个方法是Calculator类四个方法的单元测试。

 

[TestFixture]

  publicclassCalculatorTest

  ...{

  [Test]

  publicvoidTestAdd()

  ...{

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Add(2,3);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestMinus()

  ...{

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Minus(10,5);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestMultiply()

  ...{

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Multiply(1,5);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestDivide()

  ...{

  Calculatorcal=newCalculator();

  intexpected=5;

  intactual=cal.Divide(25,5);

  Assert.AreEqual(expected,actual);

  }

  }

  这里一定要注意,TestAdd()、TestMinus()、TestMultiply()和TestDivide()方法没有任何关系,也就是说单元测试中,所有的测试方法都是独立的。

各个方法之间没有依赖性,删除任何一个单元测试方法,对其它的测试不会有任何影响。

  上一章中,我们已经介绍了[TestFixture]和[Test],现在我们为这个类新增一个方法。

[SetUp]

  publicvoidInitMethod()

  {

  Console.WriteLine("Initializationmethod");

  }

  重新生成项目,再运行NUnit,选中"CalculatorTest"进行单元测试:

  切换到NUnit的"Console.Out"中,我们看到"Initializationmethod"出现了4次,如果只选中一个测试方法:

  我们看到,这时只出现一次的"Initializationmethod"。

[SetUp]的意思就是指在运行每个测试方法前执行它。

相应的,有开始必然有结束,[TearDown]是指在每个测试方法结束后运行。

  我们再新增一个方法:

 

[TearDown]

  publicvoidFinalizeMethod()

  {

  Console.WriteLine("Finalizemethod");

  }

  再来看运行NUnit的结果:

  知道了[SetUp]和[TearDown]后,我们就可以改写这个单元测试类了。

请[TestFixture]

  publicclassCalculatorTest

  ...{

  privateCalculatorcal;

  privateinta,b,expected,actual;

  [SetUp]

  publicvoidInitMethod()

  ...{

  cal=newCalculator();

  a=10;

  b=2;

  }

  [Test]

  publicvoidTestAdd()

  ...{

  expected=12;

  actual=cal.Add(a,b);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestMinus()

  ...{

  expected=8;

  actual=cal.Minus(a,b);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestMultiply()

  ...{

  expected=20;

  actual=cal.Multiply(a,b);

  Assert.AreEqual(expected,actual);

  }

  [Test]

  publicvoidTestDivide()

  ...{

  expected=5;

  actual=cal.Divide(a,b);

  Assert.AreEqual(expected,actual);

  }

  }

  因为运行每个测试方法之前,都会运行InitMethod()方法,所以每次都会初始化使第一个操作数为10,第二个操作数为2。

在[SetUp]中初始化了的资源,我们就可以在[TearDown]里销毁释放。

  这里也许有人会问,如果我的项目很大,每个测试方法都需要连接数据库,在每个方法执行的时候进行连接再释放,这样是不是太耗资源太慢了,能不能在一个单元测试类实例化的时候就运行一个指定的方法呢?

  这是可以的。

在NUnit中,我们使用[TestFixtureSetUp]和[TestFixtureTearDown]就可以实现这样的功能。

[TestFixtureSetUp]是指在这个测试类的整个生命周期中,它在所有的测试方法之前运行一次,而[TestFixtureTearDown]是在所有的测试方法都结束时运行。

  这里要注意的,[TestFixtureSetUp]与构造函数是不一样的,它标识的方法迟于构造函数运行。

我们再对这个测试类进行重构:

 [TestFixture]

  publicclassCalculatorTest

  ...{

  privateCalculatorcal;

  privateinta,b,expected,actual;

  publicCalculatorTest()

  ...{

  Console.WriteLine("执行构造函数");

  }

  [TestFixtureSetUp]

  publicvoidInitClass()

  ...{

  Console.WriteLine("执行TestFixtureSetUp");

  cal=newCalculator();

  a=10;

  b=2;

  }

  [TestFixtureTearDown]

  publicvoidFinalizeClass()

  ...{

  Console.WriteLine("执行TestFixtureTearDown");

  }

  [SetUp]

  publicvoidInitMethod()

  ...{

  Console.WriteLine("执行SetUp");

  }

  [TearDown]

  publicvoidFinalizeMethod()

  ...{

  Console.WriteLine("执行TearDown");

  a=10;

  b=2;

  }

  [Test]

  publicvoidTestAdd()

  ...{

  Console.WriteLine("TestAdd()Begin");

  expected=12;

  actual=cal.Add(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestAdd()End");

  }

  [Test]

  publicvoidTestMinus()

  ...{

  Console.WriteLine("TestMinus()Begin");

  expected=8;

  actual=cal.Minus(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestMinus()End");

  }

  [Test]

  publicvoidTestMultiply()

  ...{

  Console.WriteLine("TestMultiply()Begin");

  expected=20;

  actual=cal.Multiply(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestMultiply()End");

  }

  [Test]

  publicvoidTestDivide()

  ...{

  Console.WriteLine("TestDivide()Begin");

  expected=5;

  actual=cal.Divide(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestDivide()End");

  }

  }

  在NUnit中,我们可以很清楚地看到这个类的执行顺序:

  假如我们的测试项目中有使用到数据库,就可以把数据库连接写在[TestFixtureSetUp]中,把释放的代码写在[TestFixtureTearDown]中。

  我相信现在大家对NUnit的这4个属性都应该有一个直观的认识了吧。

都是4个很简单的属性,但是在使用中用处却是非常大的。

  接下来再为大家介绍几个常用的属性。

  现在的测试中,我们有4个测试方法,但是如果我们想让其中的一个测试方法不在NUnit中显示,怎么办呢?

不是注释,大家不要想歪了,注释大家都知道。

要想让一个测试方法不在NUnit中显示,也不运行,我们应该使用[Ignore]属性。

看看把TestAdd()添加[Ignore]属性后会是什么样子:

 [Test]

  [Ignore]

  publicvoidTestAdd()

  {

  Console.WriteLine("TestAdd()Begin");

  expected=12;

  actual=cal.Add(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestAdd()End");

  }

 

现在有了一个新的颜色了——黄色。

它是指被忽略的方法。

当然,你在项目中出现最多的肯定是绿色。

在NUnit中我们可以用[Ignore]的重载方法[Ignore("忽略原因")]来定义忽略原因。

  NUnit有一个与[Ignore]类似的属性[Explicit],它是指只有在NUnit中被明确的指定时才运行,否则不运行。

有点拗口,我们来看例子。

改写TestMinus方法:

 

[Test,Explicit]

  publicvoidTestMinus()

  {

  Console.WriteLine("TestMinus()Begin");

  expected=8;

  actual=cal.Minus(a,b);

  Assert.AreEqual(expected,actual);

  Console.WriteLine("TestMinus()End");

  }

  

这里,

[Test,Explicit]

  和

 [Test]

  [Explicit]

  是完全一样的。

  我们看它的截图:

  "TestMinus"是灰色的,运行的Cases有2个,一个被忽略。

而当我们选中TestMinus时:

  这个测试运行了。

  再给大家介绍一个分类属性[Category(stringname)],利用这个分类属性

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1