在 Android Studio 中使用 Espresso 进行 UI 测试
UI 测试是测试应用程序的视觉元素以确保它们是否适当地满足预期功能的过程。手动验证应用程序是否工作是一个耗时且累人的过程,但使用 espresso 我们可以编写运行速度快且扩展性好的自动化测试。 Espresso 是 Google 于 2013 年开发的 Android 自动化用户界面测试框架。在本文中,我们将讨论
- Espresso 框架的基础知识,
- 如何在 Android 中设置 Espresso 框架,以及
- 如何使用简单的 android 应用程序自动化测试环境。
1. Espresso 框架的基础知识
UI 测试剖析
- 取景
- 执行一个动作
- 检查结果
Espresso 主要由三个部分组成:
- ViewMatchers – 它用于使用不同的属性查找视图,例如withId()、withText( )、 withTagKey( ) 等。
- ViewActions – 它用于对 ViewMatchers 中定义的视图执行操作,如click( )、 longClick( )、 scrollTo( ) 等。
- ViewAssertions – 用于断言使用 ViewMatchers 找到的视图和使用match( )、 doesNotExist()等的预期视图相同。
由于 espresso 负责与任何 UI 事件同步,我们不必担心任何视图状态转换和实现细节。现在让我们看一下运行自动化测试的样板代码。
onView(ViewMatcher) // onView takes a viewMatcher like R.id.button
.perform(ViewAction) // perform takes a viewAction like pressing the button
.check(ViewAssertion); // check inspects if the output result is same as the expected result.
在本文中,我们将仅使用某些类型的 ViewMatchers、ViewActions 和 ViewAssertions,但是,可以在官方网站 https://developer.android.com/training/testing/espresso 上找到更多类型/备忘单
2.在Android中设置espresso框架
第 1 步:在依赖项中添加 espresso 库
导航到app > Gradle Script > build.gradle (Module:app) , 添加以下代码行,并同步项目。
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
}
第 2 步:从 Android 设备关闭动画
导航到设置 > 开发人员选项并关闭以下选项:
- 窗口动画比例
- 过渡动画比例
- 动画师持续时间比例
3.使用简单的android应用程序自动化测试环境
我们将构建一个应用程序,用户可以在其中选择他喜欢的语言,并且选择的语言显示在 textView 中。现在,我们将实现一个自动化测试来验证用户选择的首选语言是否显示在 TextView 中。下面给出了一个示例 GIF,以了解我们将在这一部分中做什么。
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅 https://www.geeksforgeeks.org/android-how-to-create-start-a-new-project-in-android-studio/。请注意,选择Java作为编程语言。
第 2 步:如上文第 2 部分所述,在 Android 中设置 espresso 框架。
第 3 步:使用 activity_main.xml 文件
导航到app > res > layout > activity_main.xml并将以下代码添加到该文件。下面是activity_main.xml文件的代码。
XML
Java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Textview to show the language
// chosen by the user
TextView preferred_language;
// onClick is called whenever
// a user clicks a button
public void onClick(View view) {
// whenever a user chooses a preferred language
// by tapping button, it changes the chosen
// language textView
switch (view.getId()){
case R.id.english:
preferred_language.setText("English");
break;
case R.id.french:
preferred_language.setText("French");
break;
case R.id.german:
preferred_language.setText("German");
break;
case R.id.hindi:
preferred_language.setText("Hindi");
break;
case R.id.urdu:
preferred_language.setText("Urdu");
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing the textview
preferred_language = findViewById(R.id.preferred_language);
}
}
Java
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest{
// rule specifies that we are
// running test on MainActivity
@Rule
public ActivityScenarioRule activityScenarioRule = new ActivityScenarioRule<>(MainActivity.class);
// test to check if the preferred language
// of user is displayed under the chosen language or not
@Test
public void selectLanguageAndCheck(){
onView(withId(R.id.german)) // ViewMatchers - withId(R.id.german) is to
// specify that we are looking for Button
// with id = R.id.german
.perform(click()); // ViewActions - Performs click action on view.
onView(withId(R.id.preferred_language)) // ViewMatchers - withId(R.id.preferred_language)
// is to specify that we are looking for a TextView
// with id = R.id.preferred_language
.check(matches(withText("German"))); // ViewAssertions - validates if preferred_language
// matches with the text "German" since we
// pressed german language button.
}
}
第 4 步:使用 MainActivity。Java
转到MainActivity。 Java文件并参考以下代码。下面是MainActivity 的代码。 Java文件。
Java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Textview to show the language
// chosen by the user
TextView preferred_language;
// onClick is called whenever
// a user clicks a button
public void onClick(View view) {
// whenever a user chooses a preferred language
// by tapping button, it changes the chosen
// language textView
switch (view.getId()){
case R.id.english:
preferred_language.setText("English");
break;
case R.id.french:
preferred_language.setText("French");
break;
case R.id.german:
preferred_language.setText("German");
break;
case R.id.hindi:
preferred_language.setText("Hindi");
break;
case R.id.urdu:
preferred_language.setText("Urdu");
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing the textview
preferred_language = findViewById(R.id.preferred_language);
}
}
第 5 步:导航到app > Java > package-name (androidTest) > ExampleInstrumentedTest。打开ExampleInstrumentedTest。 Java文件并参考以下代码。下面是ExampleInstrumentedTest 的代码。 Java文件。添加了注释以在以下代码段中描述 ViewMatchers、ViewAction 和 ViewAssertions。
Java
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest{
// rule specifies that we are
// running test on MainActivity
@Rule
public ActivityScenarioRule activityScenarioRule = new ActivityScenarioRule<>(MainActivity.class);
// test to check if the preferred language
// of user is displayed under the chosen language or not
@Test
public void selectLanguageAndCheck(){
onView(withId(R.id.german)) // ViewMatchers - withId(R.id.german) is to
// specify that we are looking for Button
// with id = R.id.german
.perform(click()); // ViewActions - Performs click action on view.
onView(withId(R.id.preferred_language)) // ViewMatchers - withId(R.id.preferred_language)
// is to specify that we are looking for a TextView
// with id = R.id.preferred_language
.check(matches(withText("German"))); // ViewAssertions - validates if preferred_language
// matches with the text "German" since we
// pressed german language button.
}
}
第 6 步:导航到app > Java > package-name(androidTest) > ExampleInstrumentedTest >右键单击并选择运行 ExampleInstrumentedTest。这将在模拟器/物理设备上运行自动化测试,一旦测试完成,结果将显示在控制台中。
输出:测试用例通过,运行自动化测试只用了 666 毫秒。这表明当我们需要测试应用程序中的 UI 元素时,即使在非常大的范围内,espresso 库也非常方便。下面附上测试用例的慢动作视频,因为自动化测试非常快。
GitHub存储库: https://github.com/garg-lucifer/GFGespresso