Android测试总结
16lz
2021-01-23
Android测试总结
[TOC]
简介
最近整理了Android测试方便的只是,主要涉及代码测试和自动化测试。
代码测试
Junit
JUnit浅谈
Mockito
Mockito浅谈
Mockwebserver
MockWebServer
Android自动化测试
Android monkey
Android Monkey整理
Android monkeyrunner
Android monkeyrunner整理
Android UIAutomator
Android UIAutomator浅谈
Android Espresso
Android Espresso浅谈
自动化测试示例
下面示例一个Android项目,就是一个简单的登录页面,依次使用上面介绍的自动化测试方案测试界面。
首先是界面布局:
<?xml version="1.0" encoding="utf-8"?>
其次是页面代码:
package cn.mycommons.testcase;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends AppCompatActivity { EditText edtUserName; EditText edtPasswd; Button btnLogin; String userName; String passwd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtUserName = (EditText) findViewById(R.id.edtUserName); edtPasswd = (EditText) findViewById(R.id.edtPasswd); btnLogin = (Button) findViewById(R.id.btnLogin); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { userName = edtUserName.getText().toString(); passwd = edtPasswd.getText().toString(); if (check(userName, passwd)) { doLogin(userName, passwd); } } }); } boolean check(String userName, String passwd) { do { if (userName.length() < 5) { showToast("User name invalidate"); break; } if (passwd.length() < 5) { showToast("Password invalidate"); break; } return true; } while (false); return false; } void doLogin(String userName, String passwd) { if ("admin".equals(userName) && "admin".equals(passwd)) { showToast("Login success"); startActivity(new Intent(this, SuccessActivity.class)); } else { showToast("Login fail"); } } void showToast(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }}
Monkey
Monkey只是检查使用下shell命令即可。
adb shell monkey -p cn.mycommons.testcase -v 50000
Monkey Runner
Monkey Runner提供的是一个python文件,然后调用monkeyrunner命令即可。
$ monkeyrunner test_case.py
# Imports the monkeyrunner modules used by this programfrom com.android.monkeyrunner import MonkeyRunner, MonkeyDevice# Connects to the current device, returning a MonkeyDevice objectprint 'wait for device connection.'device = MonkeyRunner.waitForConnection()print 'connect device success.'# Takes a screenshotresult = device.takeSnapshot()print 'takeSnapshot success.'# Writes the screenshot to a fileresult.writeToFile('./test_case1.png','png')print 'save image to file success.'# input user namedevice.touch(200,380,'DOWN_AND_UP')print 'touch user name'for x in xrange(1,100): device.press("KEYCODE_DEL",'DOWN_AND_UP')print 'delete user name'device.type("admin")print 'input admin to user name'# input passwd device.touch(200,500,'DOWN_AND_UP')print 'touch password'for x in xrange(1,100): device.press("KEYCODE_DEL",'DOWN_AND_UP')print 'delete password'device.type("admin")print 'input admin to password'# press login buttondevice.touch(200,680,'DOWN_AND_UP')print 'press login button'MonkeyRunner.sleep(2)# Takes a screenshotresult = device.takeSnapshot()print 'takeSnapshot success.'# Writes the screenshot to a fileresult.writeToFile('./test_case2.png','png')print 'save image to file success.'
UiAutomator
package cn.mycommons.testcase;import android.content.Context;import android.content.Intent;import android.os.Build;import android.support.test.InstrumentationRegistry;import android.support.test.filters.SdkSuppress;import android.support.test.runner.AndroidJUnit4;import android.support.test.uiautomator.By;import android.support.test.uiautomator.UiDevice;import android.support.test.uiautomator.UiObject;import android.support.test.uiautomator.UiObjectNotFoundException;import android.support.test.uiautomator.UiSelector;import android.support.test.uiautomator.Until;import org.hamcrest.Matchers;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import static org.junit.Assert.assertThat;@RunWith(AndroidJUnit4.class)@SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN_MR2)public class MainActivityTest { private static final String BASIC_SAMPLE_PACKAGE = "cn.mycommons.testcase"; private static final int LAUNCH_TIMEOUT = 5000; private static final String STRING_TO_BE_TYPED = "UiAutomator"; private UiDevice mDevice; @Before public void before() { mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); mDevice.pressHome(); // Wait for launcher final String launcherPackage = mDevice.getLauncherPackageName(); assertThat(launcherPackage, Matchers.notNullValue()); mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT); Context context = InstrumentationRegistry.getContext(); final Intent intent = context.getPackageManager().getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(intent); // Wait for the app to appear mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT); } @Test public void testLogin1() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText("admin"); edtPasswd.setText("admin"); login.click(); mDevice.waitForWindowUpdate(BuildConfig.FLAVOR, 3000); } @Test public void testLogin2() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText(""); edtPasswd.setText(""); login.click(); } @Test public void testLogin3() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText("abc"); edtPasswd.setText(""); login.click(); } @Test public void testLogin4() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText(""); edtPasswd.setText("abc"); login.click(); } @Test public void testLogin5() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText("abc"); edtPasswd.setText("abc"); login.click(); } @Test public void testLogin6() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText("abcedf"); edtPasswd.setText("abc"); login.click(); } @Test public void testLogin7() throws UiObjectNotFoundException { UiObject login = mDevice.findObject(new UiSelector().text("Login")); UiObject edtUserName = mDevice.findObject(new UiSelector().text("Input user name")); UiObject edtPasswd = mDevice.findObject(new UiSelector().descriptionContains("Input password")); edtUserName.clearTextField(); edtPasswd.clearTextField(); edtUserName.setText("abcedf"); edtPasswd.setText("abcedf"); login.click(); }}
Espressor
package cn.mycommons.testcase;import android.support.test.espresso.Espresso;import android.support.test.espresso.action.ViewActions;import android.support.test.espresso.matcher.ViewMatchers;import android.support.test.rule.ActivityTestRule;import android.support.test.runner.AndroidJUnit4;import org.junit.Rule;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(AndroidJUnit4.class)public class MainActivityEspressoTest { @Rule public ActivityTestRule testRule = new ActivityTestRule<>(MainActivity.class); @Test public void testLogin() { Espresso.onView(ViewMatchers.withContentDescription(R.id.edtUserName)).perform(ViewActions.typeText("admin")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("admin")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); } @Test public void testLogin1() { Espresso.onView(ViewMatchers.withId(R.id.edtUserName)).perform(ViewActions.typeText("")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); } @Test public void testLogin2() { Espresso.onView(ViewMatchers.withId(R.id.edtUserName)).perform(ViewActions.typeText("abc")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); } @Test public void testLogin3() { Espresso.onView(ViewMatchers.withId(R.id.edtUserName)).perform(ViewActions.typeText("")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("abc")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); } @Test public void testLogin4() { Espresso.onView(ViewMatchers.withId(R.id.edtUserName)).perform(ViewActions.typeText("abc")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("abc")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); } @Test public void testLogin5() { Espresso.onView(ViewMatchers.withId(R.id.edtUserName)).perform(ViewActions.typeText("abcdef")); Espresso.onView(ViewMatchers.withId(R.id.edtPasswd)).perform(ViewActions.typeText("abcdef")); Espresso.onView(ViewMatchers.withId(R.id.btnLogin)).perform(ViewActions.click()); }}
自动化测试总结
Monkey
准确来说,这不算是自动化测试,因为其只能产生随机的事件,无法按照既定的步骤操作;Monkeyrunner
优点:操作最为简单,可以录制测试脚本,可视化操作;
缺点:主要生成坐标的自动化操作,移植性不强,功能最为局限,上面代码中已经显示出来,完全使用的数字坐标,移植到另外一个设备,则不能运行。UiAutomator
优点:可以对所有操作进行自动化,操作简单;
缺点:Android版本需要高于4.3,无法根据控件ID操作,相对来说功能较为局限,但也够用了;Espresso
优点:主要针对某一个APK进行自动化测试,APK可以有源码,也可以没有源码,功能强大;
缺点:针对APK操作,因此操作相对复杂;
总结:由上面介绍可以有这样的结论:测试某个APK,可以选择Espresso;测试过程可能涉及多个APK,选择UiAutomator;一些简单的测试,选择Monkeyrunner;
更多相关文章
- android sqlite的一些简单的操作
- Android 代码当中动态改变某个控件的位置
- Android单元测试例子
- android操作sdcard
- android 获取本机号码及应加的权限 代码
- 零成本实现Android/iOS自动化测试:基于Appium和Test Perfect
- 代码设置RelativeLayout相对位置设置
- android瀑布流代码