blob: 832a91cfed131ac32ad408b3b385c3bfc5674761 [file] [log] [blame]
<html devsite><head>
<meta name="book_path" value="/_book.yaml"/>
<meta name="project_path" value="/_project.yaml"/>
</head>
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<h1 id="instrumentation_tests" class="page-title">插桩测试</h1>
<p>请先阅读 developer.android.com 上的<a href="https://developer.android.com/studio/test/" class="external">测试应用</a>一文。请注意,在平台测试中使用插桩测试的方式有一些差异。</p>
<p>总的来说,插桩测试提供了一种通过 <code>am instrument</code> 命令启动的特殊测试执行环境,其中目标应用进程会重启并使用基本的应用上下文进行初始化,并在应用进程虚拟机内启动插桩线程。您的测试代码在此插桩线程上开始执行,并附带一个 <code>Instrumentation</code> 实例,该实例可提供对应用上下文和 API 的访问权限,以操纵接受测试的应用进程。</p>
<h2 id="key_concepts">主要概念</h2>
<ul>
<li>必须在应用软件包中声明插桩,方法是在应用软件包清单的 <code>&lt;manifest&gt;</code> 标记下嵌套 <a href="https://developer.android.com/guide/topics/manifest/instrumentation-element.html"><code>&lt;instrumentation&gt;</code></a> 标记。</li>
<li>严格意义来讲,应用软件包清单可以包含多个 <code>&lt;instrumentation&gt;</code> 标记,但通常不这么做。</li>
<li>每个 <code>&lt;instrumentation&gt;</code> 必须包含:<ul>
<li><code>android:name</code> 属性:它应该是测试应用中所包含 <a href="https://developer.android.com/reference/android/app/Instrumentation.html"><code>Instrumentation</code></a> 的子类的名称,测试应用则通常是正在使用的测试运行器,例如 <code>android.support.test.runner.AndroidJUnitRunner</code></li>
<li>必须定义 <code>android:targetPackage</code> 属性。其值应该设置为接受测试的应用软件包。</li>
</ul></li>
</ul>
<h2 id="summary_of_steps">步骤总结</h2>
<ol>
<li><p>下面是框架服务封闭测试的常见位置:</p>
<pre class="prettyprint"><code>frameworks/base/core/tests/coretests
frameworks/base/services/tests/servicestests
</code></pre>
<p>如果要为组件添加全新的插桩模块,请参阅</p>
<ul>
<li><a href="instr-self-e2e.md">自插桩测试:完整的示例</a></li>
<li><a href="instr-app-e2e.md">针对应用的插桩:完整的示例</a></li>
</ul></li>
<li><p>如果要将测试添加到上述某个位置,请遵循现有惯例。如果要设置一个新的测试模块,请在上述某个位置按照 <code>AndroidManifest.xml</code><code>Android.mk</code> 的设置进行操作</p></li>
<li><p>有关示例,请参阅 <a href="https://android.googlesource.com/platform/frameworks/base.git/+/master/core/tests/coretests/">frameworks/base/core/tests/coretests/</a>。请注意,以下行会安装额外的应用:</p>
<pre class="prettyprint"><code>&lt;option name="test-file-name" value="FrameworksCoreTests.apk" /&gt;
&lt;option name="test-file-name" value="BstatsTestApp.apk" /&gt;
</code></pre></li>
<li><p>不要忘记将您的测试标记为 <code>@SmallTest</code><code>@MediumTest</code><code>@LargeTest</code></p></li>
<li><p>使用 make 命令编译测试模块,例如:</p>
<pre class="prettyprint"><code>make FrameworksCoreTests -j
</code></pre></li>
<li><p>运行测试:</p>
<ul>
<li><p>最简单的解决方案是使用 <a href="/compatibility/tests/development/atest">Atest</a>,如下所示:</p>
<pre class="prettyprint"><code>atest FrameworksCoreTests
</code></pre></li>
<li><p>或者,对于更复杂的测试,请使用 Trade Federation 自动化测试框架:</p></li>
</ul>
<pre class="prettyprint"><code>make tradefed-all -j
tradefed.sh run template/local_min --template:map test=FrameworksCoreTests
</code></pre></li>
<li><p>如果使用 Trade Federation,请手动安装并运行测试:</p>
<ol>
<li>安装生成的 apk:</li>
</ol>
<pre class="prettyprint"><code>adb install -r ${OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
</code></pre>
<p>提示:您可以使用 <code>adb shell pm list instrumentation</code> 查找刚刚安装的 apk 内的插桩</p>
<ol>
<li><p>使用各种选项运行测试:</p>
<ol>
<li><p>apk 中的所有测试</p>
<pre class="prettyprint"><code>adb shell am instrument -w com.android.frameworks.coretests\
/android.support.test.runner.AndroidJUnitRunner
</code></pre></li>
<li><p>特定 Java 软件包下的所有测试</p>
<pre class="prettyprint"><code>adb shell am instrument -w -e package android.animation \
com.android.frameworks.coretests\
/android.support.test.runner.AndroidJUnitRunner
</code></pre></li>
<li><p>特定类下的所有测试</p>
<pre class="prettyprint"><code>adb shell am instrument -w -e class \
android.animation.AnimatorSetEventsTest \
com.android.frameworks.coretests\
/android.support.test.runner.AndroidJUnitRunner
</code></pre></li>
<li><p>特定的测试方法</p>
<pre class="prettyprint"><code>adb shell am instrument -w -e class \
android.animation.AnimatorSetEventsTest#testCancel \
com.android.frameworks.coretests\
/android.support.test.runner.AndroidJUnitRunner
</code></pre></li>
</ol></li>
</ol></li>
</ol>
<p>测试可以使用 <code>JUnit</code> API 对通过或未通过测试进行显式断言;此外,任何未捕获的异常也会导致功能性故障。</p>
<p>要发出性能指标,测试代码可以调用 <a href="http://developer.android.com/reference/android/app/Instrumentation.html#sendStatus(int,%20android.os.Bundle)"><code>Instrumentation#sendStatus</code></a> 来发出键值对列表。请务必注意以下几点:</p>
<ol>
<li>指标可以是整数或浮点数</li>
<li>任何非数字值都将被舍弃</li>
<li>测试 apk 可以是功能测试或指标测试,但目前不支持混合这两种测试</li>
</ol>
</body></html>