一次简单的集成测试测试Card类,Card类需要使用Suit类和Cfg类,这两个类在这之前已经完成了测试。在这一步需要将三者集成在一起进行测试。在测试Card类时将不再考虑对Suti和Cfg类的测试,而仅仅是考虑Card类本身的测试,针对Card类的每一个方法进行测试。
使用Jtest自动生成测试代码,查看测试代码后发现,仅自动生成了部分测试代码,并且没有根据需要输入适合的值,我们需要手工完成部分测试代码。
从最复杂的一个方法开始入手。(当时我从最复杂的方法入手是因为有部分技术问题需要解决);getIcon方法返回某张纸牌所对应的图片文件,这里需要使用Cfg类,过程是根据牌的花色和分值计算出所对应的数组位置,因为返回的结果是一个Image类,所以在对比测试结果时有一些难度,而该数组并没有进行初始化,所以对比时不管测试结果如何对比的结果总是正确的。对此先对Cfg中的数组cardIcons进行初始化,这里仅始化正确结果的数组,最后进行与预期结果进行对比;代码示例如下:
Card card; //建立card类
Suit suit; //建立suit类
suit=Suit.CLUB; //suit引用
card=new Card(suit,'A'); //初始化card类
int ER=1; //预期位置是数组1
byte buffer[] = new byte[ER];
Cfg.cardIcons[ER]= Toolkit.getDefaultToolkit()。createImage(buffer);; //初始化数组1
Image RETVAL=card.getIcon();
assertEquals(Cfg.cardIcons[ER],RETVAL); //对比测试结果 |
注:如果不对Cfg中的数组进行初始化,则对比结果永远是正确的。
接下来对每一个方法进行测试,这些方法可以分为几类。
构造方法:
- Card()
- Card(final Card card)
- Card(Suit suit, char value)
|
赋值的方法:
- void assign (final Card rhs)
- boolean setSuit(Suit newSuit)
- boolean setType(char newType
|
取值的方法
- char cardType()
- Suit getSuit()
- String toString()
|
有效性判断
- final boolean isAce()
- final boolean isFaceCard()
- final boolean isValid()
- final boolean isValueCard()
|
运算
- boolean equals (Object obj)
- boolean lessThan(Card rhs)
- char suitAsChar()
- Image getIcon()
|
在这里发现当对某一个方法进行测试时可能会调用另一个方法。或者是在测试过程中需要借用另外的方法。那么这些方法本身是否有一个测试的先后顺序呢?例如:getIcon方法中调用了suitAsChar、isAce、isValueCard三个方法,先测试这三个方法是否正确,再测试getIcon方法是否正确,这样当getIcon方法出现错误时,可以确认是由于getIcon方法本身的错误还是由于suitAsChar、isAce、isValueCard三个方法中出现了错误。
手工完成每一个类的测试代码。可以使用Juint实现对已经完成的三个类的一次性完整测试。
集成测试在测试项目中加入Deck类,使用Jtest自动生测试代码。检查自动生成的测试代码发现有部分没有判断结果。对些需要手工改写测试代码。
测试AddDeck方法在测试过程中需要调用toString方法对结果进行判断。预期的结果是"Card
nums=52 [AH, 2H, 3H, 4H, 5H, 6H, 7H, 8H, 9H, TH, JH,
QH, KH, AD, 2D, 3D, 4D, 5D, 6D, 7D, 8D, 9D, TD, JD,
QD, KD, AS, 2S, 3S, 4S, 5S, 6S, 7S, 8S, 9S, TS, JS,
QS, KS, AC, 2C, 3C, 4C, 5C, 6C, 7C, 8C, 9C, TC, JC,
QC, KC]" 在测试AddDeck方法的同时也对toString方法进行了测试;
测试burnIt方法
public void testBurnIt1() throws Throwable
{
Deck deck=new
Deck();
deck.addDeck(1);
deck.burnIt();
String RET=deck.toString() ;
String Exp="Card nums=0 []";
assertEquals(Exp, RET);
} |
先增加一幅牌然后调用burnIt方法清除,使用toString方法取得返回结果,对返回结果进行判断。也可以使用getCards方法对测试结果进行判断。个人觉得getCards方法可能更加适合,因为该方法中并没有任何操作,不会对测试产生影响。下面的测试方法
会不会更好一些呢?
public void testBurnIt1() throws Throwable
{
Deck deck=new Deck();
deck.addDeck(1);
deck.burnIt();
Vector RET=deck.getCards();
assertEquals(0, RET.size());
} |
测试getCard方法testGetCard1测试使用取边界值与预期值进行比较判断测试正确性的测试策略。下例为取第一个值;
public void testGetCard1() throws Throwable
{
Deck deck=new Deck();
deck.addDeck( 1);
Card card=deck.getCard();
Card card2=new Card();
boolean RET1=card.equals( card2);
assertEquals(true,RET1);
} |
下面的例子中,测试了Deck类的异常情况;在测试过程中测试出现异常(不是错误)。对于这个例子我们是否需要考虑这种特殊情况呢?在BJ
这个项目中会不会出现不增加牌而使用牌的情况呢?对于这种情况是否需要考虑程序的整体架构呢?(这种异常可能会由其他的代码来处理)
public void testGetCard3() throws Throwable
{
Deck deck=new Deck();
Card card = null;
card=deck.getCard();
assertEquals(null,card);
} |
测试getCards方法testGetCards1测试用例判断返回长度是否正确;
public void testGetCards1() throws Throwable
{
Deck deck=new Deck();
deck.addDeck(1);
Vector deckcard=deck.getCards();
assertEquals(52,deckcard.size());
}
|
testGetCards2测试用例从返回的结果中取任意值判断内容是否正确;
public void testGetCards2() throws Throwable
{
Deck deck=new Deck();
deck.addDeck(1);
Vector deckcard=deck.getCards();
Card card=(Card) deckcard.elementAt(1);
String RET=card.toString();
assertEquals("2H",RET);
} |
测试shuffle方法testShuffle1用例测试在未增加牌时shuffle方法是否会出错;
public void testShuffle1() throws Throwable
{
Deck deck=new Deck();
deck.shuffle();
Vector RET=deck.getCards();
assertEquals(0, RET.size());
} |
testShuffle2用例测试洗牌后纸牌的内容有没有丢失或改变;代码中使用了穷举的方法,验证每一张牌是否真实存在。是否有更好的测试方法呢?
public void testShuffle2() throws Throwable
{
Deck deck=new Deck();
Deck deck2=new Deck();
deck.addDeck( 1);
deck2.addDeck( 1);
Vector carddeck= deck.getCards();
Vector carddeck2= deck2.getCards();
deck.shuffle();
Card card,card2;
boolean RET;
for(int j=0;j<52;j++){
card=(Card) carddeck.elementAt( j);
RET=false;
for(int i=0;i<52;i++){
card2=(Card) carddeck2.elementAt(i);
if(card2.toString().equals( card.toString()))
RET=true;
}
assertEquals(true,RET);
}
} |
testShuffle3用例测试洗牌后牌的数量是否错误。
public void testShuffle3() throws Throwable
{
Deck deck=new Deck();
deck.addDeck( 1);
deck.shuffle();
Vector RET=deck.getCards();
assertEquals(52, RET.size());
} |
注:由于在源代码中已经注明只使用一幅牌,所以测试过程中未考虑牌多于一幅的情况;
思考问题:
是否考虑异常情况?在本次的例子中,当不增加纸牌而取某一张牌时会出现错误,但是否有必要进行这种测试?
在getCard方法中如果测试者不知道Card类如何使用,那么将无法对测试结果进行判断。当设计文档编写的不够细致时会不会对白盒测试阻碍,这个阻碍会有多大呢?
测试shuffle方法是否有更好的方法呢?类似这种情况在实际应用中可能会很多,有时可能无法使用穷举、边界值、分类等方法来进行测试,这时应该如何进行测试呢?
由于测试代码的增多,提高了错误存在于测试代码中的风险,这时应该如何处理呢?
考虑testBurnIt1测试,当toString方法改变时,可能会引起testBurnIt1测试失败,这样会增加测试代码的维护难度,应该如何解决这一问题呢?
|