一、要记住的一些东西
1. 首先要明确用户的需求,然后列出需求,首先写测试代码。(也就是先从用户这方调用功能)
2. 看到红灯,则明白需要写程序代码。即写功能代码。
3. 一直到绿灯,然后看是否需要重构。
4. 在重构过后,继续写测试代码,增加用户功能调用,然后重复上述过程,就是测试驱动开发的力量。
5. 测试代码比文档更具有说服力,不仅让用户让测试程序员更加明白你的类是如何使用的。
6. Kent Beck把TDD定义为以下两个简单的规则:1)除非你在自动测试中失败,否则一行代码也不要写;2)消除重复(包括测试代码在内)。
二、第一个基于TDD的程序
(1)需求:一个保存文章的类Article,用于我以后将会开发的Web项目中。此Article类包括功能如下:
1. 创建一个Article,IsDirty为false;
2. 修改Article的Title后,IsDirty为true;
3. 修改Article的Title后,要查看是否真的修改了Title的值;
4. 调用Article的Save后,IsDirty为false,可代表已将文章保存到数据库中。
其它的功能,以后的文章中会渐进地实现。
(2)编写测试代码(使用了VS2005中的测试项目)
![]()
ArticleTest
1
using System;
2
using System.Text;
3
using System.Collections.Generic;
4
using Microsoft.VisualStudio.TestTools.UnitTesting;
5![]()
6
namespace FirstTDDProject
7![]()
![]()
{
8![]()
/**//// <summary>
9
/// ArticleTest 的摘要说明
10
/// </summary>
11
[TestClass]
12
public class ArticleTest
13![]()
{
14
15![]()
16
public ArticleTest()
17![]()
{
18
}
19![]()
20![]()
其他测试属性#region 其他测试属性
21
//
22
// 您可以在编写测试时使用下列其他属性:
23
//
24
// 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
25
// [ClassInitialize()]
26
// public static void MyClassInitialize(TestContext testContext) { }
27
//
28
// 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
29
// [ClassCleanup()]
30
// public static void MyClassCleanup() { }
31
//
32
// 在运行每个测试之前使用 TestInitialize 运行代码
33
// [TestInitialize()]
34
// public void MyTestInitialize() { }
35
//
36
// 在运行每个测试之后使用 TestCleanup 运行代码
37
// [TestCleanup()]
38
// public void MyTestCleanup() { }
39
//
40
#endregion
41![]()
42
protected Article _art;
43
[TestInitialize()]
44![]()
public void Initialize()
{
45
_art = new Article();
46
}
47![]()
48
[TestMethod]
49
public void CheckIsDirty()
50![]()
{
51
Assert.IsFalse(_art.IsDirty);
52
}
53![]()
54
[TestMethod]
55
public void ChangeTitle()
56![]()
{
57
_art.Title = "NewTitle";
58
Assert.IsTrue(_art.IsDirty, "After changing the Article.Title ,Article.IsDirty should be true.");
59
}
60![]()
61
[TestMethod]
62
public void ChangeTitleVerify()
63![]()
{
64
_art.Title = "The first TDD Application.";
65
Assert.AreEqual(_art.Title, "The first TDD Application.",
66
"After changing the Article.Title ,Article.Title should be 'The first TDD Application..' .");
67
}
68![]()
69
[TestMethod]
70
public void SaveArticle()
71![]()
{
72
_art.Title = "The first TDD Application.";
73
_art.Save();
74
Assert.IsFalse(_art.IsDirty, "After Saving the Article ,Article.IsDirty should be false.");
75
}
76
}
77
}
78![]()
使用NUint编写的单元测试
![]()
ArticleTestWithNUnit
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using NUnit.Framework;
5![]()
6
namespace FirstTDDProject
7![]()
![]()
{
8
[TestFixture]
9
public class ArticleTestWithNUnit
10![]()
{
11
12
protected Article _art;
13
[SetUp]
14
public void Init()
15![]()
{
16
_art = new Article();
17
}
18![]()
19
[Test]
20
public void CheckIsDirty()
21![]()
{
22
Assert.IsFalse(_art.IsDirty);
23
}
24![]()
25
[Test]
26
public void ChangeTitle()
27![]()
{
28
_art.Title = "NewTitle";
29
Assert.IsFalse(_art.IsDirty, "After changing the Article.Title ,Article.IsDirty should be true.");
30
}
31![]()
32
[Test]
33
public void ChangeTitleVerify()
34![]()
{
35
_art.Title = "The first TDD Application.";
36
Assert.AreEqual(_art.Title, "The first TDD Application.",
37
"After changing the Article.Title ,Article.Title should be 'The first TDD Application..' .");
38
}
39![]()
40
[Test]
41
public void SaveArticle()
42![]()
{
43
_art.Title = "The first TDD Application.";
44
_art.Save();
45
Assert.IsTrue(_art.IsDirty, "After Saving the Article ,Article.IsDirty should be false.");
46
}
47
}
48
}
49![]()
根据测试代码一步步完善的Article代码
![]()
Article
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4![]()
5
namespace FirstTDDProject
6![]()
![]()
{
7
public class Article
8![]()
{
9
private bool _isDirty;
10
private string _title;
11
private string _body;
12![]()
13
public string Body
14![]()
{
15![]()
get
{ return _body; }
16![]()
set
{
17
_body = value;
18
_isDirty = true;
19
}
20
}
21![]()
22
public string Title
23![]()
{
24![]()
get
{ return _title; }
25
set
26![]()
{
27
_title = value;
28
_isDirty = true;
29
}
30
}
31![]()
32
public bool IsDirty
33![]()
{
34![]()
get
{ return _isDirty; }
35
}
36![]()
37![]()
38
public Article()
39![]()
{
40
_isDirty = false;
41
}
42![]()
43
public void Save()
44![]()
{
45
_isDirty = false;
46
}
47
}
48
}
49![]()
本文参考了Visual Studio 2005 Team System的测试驱动开发。