android自动化测试03—基于junit的android测试框架

来源:互联网 发布:web数据挖掘 bing liu 编辑:程序博客网 时间:2024/06/14 15:40

        本系列的前两篇文章对menkey和junit做了比较详细的介绍,这一篇将开始介绍基于junit的andriod测试框架,主要内容来源于网络。

1、JUnit概述

Android SDK 1.5已经将JUnit包含进来了,但是一直没有去深入了解,以前在使用一些C++的开源库中学习过与CPPUnit,简要分析过其主要框架,如下:


         这次在学习Android SDK 1.6中的例子程序APIDemoes中的过程中,看到了一个test文件夹,似乎就是使用了JUnit,于是就开始学习Android中如何使用JUnit。APIDemoes\test文件夹下的测试代码相对比较复杂,我们会循序渐进的学习,逐步深入的理解,在后面为大家详细解析如何阅读这些测试代码,本篇幅就初步解析JUnit。
1.1 什么是 JUnit ?
        JUnit是采用测试驱动开发的方式,也就是说在开发前先写好测试代码,主要用来说明被测试的代码会被如何使用,错误处理等;然后开始写代码,并在测试代码中逐步测试这些代码,直到最后在测试代码中完全通过。

现简要说JUnit的4大功能

  • 管理测试用例。修改了哪些代码,这些代码的修改会对哪些部分有影响,通过JUnit将这次的修改做个完整测试。这也就JUnit中所谓的TestSuite。
  • 定义测试代码。这也就是JUnit中所谓的TestCase,根据源代码的测试需要定义每个TestCase,并将TestCase添加到相应的TestSuite方便管理。
  • 定义测试环境。在TestCase测试前会先调用“环境”配置,在测试中使用,当然也可以在测试用例中直接定义测试环境。
  • 检测测试结果。对于每种正常、异常情况下的测试,运行结果是什么、结果是否是我们预期的等都需要有个明确的定义,JUnit在这方面提供了强大的功能。
        以上部分与我们平常使用IDE调试的过程是完全一样的,只不过是增加了测试用例管理、测试结果检测等功能,提高了单元的效率,保证了单元测试的完整性,明确了单元测试的目标。

2、JUnit例子分析

在前面的初步解析中,我们简要了解了JUnit的主要功能:
管理测试用例;
定义测试代码;
定义测试环境;
检测测试结果;

结合主要功能,举个简单的例子分析如下:

SampleCalculator.java

[java] view plaincopy
  1. public class SampleCalculator  
  2. {  
  3.     public int add(int augend , int addend)  
  4.     {return augend + addend ;}  
  5.     public int subtration(int minuend , int subtrahend)  
  6.     { return minuend – subtrahend ;}  
  7. }  
测试用例(TestCase):

[java] view plaincopy
  1. import junit.framework.TestCase;  
  2. public class TestSample extends TestCase  
  3. {  
  4. private int a;  
  5. private int b;  
  6. private int r1,r2;  
  7. void setUp() /*开始测试当前用例–初始化测试环境*/  
  8. {  
  9. a = 50;  
  10. b = 20;  
  11. r1 = 70;  
  12. r2 = 30;  
  13. }  
  14. void tearDown()/*当期用例测试结束*/  
  15. {}  
  16. public void testAdd()/*测试SampleCalculator 类的Add函数*/  
  17. {  
  18. SampleCalculator calculator = new SampleCalculator();  
  19. int result = calculator.add(a , b);  
  20. assertEquals(r1 , result);/*检测测试结果*/  
  21. }  
  22. public void testSubtration()/*测试SampleCalculator 类的Subtration函数*/  
  23. {  
  24. SampleCalculator calculator = new SampleCalculator();  
  25. int result = calculator.subtration(a , b);  
  26. assertEquals(r2 , result);/*检测测试结果*/  
  27. }  
  28. }  
以上TestSample测试用例中就对SampleCalculator进行了完整的单元测试,并对测试结果做了预期说明。
TestCase的管理

[java] view plaincopy
  1. import junit.framework.Test;  
  2. import junit.framework.TestSuite;  
  3. public class TestAll  
  4. {  
  5. public static Test suite()  
  6. {  
  7. TestSuite suite = new TestSuite(“TestSuite Test”);  
  8. suite.addTestSuite(TestSample.class);  
  9. return suite;  
  10. }  
  11. }  
        以上就将TestSample增加到“TestSuite Test”中,将来在选择测试用例的过程中只要选择了TestSuite Test,TestSample就将加入当前测试中。如果将来SampleCalculator增加了其他功能,只需要在TestSample增加相应的测试代码。
      最后需要说明的:对TestCase的管理,是完全界面化的,JUnit会自动产生UI界面,运行以上测试的例子,JUnit的界面如下:


    可能还需要下载JUint packeage,最后送给大家一句话:大胆尝试下,你会发现编程真的可以如此“美好”。

3、基于junit的android测试框架(junit.framework包

          通过前面两节的学习,我们对JUnit有了初步的认识,下面我们将深入的解析JUnit数据包。整个JUnit的数据包应该是很强大的,但是一般来说,不一定每个工程都需要这些数据包,而是在JUnit部分数据包的基础上扩展出自己的数据包,Android SDK中也不例外。至于JUnit完整的包,这里我们就不详细分析了,我们这里只解析Android SDK中包含的那些JUnit数据包,以及Android SDK在JUnit的基础上扩展的一些数据包,如下:


        在这些包中最为重要的是:junit.frameworkandroid.test,其中前者是JUnit的核心包,后者是Andoid SDK在Junit.framework的基础上扩展出来的包,我们将重点解析这2个包。

首先解析junit.framework包,结构如下:


通过这张图,大家就可以比较清晰的看到JUnit的主要框架,再回去看下上篇文章的例子,对前面的例子感觉明白多了。做个简要的总结,如下:

  • TestSuit:TestSuite是测试用例的集合;
  • TestCase:定义运行多个测试用例;
  • TestResult:收集一个测试案例的结果,测试结果分为失败和错误,如果未能预计的断言就是失败,错误就像一个ArrayIndexOutOfBoundsException异常而导致的无法预料的问题;
  • TestFailure:测试失败时捕获的异常;
  • Assert:断言的方法集,当断言失败时显示信息;
        TestCase与TestSuite之间的关系,有些类似于图元对象与容器对象之间的关系,在面向对象的语言C++、JAVA中较常见,在这里就不多说了。

举个简单的例子,并简要说明过程
第一步:实现TestCase

[java] view plaincopy
  1. //继承父类TestCase;  
  2. //定义一下变量在测试中使用;  
  3. //在setUp()中初始化这些变量;  
  4. //在tearDown()中清理这些变量;  
  5. public class MathTest extends TestCase{  
  6. protected double fValue1;  
  7. protected double fValue2;  
  8. protected void setUp(){  
  9. fValue1= 2.0;  
  10. fValue2= 3.0;  
  11. }  
  12. }  
  13. //编写测试单元代码;  
  14. public void testAdd() {  
  15. double result= fValue1 + fValue2;  
  16. assertTrue(result == 5.0);  
  17. }  
  18. //运行测试用例,这里有2种方法可以使用:  
  19. //静态类型:覆盖runTes()和定义测试函数。最常用的就是采用java的匿名类,如下:  
  20. TestCase test= new MathTest(“add”){  
  21. public void runTest() { testAdd();}  
  22. };  
  23. test.run();  
  24. //动态类型:使用反射来实现runTest,它动态地发现并调用的方法,在这种情况下,测试案例的名字对应的测试方法来运行,如下:TestCase= new MathTest(“testAdd”);  
  25. test.run();  
  26. //相比之下,第2种更符合面向对象的思维。  
第二步:将TestCase添加到TestSuilt
           TestSuite suite= new TestSuite();
           suite.addTest(new MathTest("testAdd"));
由于TestSuite可以自动从TestCase中提取测试单元并运行,也可以用如下方法:
           TestSuite suite= new TestSuite(MathTest.class);
一个测试用例就完成了,想要更加详细的了解junit.framework,还是到Android SDK中仔细阅读。
看了这些代码,再仔细看下JUnit的结构图,是不是感觉更加清晰了,下面我们将深入解析android.test包。
4、基于junit的android测试框架(android.test包

        前面我们学习了junit.framework包,本篇幅我们开始学习android.test包,了解Android SDK是如何扩展junit.framework包。

首先整理android.test包的结构,如下图所示:


        在前面的篇幅中说明过:TestCase与TestSuite之间的关系,有些类似于图元对象与容器对象之间的关系。有了这个思想,顺着这张的主线图从上往下看:首先看到的是TestCase类,接着看到InstrumentationTestCase、AndroidTestCase,最后看到ApplicationTestCase,ProviderTestCase2,ServiceTestCase,ActivityTestCase。这不就是Android 系统中4大组成元素:Activity、Provider、Service、BroadCast中的前3个,然后我们在看下Android SDK中的说明:


        这些类就不在这里说明,应该与我们平时使用Activity、Service、Provider基本一样。下面举个例子,来说明如何使用这些类,我们就将上一篇J2SE测试例子,在Android中实现:

[java] view plaincopy
  1. public class MathTest extends AndroidTestCase   
  2. {  
  3.     protected int i1;  
  4.     protected int i2;  
  5.     static final String LOG_TAG = "MathTest";  
  6.   
  7.     public void setUp()   
  8.     {  
  9.         i1 = 2;  
  10.         i2 = 3;      
  11.     }  
  12.   
  13.     public void testAdd()   
  14.     {  
  15.         Log.d( LOG_TAG, "testAdd" );  
  16.         assertTrue( LOG_TAG+"1", ( ( i1 + i2 ) == 5 ) );  
  17.     }  
  18.   
  19.     public void testAndroidTestCaseSetupProperly()  
  20.     {  
  21.         super.testAndroidTestCaseSetupProperly();  
  22.         Log.d( LOG_TAG, "testAndroidTestCaseSetupProperly" );  
  23.     }  
  24. }  

与面junit的例子比较后发现,除了引用的包、父类不一样以外,其他部分是完全一样的。

具体代码可以参看下一篇文章。

在Android AVD上运行程序后看到的结果如下:


总结说明
这里我们简要学习了android.test包,其实这个的内容远不止这些,包含:3个Interface、20个class、2个Error,列举如下:


        android.test包深入的学习,只有到Android SDK中去仔细阅读了。通过学习android.test,让我们对Android 系统的组成元素:Activity、Provider、Service有了更加深入的了解。


参考文献:
Android、JUnit深入浅出系列文章

0 0
原创粉丝点击