#Jacoco收集Robotium脚本测试覆盖率#

导言##

最近做一个项目,要收集Android测试脚本的代码覆盖率,分支覆盖率,以前用Eclipse开发的时候使用Emma,但是Emma只能收集代码覆盖率,无法收集分支覆盖率,并且使用Emma比较麻烦。后来使用Android studio进行开发,发现了jacoco这个工具,简直神器,好用不说,功能还很齐全。下面说说如何使用jacoco收集robotium脚本测试覆盖率。
首先新建一个Android项目,我这里做了一个简单的加减乘除计算器,代码很少,就一个activity,具体代码如下:

package mandaria.net.jacocodemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener {

    private EditText input1_EditText;
    private EditText input2_EditText;
    private Button add_Button;
    private Button minus_Button;
    private Button multi_Button;
    private Button divide_Button;
    private TextView resultText;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        input1_EditText = (EditText) findViewById(R.id.input1_editText);
        input2_EditText = (EditText) findViewById(R.id.input2_editText);
        add_Button = (Button) findViewById(R.id.add_button);
        minus_Button = (Button) findViewById(R.id.minus_button);
        multi_Button = (Button) findViewById(R.id.multi_button);
        divide_Button = (Button) findViewById(R.id.divide_button);
        resultText = (TextView) findViewById(R.id.result_TextView);
        add_Button.setOnClickListener(this);
        minus_Button.setOnClickListener(this);
        multi_Button.setOnClickListener(this);
        divide_Button.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        String input1 = input1_EditText.getText().toString();
        String input2 = input2_EditText.getText().toString();
        double number1 = 0;
        double number2 = 0;
        try {
            number1 = Double.parseDouble(input1);
            number2 = Double.parseDouble(input2);
        } catch (RuntimeException e) {
            resultText.setText("Invalid Input");
            System.out.println(e.getMessage());
            return;
        }
        switch (view.getId()) {
            case R.id.add_button:
                resultText.setText(Double.toString(number1 + number2));
                break;
            case R.id.minus_button:
                resultText.setText(Double.toString(number1 - number2));
                break;
            case R.id.multi_button:
                resultText.setText(Double.toString(number1 * number2));
                break;
            case R.id.divide_button:
                if (number2 == 0) {
                    resultText.setText("Error!!!");
                    Toast.makeText(getApplication(), "dividend can't be zero!", Toast.LENGTH_SHORT).show();
                } else {
                    resultText.setText(Double.toString(number1 / number2));
                }
                break;
        }

    }
}
#Jacoco收集Robotium脚本测试覆盖率#_第1张图片
DEMO界面

然后配置Robotium环境:
在app/libs目录(没有则自己创建)下导入Robotium包;
在app/build.gradle文件中添加依赖:

    androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.2.1'

这样Robotium环境就配置完成了,接下来编写测试脚本:

package mandaria.net.jacocodemo;

import android.annotation.SuppressLint;
import android.test.ActivityInstrumentationTestCase2;

import com.robotium.solo.Solo;

public class DemoTest extends
        ActivityInstrumentationTestCase2 {
    private Solo solo;

    @SuppressLint("NewApi")
    public DemoTest() {
        super(MainActivity.class);
    }


    @Override
    public void setUp() throws Exception {
        solo = new Solo(getInstrumentation(), getActivity());
    }

    @Override
    public void tearDown() throws Exception {
        solo.finishOpenedActivities();
    }

    /*------ Test Core Function ------*/
    public void testOnAdd() throws Exception {
        solo.enterText(0, "10");
        solo.enterText(1, "2");
        solo.clickOnButton("+");
        boolean result = solo.searchText("12");
        assertTrue(result);
    }
    
}

主要的测试代码在testXX()方法中。
运行一下,发现可以通过

#Jacoco收集Robotium脚本测试覆盖率#_第2张图片
脚本通过!

最后使用Jacoco收集测试覆盖率
首先在app/build.gradle的buildTypes中添加

debug{
            testCoverageEnabled = 'true'
        }

表示启用Jacoco收集覆盖率。点击Android studio右侧边栏Gradle按钮,依次点击项目名称/:app/other找到createDebugAndroidTestCoverageReport,右键点击它,选择Run...

#Jacoco收集Robotium脚本测试覆盖率#_第3张图片
createDebugAndroidTestCoverageReport

稍等一会,就可以看到测试代码在手机中运行。只要脚本没有问题,等运行完,就可以在app/build/reports/coverage/debug/index.html文件中中查看覆盖率。

coverage

点进去还可以看到那些代码没被执行到。

#Jacoco收集Robotium脚本测试覆盖率#_第4张图片
详细情况

绿色的代表被执行到,红色的代表没被执行到。

*注意!!!#

千万别用三星手机去跑脚本来收集测试覆盖率,不然收集到的覆盖率全为0!!!本来很简单的过程,因为导师给我一台三星手机做实验,做了三天也收集不到覆盖率,检查了配置,考虑是不是Android Studio版本有问题,但都没有解决,后来在StackOverFlow上看到这样一句话:
Try to generate the debug coverage report using Nexus device (5 or 5x), it will works perfectly. I was facing same issue with Samsung devices (coverage.ec is empty) but after that I run it with Nexus 5x and everything was working fine.果断丢弃了三星手机,用虚拟机还跑脚本,果然成功得到了覆盖率。

最后,demo及脚本可以在我的github上下载:
https://github.com/chl19940220/JacocoDemo.git

你可能感兴趣的:(#Jacoco收集Robotium脚本测试覆盖率#)