不要追求绝对的公平,红尘之中没有公平而言,人活一世,难得糊涂。                                           it is no use doing what you like, you have got to like what you do.

6. StandardBlackJackHand类测试

上一篇 / 下一篇  2007-02-25 10:51:34 / 个人分类:单元测试

6. StandardBlackJackHand类测试
}5rs;TzR051Testing软件测试网 @UzA%CrJx{l
第六步:StandardBlackJackHand类测试
$b mJERwh["j0StandardBlackJackHand是一个抽象类,用来实现BlackJackHand接口。Jtest无法直接对抽象类进行测试,同时接口中没 有任何代码只需要进行代码走查即可。PlayerHand类继承了StandardBlackJackHand类,同时完成了 StandardBlackJackHand部分未实现的接口代码。51Testing软件测试网szq,@q!d
51Testing软件测试网p1uVWb'S#D| Q
如果通过PlayerHand类测试StandardBlackJackHand中已经实现的接口代码,这种方式不利于测试代码的维护,当PlayerHand进行方法重载时,测试代码需要进行相应的调整,并且从测试关系上看,无法清晰的看出测试关系。
$ch*i*M4jx051Testing软件测试网gWf3\*a @e6t
例:
%xN.r,]8m|j1z/GR3[ C0
3{t;T%t#A^"\/m'oS;`0public interface  BlackJackHand
pk3SvLMk0
NSoY%gu(Q0{51Testing软件测试网'f jwA7U!?c W

8aE,^%J6J Qj]0  public int lowCount();51Testing软件测试网Y os2?8r8ib0M

.i,?3s,HljF5iZ0  public int highCount();51Testing软件测试网u `!{.sgv9k/K g
51Testing软件测试网l4j,^y)H Tw%@
}
s FgUF9cE051Testing软件测试网H/y O)L.R1|
abstract class StandardBlackJackHand implements BlackJackHand51Testing软件测试网,a+U9tyk4X]
51Testing软件测试网s(bnu }hm
{51Testing软件测试网/a&`N-c5He8s o

I R"FZ3W2bS0  public int lowCount (
JC&E6h+Rod0
'iC:H o7e#WAo0  {51Testing软件测试网*f)EwjmM{S-P~H
51Testing软件测试网 av]/I4zQ"u
        //实现代码
7e'q$d;Z?Z[3t0
4w\,YE'fZ.B0  }
OD)H;O P*~#t O tq051Testing软件测试网?1aGMlW#y(z
}
)_;D'E+wI}051Testing软件测试网r4\_5xw\,_%^
class PlayerHand extends StandardBlackJackHand
~ S5U2c2m`051Testing软件测试网9j@cmW eo+@Ld
{51Testing软件测试网7gDt5b BF.Ha:j0~

3_0T$QARKI$d \0  public int highCount(){
9nkl4C9A4M!|&iP0
*Mn| }0B*gL0        //实现代码51Testing软件测试网JUk$mo-sV

5A.{*cp1wx1H])c0  }51Testing软件测试网IU6NoXc

,w#`b}|I QO0}
6N0}w*U X/~;XW0
C C-a!N|/t8v;AoAO1}0上例中我们可以通过PlayerHand类对lowCount方法进行测试,这时我们希望的是StandardBlackJackHand类中的 lowCount方法,但是当lowCount方法被重载后,则测试目标发生了变化,导致测试错误。同时从测试代码上看不出测试目标 StandardBlackJackHand类中的lowCount方法。51Testing软件测试网+`!NLW SQ'w
51Testing软件测试网(]k%Bb5{6N|
为了解决这种问题是否可以自己写一个TestBlackJackHand类,将StandardBlackJackHand类中所有方法实现代码拷贝到 TestBlackJackHand类中,同时补充未实现的接口,这样做起来非常麻烦,不利于我们后期要考虑的自动测试方法
oH{Ev0
)h)k4Z{b0如果采用继承的方法使用TestBlackJackHand继承则同样可以完成测试,但是Jtest计算代码覆盖率时是按 TestBlackJackHand类的实现方法和重载方法进行覆盖就率计算。以PlayerHand类为例,不会计算lowCount方法的代码覆盖 类,因为lowCount方法是TestBlackJackHand类中的代码。
0S{Pt9q#\051Testing软件测试网 iC(LCF9a@$z
为了完成StandardBlackJackHand类的测试,建立了一个TestStandardBlackJackHand类,类中的方法从StandardBlackJackHand类中拷贝过来。这样可以实现代码覆盖率的计算。
2S coQz#dWW051Testing软件测试网D+[w Ne$c)O
public class TestStandardBlackJackHand implements BlackJackHand51Testing软件测试网 ~/t%Ia/vc'D j

/K{2w3Z ]y*\0使用Jtest自动生成部分测试代码,然后进行手工修改和添加。在StandardBlackJackHand类中使用了Card类,Jtest无法对预期值与输入值进行自动判断,所以有大部分测试代码是无用的,需要手工进行修改。
w9NS+I6t u^ r051Testing软件测试网;d h1| V(Ulr
在测试getIdentity方法时使用了构造函数,将构造函数与getIdentity方法在一段测试代码中完成测试。
1l+yUS{^] Y0
M rwL9yn1\"pg6w0OfferInsurance、draw、takeTurn 三个方法没有实现代码,为了确保代码覆盖率计算正确,仍然为这三个方法实现了测试代码,只是代码中并没有判断预期结果。51Testing软件测试网C~Be'\
51Testing软件测试网Y9lD,wZMG6b$g
StandardBlackJackHand类中多次使用了Card类,如果我们不对Card类进行测试,在无法进行完全测试的情况,容易造成测试逃逸。51Testing软件测试网rJ%`!j9ZPw
51Testing软件测试网ZC_!V_v
例:在下面这段代码中,使用了Card类,如果我们测试设置时没有使用面值Q的纸牌进行测试(不可能进行完全测试),同时card.isFaceCard ()存在错误导致Q不能被正确计算,这时就会产生测试逃逸。如果同时进行了Card类测试,则可以发现该测试逃逸将被捕获。这表明了测试设计者在设计测试 用例时一定要对产品代码有深入的了解。
^+R9@1B n0
W+mT3b0e&R0int singleCardCount(final Card card,boolean highCount){
A%j;ha!A,`051Testing软件测试网"zq6V+e2b|hA
        int count = 0;51Testing软件测试网xbY H R-w;Wl
51Testing软件测试网yM6kj-I6VGn!s
        if( card.isAce() )
`R*Lji0
,S(\(C#AT*A&d xQ w0                  count += highCount ? 11 : 1 ;
!nZV%?'I&F051Testing软件测试网AEN|g
        else if ( card.isFaceCard() || card.cardType() == 'T')51Testing软件测试网Adj5f Q$py+i!_#{

s,@0G]Z+C1f0                  count += 10;51Testing软件测试网2O,}w;b+SS$g
51Testing软件测试网#We5aK2B8r|h
                  else51Testing软件测试网9B!HK l%TRXz3Nw

C"} Dl gR8g },};Y0                  {
~4y|+C:\X }DA1[051Testing软件测试网\d[1c Soq8K W4GW M
count = count + card.cardType() - '0';
n\^&RaY^ H051Testing软件测试网6N2WQ@5Qe
                  }
}w_ Y!]WL/D)T0
3v ~'|HqP0        return count;
m2e#S W])w%YG-z051Testing软件测试网qk3Zd%E8a
  }
3|,q VA-H'TDz u M!p0
6SEt^'] } B?M"J0根据每个方法的需求设计相应的测试用例。(测试代码略)51Testing软件测试网x_5wTx;D j)F-t
51Testing软件测试网X4J ? } kAP2A
详细设计文档不明确将会导致测试设计失败,例如highCount方法,用来计算最高分,如果没有明确说明计算方法,则会造成测试失败或者是测试逃逸。 BJ这个项目中当牌面是A时有两种计算方法,一种是1分一种是11分,当有两张A时总分值是12分,如果详细设计文档中没有说明这种情况,测试设计者也许 不会考虑这种情况,这将会造成测试逃逸。
0lo pPq!l-L\H"T051Testing软件测试网'A?#a(DqL,{
在测试isBlackJack这个方法时不能简单的考虑边界值的情况,这可能会测试冗余。BLACKJACK牌型:A+10、A+J、A+Q、A+K,按 常规考虑需要测试这四种情况,但是在程序的实现代码中,只要测试一种就可以满足(前提是前面已经完成了相关类的测试)。根据代码,isBlackJack 调用highCount方法,highCount方法调用totalCardCoun方法,totalCardCoun方法调用 singleCardCount方法,singleCardCount方法调用card.isFaceCard方法和card.cardType方法,经 过一系列操作完成BLACKJACK牌型判断。测试isBlackJack方法只需要A+10、A+J、A+Q、A+K任意一组就可以,不需要将四种情况 全部测试。
KCQ^Q#H%X0p+B0
kq4Iy#_Nz R0  public boolean isBlackJack()51Testing软件测试网0l |V y5W E f
51Testing软件测试网(Al9cw i2fw
  {
F-]HG K%s"GY051Testing软件测试网J9C"p$a,rBka M
        return ( (hand.size() == 2) && (highCount() == 21 ) );
T vp+R~+c)Y0m051Testing软件测试网T2G Om@ i
  }51Testing软件测试网7@mM_)H Uk1Mb8Y
51Testing软件测试网 ^bZ'K7MLc[ME
public int highCount()51Testing软件测试网)~`7ZJ&} f9L
51Testing软件测试网BL6}T!Z"v8H/K*_
  {51Testing软件测试网%O-b G,u_ Fz"Y

dxL?R3CG(L;^m0        return totalCardCount(true);
;C| _6~ k~2u0
p9`/f5U4oE%g0  }
'A,xwm8N}o,q#wH0
0R3[.fn6gE7ur0  private int totalCardCount(boolean highCount)
*WUR:dBq"S8]051Testing软件测试网 Y(a%I3i]#Z
  {51Testing软件测试网,P O"mV-yF])y Y
51Testing软件测试网!W8L@'C6n^y
        int count = 0;51Testing软件测试网;vR q/OA\#b
51Testing软件测试网7E)b6rj RZcX*ea:dY
        int numAces = 0;            
}T9Y+t%{W&}D$mR0
*E%_ EiJi"o0        for(Enumeration e = hand.elements();e.hasMoreElements();)
;rF/w.gpo051Testing软件测试网2}#\;[ C*gM
        {
'b6y x_7`1`7R051Testing软件测试网^8f-\qYm
                  Card card = (Card)e.nextElement();51Testing软件测试网(Q(k8D"H"i l N

1R3EwTV_p0  
/[4]O6l r:{m%w051Testing软件测试网u*x'D;Y~E%R
                  //老A的个数51Testing软件测试网C m*`@-P[
51Testing软件测试网+v End D.]9s
                  if(card.isAce())
7FB HI6m:H!N(?P051Testing软件测试网Y{E4}f
                        numAces++;        
/H2o _(j`051Testing软件测试网N rt A3m
                  count += singleCardCount(card, false);
bd&gcA0
pnQ4WoO { SF0          }
)A/j ~:tR E051Testing软件测试网%G*p2wGGjy7]D ?
        if(highCount && count <= 11 && numAces > 0)
f)N(L6j'y*w W,e051Testing软件测试网 Vd i'u:uzF#b
                  count += 10;51Testing软件测试网%JH2A}.Oc$U8G9G_c

xo6g_P&V0        return count;
0mo-Q(K?PZ051Testing软件测试网5HQ9g[p5s l'C-x6b9o
  }
T1t*j%y.?xe0
R)G8Q;MjP0   int singleCardCount(final Card card,boolean highCount)51Testing软件测试网@j/Q6V(]^5b%d'V

}n'n*Q]0  {51Testing软件测试网{ZP(k7F6D~

h:BEbo0        int count = 0;
T7X0C!B @ i051Testing软件测试网 kV,ve@ RBi
        if( card.isAce() )
/W4o9A:FL6OUk;kquJ8s0
uSa`0Vf _;u0                  count += highCount ? 11 : 1 ;
HeX R/?0
$e9AIrB*n*P0        else if ( card.isFaceCard() || card.cardType() == 'T')51Testing软件测试网|9l%]+YuA

.Mw U#}^6x)o0                  count += 10;51Testing软件测试网wTX2{2Z(^r
51Testing软件测试网2N$FHYw\+~
                  else51Testing软件测试网3s d)qe9N xo;cu

,K*Fjvy,H0                  {
Nj4}Q ~LE0
:wL7Q`A0                        count = count + card.cardType() - '0';51Testing软件测试网2L.@_9Jx#|
51Testing软件测试网$f+{:P0m O(Hl6Tc h
                  }
o:w"]"e7yG9R051Testing软件测试网 I:v.FNx L+w[w(q"_
        return count;51Testing软件测试网k8h x;y5t.a/c _

Q&i6d8D9^R&w0  }51Testing软件测试网5_W8Z fj9o
51Testing软件测试网Tr7D&v N
当研究进行到现在时发现白盒测试对于错误定位、分析非常方便,在这一方面明显优于黑盒测试。如果采用黑盒测试方法,当发现分值计算错误时对于问题原因的定位非常困难,并且错误重现比较困难,因为牌是随机分布的。
0@l(f2o5}p[1\cQ0
5UjaV:T;Q0第六步具体的操作写得没那么详细,只是对研究过程所走的弯路进行了描述。51Testing软件测试网%X~-kFgr [}V*e

j+Y [b0d0当完成StandardBlackJackHand类测试完成后,已经可以将前面所测试的类联合起来形成了一个整体,对BJ这个项目在编程思路上有了一些 较为深入的了解,同时也感觉到白盒测试对于问题的定位非常高效,执行回归测试的性能也非常好。但这不等于白盒测试可以完全取代黑盒测试,以后的研究会加以 详细的说明51Testing软件测试网p C+x,]8A

$[/K-pp4fKU0思考问题:
5Lz tW yp%ZA p V0·         在某些设计过程中是否可以不考虑边界值呢?在singleCardCount方法中实际是以条件覆盖来进行测试设计的。51Testing软件测试网*W9gb)di7M
51Testing软件测试网)_` B$e Jw,\I
·         如何确定什么时候不需要使用边界值呢?例如isBlackJack方法。

TAG: 单元测试

 

评分:0

我来说两句

Open Toolbar