Visual Studio 2005 进行单元测试
上一篇 / 下一篇 2006-12-11 17:34:48 / 天气: 晴朗 / 心情: 高兴 / 精华(3) / 置顶(3) / 个人分类:软件测试技术
每日随笔
- 每日随笔:今天开始学习如何使用VS进行单元测试,Fighting!!!!!!!!
sz)TA&M{051Testing软件测试网7NG;l#h3D$u5p]!_"F4Y
51Testing软件测试网1]6F3\8a!U?E
简介51Testing软件测试网!r+FY#d$|P3d
/^I9q.{&O%A+f0随着业务的革新和发展,运行它们的系统也需要进行更新。随业务的发展、革新以及与合作伙伴、客户和供应商的结合,这些系统将在复杂性方面持续扩增。51Testing软件测试网2jQ6|K6U'm
/Q"RVFj0这种复杂性迫使 IT 的领导者们在开发过程中(即,在实现之前)确保质量。有一种方法可使开发人员减少进入 QA 环节的故障数量,即,针对自定义代码严格执行自动化单元测试。在开发过程中强制使用自动化单元测试可为团队成员提供有关如何使用自定义代码的示例(这些示例易于使用并自行记录)。
%vj:sH}0
3sO:F;b,Pgt0z {0使用结构化、自动化单元测试面临的挑战之一是完成这些任务所需的代码总数。(测试代码需要使用大量代码!)代码生成的概念(简单定义为“创建软件的软件”)正随着时间的快速推移而逐渐深入到团队 IT 开发之中。有些人认为代码生成有助于缩短“推向市场”策略的时间,强制内部标准/协定,并促进开发过程。51Testing软件测试网Y p,X?0fQ0H6[-~2^/r
51Testing软件测试网T|9{m8CLqI
Microsoft 认识到这一需要后提供了一个功能丰富、带有下一代开发平台 Visual Studio 2005 Team System (VSTS) 的代码生成引擎。本文提供针对单元测试代码生成的循序渐进的指导,并深入探讨如何在用例中使用。
B Q!B~;},B0
iY.bZ[/l/P |0重新思考单元测试
3un@Ig4_l0T6}h0
5Xe F[S:e0请考虑以下情况:您负责为公司生成下一代系统,同时您是较大的开发团队中的一员。您是 UI 开发人员,负责尽可能多地创建 Microsoft ASP.NET/Microsoft WinForms。您依赖“中间层”团队完成其中间层组件 — 这些组件用于执行数据库 CRUD (Create-Retrieve-Update-Delete) 以及与该系统中每个实体相关的业务规则。
,Da U m2ObD f?0
4C[1OG$dKH sS0经过几周的 UI 开发,您完成了窗体并且收到了中间层开发人员打算向您提交其类库的消息。下面提供一段对话示例,说明我们大多数人在开发过程中都会遇到的一些事情。
h&bP-AL8Zn`0UI 开发人员和中间层开发人员间的示例对话51Testing软件测试网5d*S?f i'j1t
t`5O&?DF0中间层:51Testing软件测试网3d yPFh,k{gQu'E^
51Testing软件测试网 r3kj.m6q.g
R t;VyU|-GA[0“这些对象随时供您使用 — 为此,只需获取 OurSystemBL.dll 的最新版本。”51Testing软件测试网 h%Q/Ou2}o]
51Testing软件测试网(l$c3Kl"b
UI:
j0EB bYa(e2Dh0 51Testing软件测试网g*aB __P-z?@
51Testing软件测试网{0oA#\ J ~9X/p
“谢谢。您有供我们查看文档吗?”
a$atTq;p051Testing软件测试网2~.q;v },Y_A9K;TMU
中间层:51Testing软件测试网{\V$di|
%s+MCR8@[f%fq0
Q7RZ.dZ[0“哈哈!是的,当然有!我们花了很多时间编写它!请查看 Design Document — 噢,请等一等,它还没有完成……(不久之后即可完成!)”51Testing软件测试网0VI`IX"[ X
51Testing软件测试网u+MAy-U
UI:51Testing软件测试网X] O*@:] K
51Testing软件测试网J(fV Z*PD'`+b
%Wr/D G{m:L3\-Ez0“您使用 XML 文档了吗?”
(J:X0f|5Z i%G0
%XO+BpIN@0中间层:51Testing软件测试网 bwq:eNXk*^
8f d YT v'Bx#fv0
/k9d"qz;D&BFd2H0“在构造函数中,但许多方法都不使用。”51Testing软件测试网:t%w WUE]+V/n
roe%Ng7DZ4Y/M,S#e`0UI:
&azX:[KkA0 51Testing软件测试网_8q J4u2u!]Xj
51Testing软件测试网f&s!a)O'Mv$D
“显示如何创建、执行并删除对象的示例代码,怎么样?”
Z3N lQ X/x,T}j;[y051Testing软件测试网6mN6L+k@q9H
中间层:
Y}4E7j1o B0
X)n(K2QR2?*{051Testing软件测试网4kTu;vX'F
“我已经附加了一个示例 WinForms 应用程序(从我的工作区),它应该能够提供一些您所需的内容……,虽然它不在 Microsoft Visual SourceSafe 中。”51Testing软件测试网#U(V3W+I$|d@ ^6nZL
[8qHt0hJ Z;_kh0在考虑如何进行这样有趣的 项目之后,您打定了主意,决定检验中间层的单元测试套件。在深入钻研该代码之后,您注意到该窗体有两个未标记的文本框,以及三个标记为 button1、button2 和 button3 的按钮(幸运的话,它们将排列在窗体上)。接下来,在查看与这些按钮相关的事件之后,您认识到这些代码都未经注释,并且数据变量都被命名为 x、y、z。如果幸运,您还会注意到 button1 和 button2 执行该对象的 Save() 方法,而 button3 执行 Delete() 方法。执行时,您会接收到很多 System.Exception 错误,这是因为遗漏了很多配置设置。51Testing软件测试网-A5y&Pn#`o4]
51Testing软件测试网,\;QtrK_
这显然是一个特例,我希望多数开发团队不要进行这一试验,下面让我们看一下该方案中“单元测试”遇到的问题:51Testing软件测试网0Pi'\ u)}w+lP
• 51Testing软件测试网w0h-n;v9K8v#R
51Testing软件测试网tCVT4q!t,e
这种形式的单元测试代码不是结构化的:代码充斥到按钮单击事件中并且难以编译。
5G\5DU:Bu!M0•
:D(s9hiO7V#r6[*t#S051Testing软件测试网4V|J G.{-|@{S
这种形式的单元测试代码记录得不太好。
y4V,h8~2~0• 51Testing软件测试网T;~6w&jI^J&k
51Testing软件测试网1}L&C*x\/m[1x
这种形式的单元测试并不基于“已知”为好或坏的数据 — 它完全依赖于输入到那些未标记的文本框的内容。51Testing软件测试网;]%t }yYQ
•
w2z)sV*A_(h051Testing软件测试网GGm\PVQK
单元测试代码不能自动重复,它基于输入的代码。
TM3hL3x6I z![yY@0• 51Testing软件测试网&UQ~n2L(nm
8CT's` iF0单元测试代码覆盖是未知的 — 用数据指示实际测试的代码量。51Testing软件测试网7u*N'i`'G7\G B
• 51Testing软件测试网N DS/HwT
.J6W/X*X ttwR,Q0n0实现的详细信息不易于在团队成员间进行传播。
pRd}*~q"\"]0
4T5kdD~;d0输入自动化单元测试51Testing软件测试网 u#@%N+Jb9H(o1u
!X+n6C/K:_g ?M0xUnit 框架在 1998 年作为 eXtreme 编程的核心概念引入。它提出了一个有效的机制,有助于开发人员将结构化、有效且自动的单元测试添加常规开发活动中。从那以后,该框架演化为针对自动化单元测试框架的实际标准。51Testing软件测试网 N svLLc E
创建自动化单元测试的用例51Testing软件测试网I6d+b XT c Li
B$OG#pU+Nt0简单说,自动化单元测试是:51Testing软件测试网cH;v#ST3Do
•
'OG%Hvg`/`1]051Testing软件测试网p6Wh*?INC
结构化的。
$oO"]/M)I P }0•
EG+|lFpQb zq5wv051Testing软件测试网|M3N2x3o+zY%k
自行记录的。
`7hUd6R.C0• 51Testing软件测试网 q}{z*OJ)_{
51Testing软件测试网,XG9d0@7ZNB&SH
自动且可重复的。51Testing软件测试网CM K4`(YT
• 51Testing软件测试网&tC"g,gE q$}3_8_4N
|{1F7n*y]9P0基于已知数据。
%K't%`MS.~)V0• 51Testing软件测试网+Z'D.I#Z#k(b&II k o
51Testing软件测试网N'H6@+ed+M~/P
旨在测试积极和消极操作。
s0rSb4@\)T;d.k,I.N0• 51Testing软件测试网Uvu#_'KR\m j$D
` vI ]*t^A}0非常适合跨不同计算机的测试实现。
"GI}Pt,r`'cp4d0• 51Testing软件测试网(Y;c!F{N
51Testing软件测试网kf?5p9](P
配置、实现和执行的示例。
Zv}}2]Rq0xUnit 框架元素
[_a8YH%h e8e0
"\ Uizk H2w w0表 2 分析 xUnit 框架以及对应于 Visual Studio 2005 Team System 的 Unit Testing Framework 等价物的基本概念。51Testing软件测试网#G+e+n~9k$v`
表 2. 相应的 xUnit 框架和 VSTS Unit Testing Framework 概念
[,Z&mM3Giw+Y|0xUnit 框架概念 VS 2005 等价物(参见下面的属性) 描述
!fXZK ku-f051Testing软件测试网[^$Q*Z5YG qkk
测试51Testing软件测试网5n%Cvu3b
,rpF|zFb0
Ra(uyZh9tQ?0TestMethod
1FfaG6W-h0 51Testing软件测试网9WX{ M[x/r\
51Testing软件测试网#T%Y"sU^f1^`
简单说,这些是您的测试。测试预期结果的逻辑,并报告未取得结果(如果有)。请将它看作您的“方法”。51Testing软件测试网 H9p|iq F_i%H$i h
51Testing软件测试网 J,H arO0JT.B
测试装置
E"H-`eq#v0
MM*[9_%\Y+f051Testing软件测试网lSQ q)LOj
TestClass51Testing软件测试网 n ry \)KCnA
*u)S,u@!ywRJw051Testing软件测试网vq!NF%E#X
针对大量测试的一个逻辑分组。请将它看作您的“类”。51Testing软件测试网dKd[:p
F*s"J U H]1f3cz\0测试套件51Testing软件测试网HYU4K)dRK'v
^c ?*f(U M0
fXM?&F-Z,Ns0测试列表 **51Testing软件测试网LC0Yq'xf,b`"| I
51Testing软件测试网B?,O!@n5q
Q1EEco Py8k0针对大量测试装置的一个逻辑分组。请将它看作您的“类库”。51Testing软件测试网f]4|(d.sr
51Testing软件测试网k.BX!] q]iBUt
注不需要一个属性。51Testing软件测试网H:dx3n3y'v
({{{c%] N1Dj_ni0测试运行器51Testing软件测试网{6o gil+?u%d
51Testing软件测试网KxR8x^?
51Testing软件测试网g Z3J;w\B Hu
VS 2005 VSTS Unit Testing Framework51Testing软件测试网 P&UL9t,?
)G8`-j)d?!r&z0
JEG(Y#o{-h0GUI/Console 应用程序负责发现、执行和报告测试结果。Visual Studio 2005 Team System 将作为本文的测试运行器。51Testing软件测试网 FZC.U(@*_.pGP
测试装置示例
(bO*^~kZC]^,i051Testing软件测试网Nv2E&t&IR
请考虑以下针对 BankAccount 类的类关系图,以及一个示例测试装置 (BankAccountTests.cs)。
6~KvA!|8g)?051Testing软件测试网C{ };D^9{.y|b
图 1. BankAccount 类
NJpS-U,q%h)]qI0示例测试装置: BankAccountTests.cs51Testing软件测试网&S ob Aq5sT7K
N CY,`}7y p0using BankAccountDemo.Business;
Tt!x2[,R#tn q0using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;51Testing软件测试网_},Ta}}Iw
namespace BankAccountDemo.Business.Tests51Testing软件测试网A-k$~z8h+_ v
{
%|9X-pq[\0 [TestClass()]51Testing软件测试网:l7P H4{~6G XAhK
public class BankAccountTest
!]!P r^&p:D$A0 {
6RE*c`i1PK Y0 [TestInitialize()]
#I,qli6i0 public void Initialize() {51Testing软件测试网 J~QI b,o?E9me
}51Testing软件测试网w;E8DP/f H3o
[TestCleanup()]
Y xS}O^ut0 public void Cleanup() {
PBX}V[:jv,F0 }51Testing软件测试网~H3s7d%I?_(T
[TestMethod()]51Testing软件测试网6SIh1ur6x
public void ConstructorTest() {
B6Hze)R _Az%W0 float currentBalance = 500;51Testing软件测试网;a1[OqF5`i8Nr
BankAccount target = new BankAccount(currentBalance);
$mMj].D(C&QhV0 Assert.AreEqual(currentBalance, target.CurrentBalance,51Testing软件测试网 {p?~ X n)a;\-g#W
"Balances are not equal upon creation");
!F*u+A6iw6c8@9HK/^0 }51Testing软件测试网j+IbN0` B^
[TestMethod()]51Testing软件测试网z6y7X L"};F @/~9uc*p;C
public void DepositMoneyTest() {51Testing软件测试网/P-{*Nd3f ~+`sT
float currentBalance = 500;51Testing软件测试网#T#?2V.MK+x)C
BankAccount target = new BankAccount(currentBalance);51Testing软件测试网/L+nbt~hQ;w5Z_
float depositAmount = 10;51Testing软件测试网*g8~:eBngNW&G
target.DepositMoney(depositAmount);
a9Bn;k0JT2cR0 Assert.IsTrue( (currentBalance + depositAmount) > 51Testing软件测试网$BXN,kY.~&E^5hl5e
target.CurrentBalance,
C{1jpS emn0^0 "Deposit not applied correctly");51Testing软件测试网z/fq'e6R0wBC_f K
}
}$H:r"j9V0 [TestMethod()]51Testing软件测试网eB_Rm}i[RT7U z
public void MakePaymentTest() {
w7ge,y6IK(ZgF0 float currentBalance = 500;
j?LBY [0 BankAccount target = new BankAccount(currentBalance);
V\z(A FX0 float paymentAmount = 250;51Testing软件测试网E/I2Ffo G
target.MakePayment(paymentAmount);