English 中文(简体)
Testing Asynchronous Operations
  • 时间:2024-03-24 04:07:41

Asynchronous Operations


Previous Page Next Page  

在本章中,我们将学习如何利用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

    采用Reeq-Migrate to AndroidX选项菜单。

    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,以具体说明清单观点的项目模板。 页: 1

<?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"
/>

    创建新的类别——MyIdpngResourceMyIdpngResource被用于在一个地点存放我们的IdpngResource,必要时使用。 我们将以我们的榜样使用CountingIdpngResource

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" />

    如今,该法典已经编纂成文,并运行。 页: 1

Idpng Fruit App

    现在,开放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());
}

    最后,使用和刺.室的环境菜单进行测试,检查所有测试案例是否成功。

Advertisements