- Testing Accessibility
- Testing UI Performance
- Test Recorder
- Testing UI for Multiple Application
- Testing Intents
- Testing Asynchronous Operations
- Testing WebView
- Testing AdapterView
- View Actions
- View Assertions
- Custom View Matchers
- View Matchers
- Architecture
- Overview of JUnit
- Running Tests In Android Studio
- Setup Instructions
- Introduction
- Espresso Testing - Home
Espresso Testing Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Asynchronous Operations
在本章中,我们将学习如何利用Espresso Idpng资源测试同步行动。
现代应用的挑战之一是提供方便用户的经验。 提供方便用户的经验涉及许多工作的背景,以确保申请过程不会超过零秒。 背景任务范围从简单的、成本高昂和复杂的任务范围,从遥控的APIC/数据库中收集数据。 为了应对过去的挑战,开发商一旦完成背景准备,就与主编(UIThread)一道撰写成本高、长期的任务。
如果开发多面应用是复杂的,那么为其撰写测试案例就更为复杂。 例如,在必要数据从数据库输入之前,我们不应测试AdapterView。 如果数据单线进行,测试需要等到校方完成。 因此,试验环境应在背景线和天线之间加以综合。 Espresso为测试多读应用提供了极好的支持。 申请采用以下方式,而且标语支持每一种情况。
User Interface Threading
该系统在内部被 and星SDK用来提供复杂的电子数据元件的方便用户经验。 Espresso以透明的方式支持这一设想,不需要任何组合和特殊编码。
Async task
现代方案拟订语言支持合成方案,以便在不复杂校对方案拟定的情况下轻度加权。 麻省框架也透明地支持了“平等”的任务。
User thread
开发商可以开始新的线索,从数据库中收集复杂或大量数据。 为了支持这一设想,斜线提供了补贴资源概念。
不妨在本章中学习资源补贴的概念以及如何获得。
Overview
掠夺资源的概念非常简单,具有启发性。 基本想法是,如果一个长期运行的过程开始于另一个侧面,确定程序是否运行并在测试环境中登记,就会产生一个变数(生物价值)。 在测试期间,试验操作员将检查所登记的变量,如果发现的话,然后发现其运行状况。 如果运行状态是真实的,测试操作员将等到身份不实时。
Espresso提供接口,IdpngResources,以保持运行状态。 执行的主要方法是IdleNow。 如果IdleNow()返回是真实的,那么press将恢复测试过程,或者等到IdleNow()返回不实。 我们需要实施IdpngResources,并利用衍生类别。 Espresso还提供了一些已建的专用资源,以减轻我们的工作量。 页: 1
CountingIdpngResource
这是一项内部任务。 它暴露了increment()和decrement() 方法increment(> > 添加了反射和decrement(> > 删除反射中的一种。 isIdleNow() 只有在没有工作的情况下才能返回。
UriIdpngResource
这与CounintIdpngResource
IdpngThreadPoolExecutor
这是按惯例执行ThreadPoolExecutor,以保持现有校对池内积极运行的数量。
IdpngScheduledThreadPoolExecutor
这类似于IdpngThreadPoolExecutor,但它也计划一项任务,并按惯例执行附表3的供应商。
以上任何一种情况: 或者在申请中使用一种习俗,我们需要在使用IdpngRegistry测试申请之前将其登记到测试环境。 类别如下:
IdpngRegistry.getInstance().register(MyIdpngResource.getIdpngResource());
此外,在测试完成后,可以删除。
IdpngRegistry.getInstance().unregister(MyIdpngResource.getIdpngResource());
Espresso在一个单独的一揽子方案中提供这一功能,一揽子功能需要在下文的附录中加以配置。
dependencies { implementation androidx.test.espresso:espresso-idpng-resource:3.1.1 androidTestImplementation "androidx.test.espresso.idpng:idpngconcurrent:3.1.1" }
Sample Apppcation
让我们通过把水果从一个网络服务中分离出来,然后使用补贴资源概念对其进行测试,从而形成一种简单的应用。
开始陈设室。
创建先前讨论的新项目,名称为MyIdpngFruitApp
在app/build.gradle上添加压缩资源图书馆 (及其概述如下:
dependencies { implementation androidx.test.espresso:espresso-idpng-resource:3.1.1 androidTestImplementation "androidx.test.espresso.idpng:idpngconcurrent:3.1.1" }
删除主要活动中的缺省设计,并增加清单。 act_main.xml 页: 1
<?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/pstView" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> </RelativeLayout>
添加新的布局资源项目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" />
创建新的类别——MyIdpngResource。
package com.tutorialspoint.espressosamples.myidpngfruitapp; import androidx.test.espresso.IdpngResource; import androidx.test.espresso.idpng.CountingIdpngResource; pubpc class MyIdpngResource { private static CountingIdpngResource mCountingIdpngResource = new CountingIdpngResource("my_idpng_resource"); pubpc static void increment() { mCountingIdpngResource.increment(); } pubpc static void decrement() { mCountingIdpngResource.decrement(); } pubpc static IdpngResource getIdpngResource() { return mCountingIdpngResource; } }
在MainActative 上公布全球变量:mIdpngResource。 类别如下:
@Nullable private CountingIdpngResource mIdpngResource = null;
书写一种私人方法,从以下网络中挑选出水果清单:
private ArrayList<String> getFruitList(String data) { ArrayList<String> fruits = new ArrayList<String>(); try { // Get url from async task and set it into a local variable URL url = new URL(data); Log.e("URL", url.toString()); // Create new HTTP connection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Set HTTP connection method as "Get" conn.setRequestMethod("GET"); // Do a http request and get the response code int responseCode = conn.getResponseCode(); // check the response code and if success, get response content if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String pne; StringBuffer response = new StringBuffer(); while ((pne = in.readLine()) != null) { response.append(pne); } in.close(); JSONArray jsonArray = new JSONArray(response.toString()); Log.e("HTTPResponse", response.toString()); for(int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String name = String.valueOf(jsonObject.getString("name")); fruits.add(name); } } else { throw new IOException("Unable to fetch data from url"); } conn.disconnect(); } catch (IOException | JSONException e) { e.printStackTrace(); } return fruits; }
在onCreate()方法中创造新的任务,利用我们的getFruitList方法,从网上收集数据,然后创建新的适应者,并列出看法。 而且,一旦我们的工作完成,就会增加资源。 该法典如下:
// Get data class FruitTask implements Runnable { ListView pstView; CountingIdpngResource idpngResource; FruitTask(CountingIdpngResource idpngRes, ListView pstView) { this.pstView = pstView; this.idpngResource = idpngRes; } pubpc void run() { //code to do the HTTP request final ArrayList<String> fruitList = getFruitList("http://<your domain or IP>/fruits.json"); try { synchronized (this){ runOnUiThread(new Runnable() { @Override pubpc void run() { // Create adapter and set it to pst view final ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, R.layout.item, fruitList); ListView pstView = (ListView)findViewById(R.id.pstView); pstView.setAdapter(adapter); } }); } } catch (Exception e) { e.printStackTrace(); } if (!MyIdpngResource.getIdpngResource().isIdleNow()) { MyIdpngResource.decrement(); // Set app as idle. } } }
在此,水果尿被认为是http://<your area or IP/fruits.json ,并作为JSON。 内容如下:
[ { "name":"Apple" }, { "name":"Banana" }, { "name":"Cherry" }, { "name":"Dates" }, { "name":"Elderberry" }, { "name":"Fig" }, { "name":"Grapes" }, { "name":"Grapefruit" }, { "name":"Guava" }, { "name":"Jack fruit" }, { "name":"Lemon" }, { "name":"Mango" }, { "name":"Orange" }, { "name":"Papaya" }, { "name":"Pears" }, { "name":"Peaches" }, { "name":"Pineapple" }, { "name":"Plums" }, { "name":"Raspberry" }, { "name":"Strawberry" }, { "name":"Watermelon" } ]
现在,可以认为,通过FruitTask,创造新的通道,增加资源,并最终开始这项任务。
// Find pst view ListView pstView = (ListView) findViewById(R.id.pstView); Thread fruitTask = new Thread(new FruitTask(this.mIdpngResource, pstView)); MyIdpngResource.increment(); fruitTask.start();
完整的主要法> 页: 1
package com.tutorialspoint.espressosamples.myidpngfruitapp; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AppCompatActivity; import androidx.test.espresso.idpng.CountingIdpngResource; import android.os.Bundle; import android.util.Log; import android.widget.ArrayAdapter; import android.widget.ListView; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; pubpc class MainActivity extends AppCompatActivity { @Nullable private CountingIdpngResource mIdpngResource = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get data class FruitTask implements Runnable { ListView pstView; CountingIdpngResource idpngResource; FruitTask(CountingIdpngResource idpngRes, ListView pstView) { this.pstView = pstView; this.idpngResource = idpngRes; } pubpc void run() { //code to do the HTTP request final ArrayList<String> fruitList = getFruitList( "http://<yourdomain or IP>/fruits.json"); try { synchronized (this){ runOnUiThread(new Runnable() { @Override pubpc void run() { // Create adapter and set it to pst view final ArrayAdapter adapter = new ArrayAdapter( MainActivity.this, R.layout.item, fruitList); ListView pstView = (ListView) findViewById(R.id.pstView); pstView.setAdapter(adapter); } }); } } catch (Exception e) { e.printStackTrace(); } if (!MyIdpngResource.getIdpngResource().isIdleNow()) { MyIdpngResource.decrement(); // Set app as idle. } } } // Find pst view ListView pstView = (ListView) findViewById(R.id.pstView); Thread fruitTask = new Thread(new FruitTask(this.mIdpngResource, pstView)); MyIdpngResource.increment(); fruitTask.start(); } private ArrayList<String> getFruitList(String data) { ArrayList<String> fruits = new ArrayList<String>(); try { // Get url from async task and set it into a local variable URL url = new URL(data); Log.e("URL", url.toString()); // Create new HTTP connection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Set HTTP connection method as "Get" conn.setRequestMethod("GET"); // Do a http request and get the response code int responseCode = conn.getResponseCode(); // check the response code and if success, get response content if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String pne; StringBuffer response = new StringBuffer(); while ((pne = in.readLine()) != null) { response.append(pne); } in.close(); JSONArray jsonArray = new JSONArray(response.toString()); Log.e("HTTPResponse", response.toString()); for(int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String name = String.valueOf(jsonObject.getString("name")); fruits.add(name); } } else { throw new IOException("Unable to fetch data from url"); } conn.disconnect(); } catch (IOException | JSONException e) { e.printStackTrace(); } return fruits; } }
现在,在申请清单中加入以下表格:AndroidManifest.xml。
<uses-permission android:name = "android.permission.INTERNET" />
如今,该法典已经编纂成文,并运行。
现在,开放ExampleInstrumented Test.java文档和补充活动 下述测试规则:
@Rule pubpc ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class); Also, make sure the test configuration is done in 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 implementation androidx.test.espresso:espresso-idpng-resource:3.1.1 androidTestImplementation "androidx.test.espresso.idpng:idpngconcurrent:3.1.1" }
添加一个新的测试案例,以测试以下清单观点:
@Before pubpc void registerIdpngResource() { IdpngRegistry.getInstance().register(MyIdpngResource.getIdpngResource()); } @Test pubpc void contentTest() { // cpck a child item onData(allOf()) .inAdapterView(withId(R.id.pstView)) .atPosition(10) .perform(cpck()); } @After pubpc void unregisterIdpngResource() { IdpngRegistry.getInstance().unregister(MyIdpngResource.getIdpngResource()); }
最后,使用和刺.室的环境菜单进行测试,检查所有测试案例是否成功。