全面接触TDD - 1. 第一个基于TDD的程序

一、要记住的一些东西
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中的测试项目)

ContractedBlock.gif ExpandedBlockStart.gif ArticleTest
 1None.gifusing System;
 2None.gifusing System.Text;
 3None.gifusing System.Collections.Generic;
 4None.gifusing Microsoft.VisualStudio.TestTools.UnitTesting;
 5None.gif
 6None.gifnamespace FirstTDDProject
 7ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 9InBlock.gif    /// ArticleTest 的摘要说明
10ExpandedSubBlockEnd.gif    /// </summary>

11InBlock.gif    [TestClass]
12InBlock.gif    public class ArticleTest
13ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
14InBlock.gif        
15InBlock.gif
16InBlock.gif        public ArticleTest()
17ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
18ExpandedSubBlockEnd.gif        }

19InBlock.gif
20ContractedSubBlock.gifExpandedSubBlockStart.gif        其他测试属性#region 其他测试属性
21InBlock.gif        //
22InBlock.gif        // 您可以在编写测试时使用下列其他属性:
23InBlock.gif        //
24InBlock.gif        // 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
25InBlock.gif        // [ClassInitialize()]
26InBlock.gif        // public static void MyClassInitialize(TestContext testContext) { }
27InBlock.gif        //
28InBlock.gif        // 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
29InBlock.gif        // [ClassCleanup()]
30InBlock.gif        // public static void MyClassCleanup() { }
31InBlock.gif        //
32InBlock.gif        // 在运行每个测试之前使用 TestInitialize 运行代码 
33InBlock.gif        // [TestInitialize()]
34InBlock.gif        // public void MyTestInitialize() { }
35InBlock.gif        //
36InBlock.gif        // 在运行每个测试之后使用 TestCleanup 运行代码
37InBlock.gif        // [TestCleanup()]
38InBlock.gif        // public void MyTestCleanup() { }
39InBlock.gif        //
40ExpandedSubBlockEnd.gif        #endregion

41InBlock.gif
42InBlock.gif        protected Article _art;
43InBlock.gif        [TestInitialize()]
44ExpandedSubBlockStart.gifContractedSubBlock.gif        public void Initialize() dot.gif{
45InBlock.gif            _art = new Article();
46ExpandedSubBlockEnd.gif        }

47InBlock.gif
48InBlock.gif        [TestMethod]
49InBlock.gif        public void CheckIsDirty()
50ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
51InBlock.gif            Assert.IsFalse(_art.IsDirty);
52ExpandedSubBlockEnd.gif        }

53InBlock.gif
54InBlock.gif        [TestMethod]
55InBlock.gif        public void ChangeTitle()
56ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
57InBlock.gif            _art.Title = "NewTitle";
58InBlock.gif            Assert.IsTrue(_art.IsDirty, "After changing the Article.Title ,Article.IsDirty should be true.");
59ExpandedSubBlockEnd.gif        }

60InBlock.gif
61InBlock.gif        [TestMethod]
62InBlock.gif        public void ChangeTitleVerify()
63ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
64InBlock.gif            _art.Title = "The first TDD Application.";
65InBlock.gif            Assert.AreEqual(_art.Title, "The first TDD Application.",
66InBlock.gif                "After changing the Article.Title ,Article.Title should be 'The first TDD Application..' .");
67ExpandedSubBlockEnd.gif        }

68InBlock.gif
69InBlock.gif        [TestMethod]
70InBlock.gif        public void SaveArticle()
71ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
72InBlock.gif            _art.Title = "The first TDD Application.";
73InBlock.gif            _art.Save();
74InBlock.gif            Assert.IsFalse(_art.IsDirty, "After Saving the Article ,Article.IsDirty should be false.");
75ExpandedSubBlockEnd.gif        }

76ExpandedSubBlockEnd.gif    }

77ExpandedBlockEnd.gif}

78None.gif

使用NUint编写的单元测试

ContractedBlock.gif ExpandedBlockStart.gif ArticleTestWithNUnit
 1None.gifusing System;
 2None.gifusing System.Collections.Generic;
 3None.gifusing System.Text;
 4None.gifusing NUnit.Framework;
 5None.gif
 6None.gifnamespace FirstTDDProject
 7ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 8InBlock.gif    [TestFixture] 
 9InBlock.gif    public class ArticleTestWithNUnit
10ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
11InBlock.gif        
12InBlock.gif        protected Article _art;
13InBlock.gif        [SetUp]
14InBlock.gif        public void Init()
15ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
16InBlock.gif            _art = new Article();
17ExpandedSubBlockEnd.gif        }

18InBlock.gif
19InBlock.gif        [Test]
20InBlock.gif        public void CheckIsDirty()
21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
22InBlock.gif            Assert.IsFalse(_art.IsDirty);
23ExpandedSubBlockEnd.gif        }

24InBlock.gif
25InBlock.gif        [Test]
26InBlock.gif        public void ChangeTitle()
27ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
28InBlock.gif            _art.Title = "NewTitle";
29InBlock.gif            Assert.IsFalse(_art.IsDirty, "After changing the Article.Title ,Article.IsDirty should be true.");
30ExpandedSubBlockEnd.gif        }

31InBlock.gif
32InBlock.gif        [Test]
33InBlock.gif        public void ChangeTitleVerify()
34ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
35InBlock.gif            _art.Title = "The first TDD Application.";
36InBlock.gif            Assert.AreEqual(_art.Title, "The first TDD Application.",
37InBlock.gif                "After changing the Article.Title ,Article.Title should be 'The first TDD Application..' .");
38ExpandedSubBlockEnd.gif        }

39InBlock.gif
40InBlock.gif        [Test]
41InBlock.gif        public void SaveArticle()
42ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
43InBlock.gif            _art.Title = "The first TDD Application.";
44InBlock.gif            _art.Save();
45InBlock.gif            Assert.IsTrue(_art.IsDirty, "After Saving the Article ,Article.IsDirty should be false.");
46ExpandedSubBlockEnd.gif        }

47ExpandedSubBlockEnd.gif    }

48ExpandedBlockEnd.gif}

49None.gif

根据测试代码一步步完善的Article代码

ContractedBlock.gif ExpandedBlockStart.gif Article
 1None.gifusing System;
 2None.gifusing System.Collections.Generic;
 3None.gifusing System.Text;
 4None.gif
 5None.gifnamespace FirstTDDProject
 6ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 7InBlock.gif    public class Article
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 9InBlock.gif        private bool _isDirty;
10InBlock.gif        private string _title;
11InBlock.gif        private string _body;
12InBlock.gif
13InBlock.gif        public string Body
14ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
15ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _body; }
16ExpandedSubBlockStart.gifContractedSubBlock.gif            set dot.gif
17InBlock.gif                _body = value;
18InBlock.gif                _isDirty = true;
19ExpandedSubBlockEnd.gif            }

20ExpandedSubBlockEnd.gif        }

21InBlock.gif
22InBlock.gif        public string Title
23ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
24ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _title; }
25InBlock.gif            set 
26ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
27InBlock.gif                _title = value;
28InBlock.gif                _isDirty = true;
29ExpandedSubBlockEnd.gif            }

30ExpandedSubBlockEnd.gif        }

31InBlock.gif
32InBlock.gif        public bool IsDirty
33ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
34ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _isDirty; }
35ExpandedSubBlockEnd.gif        }

36InBlock.gif
37InBlock.gif
38InBlock.gif        public Article()
39ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
40InBlock.gif            _isDirty = false;
41ExpandedSubBlockEnd.gif        }

42InBlock.gif
43InBlock.gif        public void Save()
44ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
45InBlock.gif            _isDirty = false;
46ExpandedSubBlockEnd.gif        }

47ExpandedSubBlockEnd.gif    }

48ExpandedBlockEnd.gif}

49None.gif


本文参考了Visual Studio 2005 Team System的测试驱动开发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值