多测师是一家拥有先进的教学理念,强大的师资团队,业内好评甚多的接口自动化测试培训机构!

17727591462

联系电话

您现在所在位置:接口自动化测试培训 > 新闻资讯

Android自动化测试生成单元测试结果报告

更新时间:2022-09-30 09:33:20 作者:多测师 浏览:64

  使用robotium进行Android应用进行自动化测试,之前用TMTS框架,但收集到的单元测试结果常常会少掉一些用例集。。穷则思变,Android的测试框架主要是通过InstrumentationTestRunner对被测应用进行控制与执行,因此可以对InstrumentationTestRunner进行扩展以完成测试结果收集,然后通过jenkins的Publish JUnit test result report插件得到结果报告。

Android自动化测试生成单元测试结果报告

  1.新建一个java package,新建一个java类

  源码来自开源项目:https://code.google.com/p/nbandroid-utils/

  源码中生成的TEST-all.xml结果文件位于/data/data/com.example/files目录下,要导出结果文件的话,需要手机拥有root权限,比较麻烦,因此下面修改了文件存放路径,有SD卡则文件位于SD卡的/robotium目录下

package com.example.test.instrumentation;

import java.io.File;

import java.io.FileWriter;

import java.io.IOException;

import java.io.Writer;

import org.xmlpull.v1.XmlPullParserFactory;

import org.xmlpull.v1.XmlSerializer;

import android.content.Context;

import android.os.Bundle;

import android.os.Environment;

/**

* This test runner creates a TEST-all.xml in the files directory of the application under test. The output is compatible with that of the junitreport ant task, the format

* that is understood by Hudson. Currently this implementation does not implement the all aspects of the junitreport format, but enough for Hudson to parse the test results.

*/

public class InstrumentationTestRunner extends android.test.InstrumentationTestRunner {

private Writer mWriter;

private XmlSerializer mTestSuiteSerializer;

private long mTestStarted;

private static final String JUNIT_XML_FILE = "TEST-all.xml";

@Override

public void onStart() {

try{

File fileRobo = new File(getTestResultDir(getTargetContext()));

if(!fileRobo.exists()){

fileRobo.mkdir();

}

if(isSDCardAvaliable()){

File resultFile = new File(getTestResultDir(getTargetContext()),JUNIT_XML_FILE);

startJUnitOutput(new FileWriter(resultFile));

}else{

startJUnitOutput(new FileWriter(new File(getTargetContext().getFilesDir(), JUNIT_XML_FILE)));

}

}

catch(IOException e){

throw new RuntimeException(e);

}

super.onStart();

}

void startJUnitOutput(Writer writer) {

try {

mWriter = writer;

mTestSuiteSerializer = newSerializer(mWriter);

mTestSuiteSerializer.startDocument(null, null);

mTestSuiteSerializer.startTag(null, "testsuites");

mTestSuiteSerializer.startTag(null, "testsuite");

} catch (Exception e) {

throw new RuntimeException(e);

}

}

/**

* 判断SD卡是否存在

* @return

*/

private boolean isSDCardAvaliable(){

return Environment.getExternalStorageState()

.equals(Environment.MEDIA_MOUNTED);

}

/**

* 获取测试结果报告文件所在的路径

* @param context  被测工程的context

* @return  返回测试结果报告文件所在的路径

*/

private String getTestResultDir(Context context){

String packageName = "/" + "robotium";

String filepath = context.getCacheDir().getPath() + packageName;

if(android.os.Build.VERSION.SDK_INT < 8){

if(isSDCardAvaliable()){

filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ packageName;

}

}else{

if(isSDCardAvaliable()){

filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ packageName;

}

}

return filepath;

}

private XmlSerializer newSerializer(Writer writer) {

try {

XmlPullParserFactory pf = XmlPullParserFactory.newInstance();

XmlSerializer serializer = pf.newSerializer();

serializer.setOutput(writer);

return serializer;

} catch (Exception e) {

throw new RuntimeException(e);

}

}

@Override

public void sendStatus(int resultCode, Bundle results) {

super.sendStatus(resultCode, results);

switch (resultCode) {

case REPORT_VALUE_RESULT_ERROR:

case REPORT_VALUE_RESULT_FAILURE:

case REPORT_VALUE_RESULT_OK:

try {

recordTestResult(resultCode, results);

} catch (IOException e) {

throw new RuntimeException(e);

}

break;

case REPORT_VALUE_RESULT_START:

recordTestStart(results);

default:

break;

}

}

void recordTestStart(Bundle results) {

mTestStarted = System.currentTimeMillis();

}

void recordTestResult(int resultCode, Bundle results) throws IOException {

float time = (System.currentTimeMillis() - mTestStarted) / 1000.0f;

String className = results.getString(REPORT_KEY_NAME_CLASS);

String testMethod = results.getString(REPORT_KEY_NAME_TEST);

String stack = results.getString(REPORT_KEY_STACK);

int current = results.getInt(REPORT_KEY_NUM_CURRENT);

int total = results.getInt(REPORT_KEY_NUM_TOTAL);

mTestSuiteSerializer.startTag(null, "testcase");

mTestSuiteSerializer.attribute(null, "classname", className);

mTestSuiteSerializer.attribute(null, "name", testMethod);

if (resultCode != REPORT_VALUE_RESULT_OK) {

mTestSuiteSerializer.startTag(null, "failure");

if (stack != null) {

String reason = stack.substring(0, stack.indexOf('\n'));

String message = "";

int index = reason.indexOf(':');

if (index > -1) {

message = reason.substring(index+1);

reason = reason.substring(0, index);

}

mTestSuiteSerializer.attribute(null, "message", message);

mTestSuiteSerializer.attribute(null, "type", reason);

mTestSuiteSerializer.text(stack);

}

mTestSuiteSerializer.endTag(null, "failure");

} else {

mTestSuiteSerializer.attribute(null, "time", String.format("%.3f", time));

}

mTestSuiteSerializer.endTag(null, "testcase");

if (current == total) {

mTestSuiteSerializer.startTag(null, "system-out");

mTestSuiteSerializer.endTag(null, "system-out");

mTestSuiteSerializer.startTag(null, "system-err");

mTestSuiteSerializer.endTag(null, "system-err");

mTestSuiteSerializer.endTag(null, "testsuite");

mTestSuiteSerializer.flush();

}

}

@Override

public void finish(int resultCode, Bundle results) {

endTestSuites();

super.finish(resultCode, results);

}

void endTestSuites() {

try {

mTestSuiteSerializer.endTag(null, "testsuites");

mTestSuiteSerializer.endDocument();

mTestSuiteSerializer.flush();

mWriter.flush();

mWriter.close();

} catch (IOException e) {

throw new RuntimeException(e);

}

}

}

  2.修改AndroidManifest.xml文件

  将原来的:

<instrumentation

android:name="android.test.InstrumentationTestRunner"

android:targetPackage="com.example" />

  修改为:

<instrumentation

android:name="com.example.test.instrumentation.InstrumentationTestRunner"

android:targetPackage="com.example" />

  3.修改Run Configurations

  右键测试工程>Run as >Run Configurations

  在Test栏中,勾选Run all tests in the selected project,or package

  这样每次在Eclipse中运行时才会使用新的InstrumentationTestRunner

  在Instrumentation runner处下拉选择新写的InstrumentationTestRunner

  点击Apply完成设置

  4.命令行下运行测试用例

Running all tests: adb shell am instrument -w com.android.foo/com.example.test.instrumentation.InstrumentationTestRunner

Running a single testcase: adb shell am instrument -w -e class com.android.foo.FooTest com.android.foo/com.example.test.instrumentation.InstrumentationTestRunner

Running multiple tests: adb shell am instrument -w -e class com.android.foo.FooTest,com.android.foo.TooTest com.android.foo/com.example.test.instrumentation.InstrumentationTestRunner

  命令行下运行测试用例与平时一样,只要将原来的InstrumentationTestRunner换成新的InstrumentationTestRunner就行,需要注意的是,由于每次命令行执行完毕,都会覆盖原有的TEST-all.xml文件,即如果采用Running a single testcase方式运行多个测试用例集,则最后结果只会记录最后一个用例集,因此建议采用Running multiple tests方式。

  5.运行完成后将手机中的文件导出

  adb -s $ANDROID_AVD_DEVICE pull /mnt/sdcard/rototium/TEST-all.xml

  其中$ANDROID_AVD_DEVICE为参数化的手机序列号

  6.在jenkins中任务构建完成后即可使用Publish JUnit test result report插件分析得出单元测试报告了。

  以上内容为大家介绍了Android自动化测试生成单元测试结果报告,本文由多测师亲自撰写,希望对大家有所帮助。了解更多自动化测试相关知识:https://www.aichudan.com/xwzx/

联系电话

17727591462

返回顶部