- Espresso 测试框架教程
- Espresso 测试 - 首页
- 简介
- 设置说明
- 在 Android Studio 中运行测试
- JUnit 概述
- 架构
- 视图匹配器 (View Matchers)
- 自定义视图匹配器 (Custom View Matchers)
- 视图断言 (View Assertions)
- 视图操作 (View Actions)
- 测试 AdapterView
- 测试 WebView
- 测试异步操作
- 测试 Intent
- 测试多个应用程序的 UI
- 测试录制器 (Test Recorder)
- 测试 UI 性能
- 测试可访问性
- Espresso 测试资源
- Espresso 测试 - 快速指南
- Espresso 测试 - 有用资源
- Espresso 测试 - 讨论
Espresso 测试框架 - AdapterView
AdapterView 是一种特殊的视图,专门用于呈现类似信息的集合,例如从底层数据源(使用Adapter)获取的产品列表和用户联系人。数据源可以是简单的列表到复杂数据库条目。一些从AdapterView派生的视图是ListView、GridView和Spinner。
AdapterView根据底层数据源中可用数据的数量动态呈现用户界面。此外,AdapterView仅呈现屏幕可见区域内可以呈现的必要最小数据。AdapterView这样做是为了节省内存,并使即使底层数据量很大时,用户界面也能保持流畅。
分析表明,AdapterView架构的性质使得onView选项及其视图匹配器变得无关紧要,因为首先可能根本没有呈现要测试的特定视图。幸运的是,espresso 提供了一个方法onData(),它接受 Hamcrest 匹配器(与底层数据的类型相关)来匹配底层数据,并返回对应于匹配数据视图的DataInteraction类型对象。示例代码如下所示:
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
在这里,onData()匹配条目“Apple”,如果它在底层数据(数组列表)中可用,则返回DataInteraction对象以与匹配的视图(对应于“Apple”条目的 TextView)进行交互。
方法
DataInteraction提供以下方法来与视图交互:
perform()
这接受视图操作并触发传入的视图操作。
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
check()
这接受视图断言并检查传入的视图断言。
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))) .check(matches(withText("Apple")))
inAdapterView()
这接受视图匹配器。它根据传入的视图匹配器选择特定的AdapterView,并返回DataInteraction对象以与匹配的AdapterView进行交互。
onData(allOf()) .inAdapterView(withId(R.id.adapter_view)) .atPosition(5) .perform(click())
atPosition()
这接受一个整数类型的参数,并引用项目在底层数据中的位置。它选择对应于传入数据位置值的视图,并返回DataInteraction对象以与匹配的视图进行交互。如果我们知道底层数据的正确顺序,这将非常有用。
onData(allOf()) .inAdapterView(withId(R.id.adapter_view)) .atPosition(5) .perform(click())
onChildView()
这接受视图匹配器并匹配特定子视图内的视图。例如,我们可以与基于AdapterView的产品列表中的特定项目(如“购买”按钮)进行交互。
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))) .onChildView(withId(R.id.buy_button)) .perform(click())
编写示例应用程序
按照以下步骤编写一个基于AdapterView的简单应用程序,并使用onData()方法编写测试用例。
启动 Android Studio。
如前所述创建新项目,并将其命名为MyFruitApp。
使用重构→迁移到AndroidX选项菜单将应用程序迁移到 AndroidX 框架。
删除主活动中的默认设计并添加ListView。activity_main.xml的内容如下所示:
<?xml version = "1.0" encoding = "utf-8"?> <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:app = "http://schemas.android.com/apk/res-auto" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <ListView android:id = "@+id/listView" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> </RelativeLayout>
添加新的布局资源item.xml以指定列表视图的项目模板。item.xml的内容如下所示:
<?xml version = "1.0" encoding = "utf-8"?> <TextView xmlns:android = "http://schemas.android.com/apk/res/android" android:id = "@+id/name" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:padding = "8dp" />
现在,创建一个适配器,其水果数组作为底层数据,并将其设置为列表视图。这需要在MainActivity的onCreate()中完成,如下所示:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Find fruit list view final ListView listView = (ListView) findViewById(R.id.listView); // Initialize fruit data String[] fruits = new String[]{ "Apple", "Banana", "Cherry", "Dates", "Elderberry", "Fig", "Grapes", "Grapefruit", "Guava", "Jack fruit", "Lemon", "Mango", "Orange", "Papaya", "Pears", "Peaches", "Pineapple", "Plums", "Raspberry", "Strawberry", "Watermelon" }; // Create array list of fruits final ArrayList<String> fruitList = new ArrayList<String>(); for (int i = 0; i < fruits.length; ++i) { fruitList.add(fruits[i]); } // Create Array adapter final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item, fruitList); // Set adapter in list view listView.setAdapter(adapter); }
现在,编译代码并运行应用程序。我的水果应用程序 (My Fruit App) 的屏幕截图如下所示:
现在,打开ExampleInstrumentedTest.java文件并添加ActivityTestRule,如下所示:
@Rule public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class);
另外,请确保在app/build.gradle中完成了测试配置:
dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test:rules:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' }
添加一个新的测试用例来测试列表视图,如下所示:
@Test public void listView_isCorrect() { // check list view is visible onView(withId(R.id.listView)).check(matches(isDisplayed())); onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click()); onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))) .check(matches(withText("Apple"))); // click a child item onData(allOf()) .inAdapterView(withId(R.id.listView)) .atPosition(10) .perform(click()); }
最后,使用 Android Studio 的上下文菜单运行测试用例,并检查所有测试用例是否都成功。