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;

更多相关文章

  1. android sqlite的一些简单的操作
  2. Android 代码当中动态改变某个控件的位置
  3. Android单元测试例子
  4. android操作sdcard
  5. android 获取本机号码及应加的权限 代码
  6. 零成本实现Android/iOS自动化测试:基于Appium和Test Perfect
  7. 代码设置RelativeLayout相对位置设置
  8. android瀑布流代码

随机推荐

  1. Android一周时间早中晚排班表
  2. android中widgets开发入门(开发显示电源电
  3. android TextView 图文混排
  4. Android系统启动之配置文件解析
  5. 一个android个人开发者的总结
  6. Android(安卓)O Treble框架
  7. (转载)Android应用程序签名系统的签名(Sign
  8. Android处理延时加载的方法
  9. Android(安卓)savedInstanceState的作用
  10. android退出所有的activity