我的测试人生........

【转】结合junit + ant + emma实现Android项目单元测试代码覆盖率统计

上一篇 / 下一篇  2013-07-09 23:06:22 / 个人分类:移动测试

http://www.51testing.com/html/28/n-848528.html

结合junit + ant + emma实现Android项目单元测试代码覆盖率统计

  1.建立一个简单的android应用

  应用的界面如下,首先是两个id分别为value1和value2的输入框用于输入两个数字,然后是两个按钮,分别用来实现两个数的求和与求积操作,运算的结果在id为result的文本框中显示。

  整个应用只有一个Activity,主要代码如下:

public class MainActivity extends Activity {
protected static final String LOG_TAG = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText value1 = (EditText) findViewById(R.id.value1);
final EditText value2 = (EditText) findViewById(R.id.value2);
final EditText result = (EditText) findViewById(R.id.result);
Button addButton = (Button) findViewById(R.id.addValues);
addButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
int val1 = Integer.parseInt(value1.getText().toString());
int val2 = Integer.parseInt(value2.getText().toString());
Integer answer = val1 + val2;
result.setText(answer.toString());
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to add numbers", e);
}
}
});
Button multiplyButton = (Button) findViewById(R.id.multiplyValues);
multiplyButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
int val1 = Integer.parseInt(value1.getText().toString());
int val2 = Integer.parseInt(value2.getText().toString());
Integer answer = val1 * val2;
result.setText(answer.toString());
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to multiply numbers", e);
}
}
});
}

  2.利用JUnit基于android的扩展,从eclipse中生成应用项目对应的测试项目

  右击Demo项目名称,在弹出的菜单中依次选择Android->NewTestProject,如图:

  在弹出的对话框中进行设置,如下:

  设置对应于Demo项目的测试项目名为:DemoTest

  选择测试对象为Demo项目:

  随后得到了针对Demo项目的基于JUnit在android上的扩展的单元测试框架:

  3.在测试项目中编写测试用例

  首先在com.winston.demo.test包中新建一个测试用例,操作如下:

  测试用例的设置如下:

测试用例的设置如下:

  其中,新建的测试用例名称为testCase1,父类为junit.framework.TestCase,在随后的源代码中需要修改父类为ActivityInstrumentationTestCase2。

  另外可以勾选是否生成一些默认的代码,其中:

  setUp()用来执行测试执行之前的一些相关的准备工作,constructor其实就是构造函数,tearDown用来做测试收尾的回收工作。

  测试用例的代码如下,包含4个测试用例,分别用来测试两个整数相加、带浮点数的操作、带负数的操作、两个数相乘:

package com.winston.demo.test;
import android.test.ActivityInstrumentationTestCase2;
import com.winston.demo.MainActivity; //被测试对象
import com.winston.demo.R;
import android.widget.EditText;
public class testCase1 extends ActivityInstrumentationTestCase2<MainActivity> {
private EditText result;
@SuppressWarnings("deprecation")
public testCase1() {
super("com.winston.demo", MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
MainActivity mainActivity = getActivity();
result = (EditText) mainActivity.findViewById(R.id.result);
}
private static final String NUMBER_24 = "2 4 ENTER ";
private static final String NUMBER_74 = "7 4 ENTER ";
private static final String NUMBER_5_DOT_5 = "5 PERIOD 5 ENTER "; //PERIOD 小数
private static final String NUMBER_NEG_22 = "MINUS 2 2 ENTER "; // -22
private static final String ADD_RESULT = "98";
private static final String ADD_DECIMAL_RESULT = "79.5";
private static final String ADD_NEGATIVE_RESULT = "52";
private static final String MULTIPLY_RESULT = "1776";
public void testAddValues() { //两个整数相加
sendKeys(NUMBER_24);
sendKeys(NUMBER_74);
sendKeys("ENTER");
String mathResult = result.getText().toString();
assertTrue("Add result should be 98 " + ADD_RESULT + " but was "
+ mathResult, mathResult.equals(ADD_RESULT));
}
public void testAddDecimalValues() { //带小数的相加操作
sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
String mathResult = result.getText().toString();
assertTrue("Add result should be " + ADD_DECIMAL_RESULT + " but was "
+ mathResult, mathResult.equals(ADD_DECIMAL_RESULT));
}
public void testSubtractValues() { //负数
sendKeys(NUMBER_NEG_22 + NUMBER_74 + "ENTER");
String mathResult = result.getText().toString();
assertTrue("Add result should be " + ADD_NEGATIVE_RESULT + " but was "
+ mathResult, mathResult.equals(ADD_NEGATIVE_RESULT));
}
public void testMultiplyValues() { //两个整数相乘
sendKeys(NUMBER_24 + NUMBER_74 + " DPAD_RIGHT ENTER"); // 须到config.ini中启用虚拟机的D_PAD,否则影响测试
String mathResult = result.getText().toString();
assertTrue("Multiply result should be " + MULTIPLY_RESULT + " but was "
+ mathResult, mathResult.equals(MULTIPLY_RESULT));
}
}

可以在虚拟机中检测自动化测试的执行情况,选择DemoTest项目执行:

  可以用来检测测试是否顺利进行。

  至此,完成了Demo项目的自动化单元测试。

  4.用ant编译一个覆盖率统计版,运行并得到测试项目对于应用项目的代码覆盖率结果

  cd到项目所在目录(我的是C:\Users\winstonwu\workspace\Demo)

  首先用ant更新一下Demo项目:

  再用“update test-project”命令将测试项目DemoTest也转换为ant工程:

  其中-m选项用来指定要测试的项目(这里是Demo),-p选项用来指定测试项目(这里是DemoTest)。

  这样就可以调用emma执行单元测试,并收集代码覆盖率信息了(当然前提是有安装配置emma,我直接使用的google ADT,在路径ADT\sdk\tools\lib下google已经事先整合了emma),cd到测试项目所在目录,执行:

  接着可以到路径“DemoTest\bin\_files”下查找代码覆盖率的统计文件,是两个html文件:

  覆盖率的统计数据包含了多个层次:包、源文件、类、方法、语句;

  0.html是一个总体的统计,即包和源文件的覆盖率结果如下:

  1.html中是更为详细的覆盖率统计,包括类、函数、语句:

  精确到语句的覆盖率:

  emma的语句覆盖统计结果中用3种颜色提示,绿色表示完全覆盖,黄色表示不完全覆盖,红色表示未覆盖。

  可以看到,测试用例的执行没有覆盖到第53和54两行的代码。

  此外,在路径\DemoTest\bin下还可以找到代码覆盖率统计结果的xml、txt、html三种格式的文件。


TAG:

引用 删除 kevinf_sun   /   2014-02-07 14:05:15
5
引用 删除 kevinf_sun   /   2014-02-07 14:05:11
找了好久才看到这篇文章,很详尽。不过最后执行了哪一个命令才有报表产生到DemoTest\bin\_files位置的?我试了几个命令都不对,可以的话请回个信息给kevinf_sun@163.com。谢谢!
 

评分:0

我来说两句

Open Toolbar