Android单元测试,使用ThreadingTest进行全新体验

更新时间:2023-04-21 07:09:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

1、 背景

长期以来,软件测试工程师都在如何提高软件系统质量和如何提高测试效率的道路上艰难地探索,但始终没有一款性能全面的测试工具可以满足需求。

ThreadingTest(简称“TT”) 智能型测试工具系列一期,是基于程序源代码的Android应用测试工具。采取前端分析器和后端结果分析分离的技术路线,实现对多种语言的编译器级分析和多维度测试。

ThreadingTest通过一系列自动、高效、可视化技术,使软件维护与开发效率加倍、成本减半、系统软件质量提高几个数量级。

ThreadingTest采用离线分析操作,即使电脑脱离互联网也可以获得同样的体验,保障代码的安全。

2、 ThreadingTest Android JUnit Test单元测试

ThreadingTest Android JUnit Test是基于Android JUnit Test,利用ThreadingTest本身的优势,编写的一套单元测试组件。在原有的Android JUnit Test测试驱动代码的基础上,只需要进行很小的改动,就可以修改为符合ThreadingTest Android JUnit Test测试代码的单元测试。除此之外,两者的测试几乎没有差别,只需要您在测试时,打开TT实时监控来接收数据,而在测试过程中,则无需其他操作,甚至感觉不到数据的收集过程。

对于传统的单元测试,在单元测试结束后,测试人员只能获得测试结果是否符合预期结果。如果与预期结果存在差异,也无法立即得到错误原因。

当使用ThreadingTest Android JUnit Test进行单元测试时,还是相同的测试体验,却能够得到白盒测试的数据,当单元执行结束后,可以根据产生的数据来分析程序的出错点,使Bug的查找更快速,更准确,而为此付出最小的代

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

价。

3、 Android单元测试的编写

Android单元测试有两种方法,首先作为java程序,可以试用JUnit Test进行测试,另外也可使用Android JUnit Test进行单元测试。

1)、JUnit Test进行单元测试

JUnit对Android应用程序进行单元测试需要使用Java命令来启动或者在eclipse里面将启动的Bootstrap Entries改为JRE,但是这种只能测试逻辑代码,因为是是运行在JVM上,而不是Android系统中,所以不能测试Android有关的代码。

使用JUnit测试的代码,需要在函数的之前加@Test,函数必须为public类型,在eclipse中,在类上右击,选择JUnit Test即可进行测试。

2)Android JUnit Test进行单元测试

Android JUnit Test单元测试是一组直接或间接继承自junit.framework.Testcase的类集合,入口是InstrumentationTestRunner。

使用Android JUnit Test测试,也存在两种测试方法,测试驱动与测试代码在同一工程下和测试驱动和测试代码位于不同工程,两者之间并无巨大差异,只是在测试时,前者只安装一个App,后者安装两个App。

如下为一个单元测试的实例: 步骤 1:准备好需要测试的源代码 步骤2:添加测试类,编写测试代码

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

import java.util.ArrayList; import java.util.LinkedList; import android.test.ActivityInstrumentationTestCase2; import android.app.AlertDialog; import android.app.Instrumentation; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import calculator.xwg.CalculatorMainActivity;

public class CalculatorMainActivityTest extends ActivityInstrumentationTestCase2<CalculatorMainActivity> { private Instrumentation mInstrumentation; private CalculatorMainActivity mActivity; private TextView mQuestionText; private TextView mAnswerText; private Button mCalculateButton; private Button mButton1; private Button mButtonPlus; private Button mButtonAngle; private Button mButtonDegree; private Button mButtonF6;

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

class AssertPair{ public AssertPair(CharSequence quest, CharSequence res){ question = quest; result = res; } boolean assertResult(){ return (question.toString().compareTo(result.toString()) == 0); } public CharSequence question; public CharSequence result; }

ArrayList<AssertPair> assertList = new ArrayList<AssertPair>(); AssertPair mAssertPair; FailureInfo mFailureInfo;

@SuppressWarnings("deprecation") public CalculatorMainActivityTest() { super("calculator.xwg", CalculatorMainActivity.class); // TODO Auto-generated constructor stub

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

}

@Override protected void setUp() throws Exception { super.setUp(); mInstrumentation = getInstrumentation(); setActivityInitialTouchMode(false);

mActivity = (CalculatorMainActivity) getActivity(); mQuestionText = (TextView)mActivity.findViewById(calculator.xwg.R.id.textQuestion); mAnswerText = (TextView)mActivity.findViewById(calculator.xwg.R.id.textAnswer); mCalculateButton = (Button)mActivity.findViewById(calculator.xwg.R.id.button74); mButton1 = (Button)mActivity.findViewById(calculator.xwg.R.id.button60); mButtonPlus = (Button)mActivity.findViewById(calculator.xwg.R.id.button63); mButtonAngle = (Button)mActivity.findViewById(calculator.xwg.R.id.button03); mButtonDegree =

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

(Button)mActivity.findViewById(calculator.xwg.R.id.button02); mButtonF6 = (Button)mActivity.findViewById(calculator.xwg.R.id.buttonF6);

mActivity.engine.clearCustomFunctions(); } // end of setUp() method definition

@Override protected void tearDown() throws Exception { mActivity.engine.clearCustomFunctions(); super.tearDown(); }

public void testPreConditions() { //assertTrue(mSpinner.getOnItemSelectedListener() != null); //assertTrue(mPlanetData != null); //assertEquals(mPlanetData.getCount(),ADAPTER_COUNT); } // end of testPreConditions() method definition

public void testCalculate() { LinkedList<AssertPair> checkItemList = new LinkedList<AssertPair>();

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

checkItemList.add(new AssertPair("1-2×((3+4)/58+8)×25%", "-3.06034482759")); checkItemList.add(new AssertPair("root(16,4)", "2")); checkItemList.add(new Ass

ertPair("sin(0°)", "0")); checkItemList.add(new AssertPair("sin(30°)", "0.5")); checkItemList.add(new AssertPair("sin(390°)", "0.5")); checkItemList.add(new AssertPair("sin(-330°)", "0.5")); checkItemList.add(new AssertPair("sin(90°)", "1")); checkItemList.add(new AssertPair("sin(145°)", "0.573576436351")); checkItemList.add(new AssertPair("sin(180°)", "0")); checkItemList.add(new AssertPair("sin(200°)", "-0.342020143326")); checkItemList.add(new AssertPair("sin(270°)", "-1")); checkItemList.add(new AssertPair("sin(300°)", "-0.866025403784")); checkItemList.add(new AssertPair("sin(360°)", "0")); checkItemList.add(new AssertPair("sin(π/6)", "0.5")); checkItemList.add(new AssertPair("tan(0)", "0")); checkItemList.add(new AssertPair("tan(0.2)", "0.202710035509")); checkItemList.add(new AssertPair("tan(0.4)",

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

"0.422793218738")); checkItemList.add(new AssertPair("tan(0.6)", "0.684136808342")); checkItemList.add(new AssertPair("tan(0.8)", "1.02963855705")); checkItemList.add(new AssertPair("tan(1.0)", "1.55740772465")); checkItemList.add(new AssertPair("tan(1.2)", "2.57215162213")); checkItemList.add(new AssertPair("tan(1.4)", "5.79788371548")); checkItemList.add(new AssertPair("tan(1.8)", "-4.28626167463")); checkItemList.add(new AssertPair("tan(2.0)", "-2.18503986326")); checkItemList.add(new AssertPair("tan(2.2)", "-1.37382305677")); checkItemList.add(new AssertPair("tan(2.4)", "-0.916014289673")); checkItemList.add(new AssertPair("tan(2.6)", "-0.60159661309")); checkItemList.add(new AssertPair("tan(2.8)",

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

"-0.355529831651")); checkItemList.add(new AssertPair("tan(3.0)", "-0.142546543074")); checkItemList.add(new AssertPair("tan(3.2)", "0.0584738544596")); checkItemList.add(new AssertPair("tan(π/2)", "tan:Invalid input.")); checkItemList.add(new AssertPair("tan(π)", "0")); checkItemList.add(new AssertPair("tan(π/2×3)", "tan:Invalid input.")); checkItemList.add(new AssertPair("tan(2×π)", "0")); checkItemList.add(new AssertPair("tan(45°)", "1")); checkItemList.add(new AssertPair("tan(90°)", "tan:Invalid input.")); checkItemList.add(new AssertPair("tan(405°)", "1")); checkItemList.add(new AssertPair("tan(-315°)", "1")); checkItemList.add(new AssertPair("tan(-675°)", "1")); checkItemList.add(new AssertPair("1+1", "2")); checkItemList.add(new AssertPair("(1+2i)×(3-4i)/(5+6i)", "1.0983607-0.91803279i"));

for(final AssertPair pair : checkItemList){

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

mActivity.runOnUiThread( new Runnable() { public void run() { mQuestionText.setText(pair.question); mActivity.onButtonClick(mCalculateButton); } } ); mInstrumentation.waitForIdleSync();

assertEquals("The result of " + pair.question + ":",pair.result, mAnswerText.getText()); } }

public void testConvert() { mActivity.runOnUiThread( new Runnable() { public void run() { mQuestionText.setText("1-i"); mActivity.onButtonClick(mButtonAngle); } }

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

); mInstrumentation.waitForIdleSync();

assertEquals("1.4142136∠5.4977871", mAnswerText.getText());mActivity.runOnUiThread( new Runnable()

{ public void run() { mQuestionText.setText("1-i"); mActivity.onButtonClick(mButtonDegree); } } ); mInstrumentation.waitForIdleSync();

assertEquals("1.4142136∠315°", mAnswerText.getText());}

public void testContinue() { mActivity.runOnUiThread( new Runnable() { public void run() { mQuestionText.setText("1-i"); mActivity.onButtonClick(mButtonAngle); assertList.add(new AssertPair("1.4142136∠

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

5.4977871", mAnswerText.getText())); mActivity.onButtonClick(mButtonDegree); assertList.add(new AssertPair("1.4142136∠315°", mAnswerText.getText())); } } ); mInstrumentation.waitForIdleSync(); for(AssertPair pair : assertList){

assertEquals(pair.question, pair.result);} assertList.clear(); }

public void testCustomFunction() { mActivity.runOnUiThread( new Runnable() { public void run() { mActivity.onButtonClick(mButtonF6); mActivity.onButtonClick("5"); mActivity.onButtonClick(")"); mActivity.onButtonClick("=");

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

mFailureInfo = FailureInfo.checkFailure("Unknown keyword:F", mAnswerText.getText()); if(mFailureInfo != null) return;

mQuestionText.setText("π×#1×#1"); mActivity.onButtonClick("FS"); TextView tv = (TextView)mActivity.mDialog.findViewById(calculator.xwg.R.id.inputText) ; tv.setText("Test"); Button ok = (Button)mActivity.mDialog.findViewById(calculator.xwg.R.id.buttonOK); ok.performClick(); ListView lv = (ListView)((AlertDialog)mActivity.mDialog).getListView(); lv.requestFocus(); lv.setSelection(5); lv.performItemClick(null, 5, 5);

mActivity.onButtonClick(mButtonF6); mActivity.onButtonClick("5");

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

步骤3:修改AndroidManifest.xml文件

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

xmlns:android="/apk/res/android" package="calculator.xwg" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <uses-permission android:name="android.permission.INTERNET"></uses-permission>

<application android:label="@string/app_name" android:icon="@drawable/calculator"> <uses-library android:name="android.test.runner" /> <activity android:name=".CalculatorMainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="UNCHER" /> </intent-filter> </activity> <activity android:name="HelpActivity"></activity>

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

在模拟器中的Dev Tools工具中,设置Instrumentation下显示的名称,在步骤4运行中,点击该标签,也可运行单元测试。在ThreadingTest Android JUnit Test中也是重要一步,可以设置多个单元,多个名称,每个名称尽量不要重复,以区分不同的单元测试。

步骤4:运行测试类

运行测试类有三种方式,包括: 1、 命令行方式

使用adb命令启动单元测试

2、 eclipse中选择Android JUnit Test运行方式

在eclipse中,右击测试工程,选择run as -> Android JUnit Test 3、 模拟器中,使用Dev Tools

在模拟器中安装该程序后,在Dev Tools工具中,选择Instrumentation下显示的与android:label同名的标签运行单元测试。

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

4、 ThreadingTest单元测试的编写

要使用ThreadingTest进行单元测试类的编写,需要将所有的测试类写到一个单独的文件夹下,在进行编译工程时,使用参数-filter将其从编译路径中排除,不对其进行插桩。如下图所示:

被测源码放在src文件夹中,单元测试驱动代码放在test_src文件下。 其他方面,需要在Android单元测试上进行的修改为:

1、引入ThreadingTest Android jar包,JavaParser-Android.jar和通信包jeromq-0.3.0-SNAPSHOT.jar。

2、将继承Android JUnit Test类换成继承ThreadingTest Android JUnit Test类,ThreadingTest Android JUnit Test类中与Android JUnit Test相对应的类为在类名前加TT。例如与InstrumentationTestCase相对应的类为TTInstrumentationTestCase,TT Android JUnit Test类所在的包为com.zoa.android.test。

3、在重载了setUp和tearDown函数的测试类中,需要分别调用super.setUp()和super.tearDown()函数,否则无法对数据进行惊醒测试用例的区分,如果没无需进行初始化和资源释放则不用继承setUp()和tearDown()函数。

4、其他操作同Android JUnit Test操作相同。

如下为一个与上面Android JUnit Test单元测试类相对应的TT

Android

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

JUnit Test单元测试类,添加背景色的为需要注意的点,其他的与原测试代码相同,无需改动:

ThreadingTest使用离线检测的方式,在保护用户源代码的基础上,运用插装、第二代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化、可视化的交流工具。

5、 ThreadingTest单元测试的编译

编写完成TT Android JUnit Test 测试类之后,使用TT对工程进行编译。 1、修改编译文件,如果是单一编码格式的工程,需要修改%TT_Path%/ant-build-a/android-instru_en.xml文件,多种编码格式源码的工程,则需要修改%TT_Path%/ant-build-a/android-instru_code_en.xml文件。修改内容为,添加-filter参数,修改方法为:

添加filterpath属性,用于过滤不需要插桩的单元测试驱动类文件。 <property location="不需要插桩编译的路径,这里为test_src路径" name="filterpath"/>

… <arg

line="&quot;${propath}&quot;

&quot;${TT}&quot;

本文来源:https://www.bwwdw.com/article/7ihq.html

Top