11.UiAutomator 相关JAVA知识

一、封装方法与模块化用例

1.方法:

在JAVA中,方法就好比日常生活中的一个动作,由动作组合成一系列完整的操作。

  • 方法结构:
方法修饰符 方法返回值类型 方法名
{
    方法体
}
  • 比如:
public void testDemo1{
    UiDevice.getInstance().pressBack();
}

2.模块化用例:

UI自动化用例为模拟手工动作用例
手工用例为一个个的动作组成

自动化用例也可以拆解成一个个动作组成

将每个动作抽象封装成方法,达到复用和简化维护的目的

  • 示例:
public class Test extends UiAutomatorTestCase {
    //开始
    protected void setUp() throws Exception{
        super.setUp();
        //初始化
        BackApp();
    }
    //进行一系列用例操作
    public void testDemo1() throws UiObjectNotFoundException {
        //点击拨号应用
        open("拨号");
        //输入电话号码
        input("一");
        input("零");
        input("零");
        input("八");
        input("六");
        //按拨号按钮
        CallAndEnd("拨打");
        //通话状态
        sleep(2000);
        //挂断电话
        CallAndEnd("挂断");
    }
    protected void tearDown() throws Exception{
        super.tearDown();
        //结束
        BackApp();
    }
    //从此处开始,下面的代码都可以copy到另外一个类中这样看起来就更直观了
    //初始化和退出操作
    public void BackApp(){
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressHome();
    }
    //点击拨号应用
    public void open(String text) throws UiObjectNotFoundException{
        textSelector(text).clickAndWaitForNewWindow();
    }
    //进行拨号
    public void input(String text) throws UiObjectNotFoundException{
        descSelector(text).click();
    }
    //拨打和挂断
    public void CallAndEnd(String text) throws UiObjectNotFoundException{
        descSelector(text).click();
    }

    //使用text定位对象
    public UiObject textSelector(String text){
        return new UiObject(new UiSelector().text(text));
    }
    //使用description定位对象
    public UiObject descSelector(String desc){
        return new UiObject(new UiSelector().description(desc));
    }
}

二、JAVA基本数据类型与流程控制

1.数据类型

1)基本数据类型

a.数值型
    整数类型

byte

short

int

long

浮点类型

folat

dpuble

b.字符型(char)

c.布尔型(boolean)

2)引用数据类型

类(class)

接口(interface)

数组()

2.流程控制

  • if语句:
if (表达式){
    方法体1
}else{
    方法体2
}
  • switch分支语句:
switch(表达式){
    case 表达式1:{
        执行方法体1
        break;
    }
    case 表达式2:{
        执行方法体2
        break;
    }
    default:{
        都不匹配时执行
    }
}
  • while循环:
while(){
    方法体
}do{
    方法体
}while(表达式);
  • for循环:

    for(初始化变量;表达式;循环表达式){
        方法体
    }
  • 中断循环语句:
break;
continue;

例子:

//一个0-100的随机计算器测试例子
public class Test extends UiAutomatorTestCase {
    protected void setUp() throws Exception{
        super.setUp();
        //初始化
        BackApp();
    }
    public void testDemo1() throws UiObjectNotFoundException{
        //开启APP
        open();
        //第一个随机数
        double one=randomInputData();
        //第一个随机符号
        int operation=getRandomOperation();
        //第二个随机数
        double two=randomInputData();
        //等于
        pressKeyboard("=");
        //断言
        double expected=calculator(one,operation,two);
        assertEquals(expected, getActual(),0.1);
    }
    protected void tearDown() throws Exception{
        super.tearDown();
        //结束
        BackApp();
    }

    //从这里开始往下的代码都可以封装到另一个类中
    //开启APP
    public void open() throws UiObjectNotFoundException{
        descSelector("应用").clickAndWaitForNewWindow();
        textSelector("计算器").clickAndWaitForNewWindow();
    }
    //随机数
    public double randomInputData() throws UiObjectNotFoundException{
        int num=0;
        while(num==0){
            num=new Random().nextInt(100);
        }
        String s=num+"";
        for(int i=0;i<s.length();i++){
            pressKeyboard(s.charAt(i)+"");
        }
        return Double.valueOf(num);
    }
    //按键
    public void pressKeyboard(String text) throws UiObjectNotFoundException{
        textSelector(text).click();
    }
    public int getRandomOperation() throws UiObjectNotFoundException{
        int num=new Random().nextInt(1000);
        if (num<250){
            pressKeyboard("+");
            return 1;
        }else if (num>=250&&num<500){
            pressKeyboard("−");
            return 2;
        }else if (num>=500&&num<750){
            pressKeyboard("×");
            return 3;
        }else{
            pressKeyboard("÷");
            return 4;
        }
    }
    //获取预期结果
    public double calculator(double one,int operation,double two){
        switch (operation) {
        case 1:
            return  one+two;
        case 2:
            return  one-two;
        case 3:
            return  one*two;
        case 4:
            return  one/two;
        }
            return -1;
    }
    //获取实际结果
    public double getActual() throws UiObjectNotFoundException{
        String result=getClassName("android.widget.EditText").getText();
        //负数、小数点
        if (result.contains("减")){
            result=result.replace("减", "-");
        }
        if (result.contains("点")){
            result.replace("点", ".");
        }
        return Double.valueOf(result);
    }
    //使用text定位对象
    public UiObject textSelector(String text){
        return new UiObject(new UiSelector().text(text));
    }
    //使用类名定位对象
    public UiObject getClassName(String className){
        return new UiObject(new UiSelector().text(className));
    }
    //使用description定位对象
    public UiObject descSelector(String desc){
        return new UiObject(new UiSelector().description(desc));
    }
    //初始化和退出操作
    public void BackApp(){
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressBack();
        UiDevice.getInstance().pressHome();
    }
}

三、数组与集合:

1.数组:

一组对象的集合,且对象的类型相同

1)数组分类:

一维数组
多维数组

2)数组书写格式:

类型 数组名[]=new 类型[数组长度]

类型[]数组名=new 类型[数组长度]

类型[][]数组名=new 类型p[数组长度][数组长度]

类型 数组名[][]=new 类型[数组长度][数组长度]

  • 例如:
intk[]=new int[]100;//0-99
int[]k=new int[100];
int[][] k=new int[2][100];
intk[][]=new int [2][100];

2.集合:

集合是对某一对象的统称,以某种方式组合在一起的对象

1)集合类型:

List:列表,元素保持一定的顺序,可重复
Set:集合,不包含重复元素的集合

Map:关键字和值的集合,形式为,键=值

  • 例如:
ArrayList<String> list=new ArrayList<String>();
HashSet<String> set =new HashSet<String>();
HashMap<String,string> map=new HashMap<String,String>();

3.示例:

获得文件列表的所有文件名与列表数量
//通过HashMap来统计列表的数量

public class Test extends UiAutomatorTestCase {
    protected void setUp() throws Exception{
        super.setUp();
        //初始化
        BackApp();

    }
public void testDemo2() throws UiObjectNotFoundException{
    int count=getListCount();
    //打开文件管理
    launchApp("文件管理器");
    //输出文件数量
    System.out.println("List Count:"+count);
}

protected void tearDown() throws Exception{
    super.tearDown();
    //结束
    BackApp();
}
//从这里开始下面的代码都可以封装到另外一个类中
//开启APP
public void launchApp(String app) throws UiObjectNotFoundException{
    descSelector("应用").clickAndWaitForNewWindow();
    textSelector(app).clickAndWaitForNewWindow();
}
//获取文件个数和大小
public int getListCount() throws UiObjectNotFoundException{
    HashSet<String> fileName=new HashSet<String>();
    UiScrollable list=getScrollObjecyByClass(ListView.class.getName());
    UiSelector selector=new UiSelector().className("android.widget.LinearLayout");
    list.scrollToBeginning(5);
    boolean flag=false;
    while(true){
        int count=list.getChildCount(selector);
        for (int i=0;i<count;i++){
            String name=list.getChildByInstance(selector, 1)
            .getChild(new UiSelector().className("android.widget.TextView"))
            .getText();
            fileName.add(name);
        }
        if (flag){
            break;
        }
        if(!list.scrollForward(80)){
            flag=true;
        }
    }
    return fileName.size();
}
//滑动搜索
public UiScrollable getScrollObjecyByClass(String className){
    return new UiScrollable(new UiSelector().className(className));
}
//初始化和退出操作
public void BackApp(){
    UiDevice.getInstance().pressBack();
    UiDevice.getInstance().pressBack();
    UiDevice.getInstance().pressBack();
    UiDevice.getInstance().pressHome();
    sleep(500);
}
//使用text定位对象
public UiObject textSelector(String text){
    return new UiObject(new UiSelector().text(text));
}
//使用类名定位对象
public UiObject getClassName(String className){
    return new UiObject(new UiSelector().text(className));
}
//使用description定位对象
public UiObject descSelector(String desc){
    return new UiObject(new UiSelector().description(desc));
}
}

四、继承与接口

1.继承:

子类继承父类(超类)的所有功能,关键字:extends

  • 例如:
public class a{
//超类
    public int add(){
        System.out.println("add");
    }
}

//子类

public class b extends a{
    //可以直接使用父类的方法
    public void printAdd(){
        add();
    }
}

2.接口:

完成描述某个事物特定功能,如产品说明书,关键字:interface

接口用例使用场景:对一些固定的用例,不需要变化和不能变化的用例实行接口化

场景例子:性能测试用例,冒烟测试用例等

  • 实例:
//1.像创建UiAutomator那样做到新建好类的那一步
//2.右键包名--[new]--[interface]创建好一个接口,然后创建好你要的用例名如下:
public interface FileManagerInterface {
    public void testNewFolder();
    public void testFile();
    public void testSelectAll();
    public void testAddToBookmarks();
    public void testSetAsHome();
}
//3.在你的test类中选中添加的接口。
public class FileMnagerTestCase implements FileManagerInterface{

}
//4.此时他会自动添加方法进去,变为:
public class FileMnagerTestCase implements FileManagerInterface {
    public static void main(String [] args){
        new UiAutomatorHelper("test","testDemo1.test1","testDemo1","2");
    }

    @Override
    public void testNewFolder() {
        // TODO Auto-generated method stub

    }

    @Override
    public void testFile() {
        // TODO Auto-generated method stub

    }

    @Override
    public void testSelectAll() {
        // TODO Auto-generated method stub

    }

    @Override
    public void testAddToBookmarks() {
        // TODO Auto-generated method stub

    }

    @Override
    public void testSetAsHome() {
        // TODO Auto-generated method stub

    }
}
//5.然后在相应的方法名中添加相应的用例步骤即可
//6.如果要继承多个接口,只需在public class FileMnagerTestCase implements FileManagerInterface 后面加",接口名"即可,比如public class FileMnagerTestCase implements FileManagerInterface ,FileManagerInterface 2{}

3.实现接口:

实现接口描述的功能,关键字:implements

  • 例如:
//接口
public interface a{
    public int add();
}

//实现接口
public class b inplements a {
    public int add(){
        System.out.println("add");
    }
}

五、文件流与多线程

1.文件流

null 从文件读取操作 写入文件
文件 File File
逐个字节 InputStream OutputStream
从文件逐个字节操作 FileInputStream FileOutStream
字节到字符的桥梁 InputStreamReader OutStreamReader
逐行读取操作String BufferedReader BufferedWriter

2.多线程

在同一个时间类同时执行多个操作,如一手画圆一手画方

实现Runnable接口来定义线程,格式如下:

public class RunnableThread implements Runnable{
    public void run(){

    }
}

3.实例:

保存每条用例运行的logcat输出信息

setUp 启动log线程,线程包括读取log和保存log到SD卡中
test

tearDown 销毁的时候,会将本用例所有的线程都自动结束

1)新建一个类文件

// 1.实现接口
public class logCatTread implements Runnable{
    public BufferedWriter bW=null;
    //文件夹路径
    private String pathDir="/mnt/sdcard/testDemo";
    //文件路径
    private String path="";
    @Override
    //2.另一个线程中要做的事情写在run方法里
    public void run() {
        //文件路径=文件夹路径+分隔符+文件名test
        path=pathDir+File.separator+"test.txt";
        try{
            //执行系统命令"logcat -c"清除旧的log
            Runtime.getRuntime().exec("logcat -c");
            //执行系统命令"mkdir"+pathDir在指定路径创建文件夹
            Runtime.getRuntime().exec("mkdir"+pathDir);
            //执行系统命令"touch"+path)在指定路径创建文件
            Runtime.getRuntime().exec("touch"+path);
            //开始取log
            //按时间格式输出log"logcat -v time"
            Process process=Runtime.getRuntime().exec("logcat -v time");
            //获取错误流
            InputStream inputStream=process.getInputStream();
            //中间变量
            InputStreamReader in=new InputStreamReader(inputStream);
            //读取
            BufferedReader reader=new BufferedReader(in);
            //开始逐行读取输出
            String line="";
            while((line=reader.readLine())!=null){
                System.out.println(line);
                saveFile(line,path);
            }
        }catch(Exception e){

        }
    }
    //3.保存文件的方法
    //声明日志+路径
    public BufferedWriter saveFile(String line,String path){

        File file=new File(path);
        try{
            FileOutputStream stream=new FileOutputStream(file,true);
            OutputStreamWriter out=new OutputStreamWriter(stream);
            bW=new BufferedWriter(out);
            //一行一行附加上去
            bW.append(line);
            //新建一行
            bW.newLine();
            //刷进去
            bW.flush();
        }catch(Exception e){
        }
        return bW;
    }

}

2)再新建一个类文件开始多线程用例

public class logCat extends UiAutomatorTestCase{
    //快速调试
    public static void main(String [] args){
        new UiAutomatorHelper("test","testDemo2.logCat","testDemo","2");
    }
    @Override
    //启动
    protected void setUp() throws Exception {
        super.setUp();
        //启动线程
        new Thread(new logCatTread()).start();
    }
    //用例
    public void testDemo(){
        //随便编辑一条用例方便输出日志信息
        for(int i=0;i<30;i++){
            UiDevice.getInstance().pressMenu();
        }
    }
    @Override
    //结束
    protected void tearDown() throws Exception {
        super.tearDown();
    }
}

六、网络编程

Socket通讯基本模型

  • 实例:
//1.先新建一个服务器工程(新建java工程–新建包–新建类),相关代码如下:

public class Sever {
    public static void main(String[] args){
        int port=9998;
        try{
        //启动服务
        final ServerSocket server=new ServerSocket(port);
        //输出提示语
        System.out.println("The server is running..");
        //输出服务
        System.out.println(server);
        //无限循环
        while(true){
            //类似于sleep效果
            final Socket socket=server.accept();
            //新建线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //要处理的动作:读取
                    Reader reader;
                    try{
                        //获取读取内容
                        reader=new InputStreamReader(socket.getInputStream());
                        char[] chars=new char[64];
                        int len;
                        //不断读取就要不断创建对象
                        StringBuilder sb=new StringBuilder();
                        //不断附加消息
                        while((len=reader.read(chars))!=-1){
                            sb.append(new String(chars,0,len));
                        }
                        //读取完后输出消息
                        System.out.println("From client:"+sb);
                    } catch(Exception e ){

                    }
                }

        }).start();//线程的开始
        }

        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

//2.新建用例,也就是客户端向服务器发送消息,正常的新建uiautomator的方法。代码如下:

public class testDemo extends UiAutomatorTestCase{
    //快速调试
    public static void main(String [] args){
        new UiAutomatorHelper("test","ScketCase.testDemo","testDemo1","2");
    }
    //开始
    @Override
    protected void setUp() throws Exception {
        // TODO Auto-generated method stub
        super.setUp();
    }
    //用例
    public void testDemo1(){
        String className=getClass().toString();
        String testName=getName().toString();
        String flag="mms test";
        String mms=className+","+testName+","+flag;
        //向服务器发送一条消息
        sendMMSSocket(mms,"172.16.2.83",9998);//这里的IP是本机IP
        //多发送几条,方便查看
        for(int i=0;i<10;i++){
            sendMMSSocket(i+":"+mms,"172.16.2.83",9998);
        }
    }

    //发送消息的方法
    public void sendMMSSocket(String mms,String host,int port){
        Socket client;
        try{
            client=new Socket(host,port);

            Writer writer=new OutputStreamWriter(client.getOutputStream());
            writer.write(mms);
            writer.flush();
            writer.close();
            writer.close();
        }catch (Exception e ){

        }
    }
    //结束
    @Override
    protected void tearDown() throws Exception {
        // TODO Auto-generated method stub
        super.tearDown();
    }
}

//调试过程中先run服务器工程,然后run用例,观察控制台消息

时间: 2024-10-25 21:18:08

11.UiAutomator 相关JAVA知识的相关文章

Java知识回顾 (11) 异常处理

距离最近的 Java知识回顾系列(10),2019.4.24日,到现在,已经近半年过去了. 感觉,做一件事情,如果有头无尾,实在不好,心里会一直悬着.所以,现在继续上面的内容. 再次声明,正如(1)中所描述的,本资料来自于runoob,略有修改. 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error. 异常发生的原因有很多,通常包含以下几大类: 用户输入了非法数据. 要打开的文

测试必备之Java知识(四)———— 线程相关

线程相关 Java多线程实现方式 继承Thread,实现Runnable接口,实现Callable接口(能抛异常且有返回值,不常用) 为什么有了继承Thread方式还要有Runnable接口方式 实现接口的方式适合多个相同程序代码的线程去处理同一个资源,可以避免Java中单继承的限制 为什么JVM启动是多线程的? 因为至少启动了两个线程:主线程.垃圾回收线程 线程和进程的含义 进程:是操作系统资源分配的基本单位,正在运行的程序 线程:是任务调度和执行的基本单位,程序使用CPU的最基本单位 多线程

【RAC】RAC相关基础知识

[RAC]RAC相关基础知识 1.CRS简介    从Oracle 10G开始,oracle引进一套完整的集群管理解决方案—-Cluster-Ready Services,它包括集群连通性.消息和锁.负载管理等框架.从而使得RAC可以脱离第三方集群件,当然,CRS与第三方集群件可以共同使用. (1).CRS进程 CRS主要由三部分组成,三部分都作为守护进程出现 <1>CRSD:资源可用性维护的主要引擎.它用来执行高可用性恢复及管理操作,诸如维护OCR及管理应用资源,它保存着集群的信息状态和OC

磁盘相关的知识

每一块硬盘都由一个或多个盘片组成,每一个盘片都有两个可以读写的盘面组成. 硬盘的逻辑组成: 磁道(Track):盘片的同心圆就称为磁道. 柱面(Cylinder):所有盘片的同一个磁道就组成了柱面.柱面是分区的最小单位. 扇区(Sector):存储数据的最小单位.每一个扇区为512字节.扇区包含用户数据.以及该扇区的一些标识信息,如所位于的磁头.磁道等编号信息. MBR:Master Boot Record MBR位于0盘片,0磁道,0扇区的512字节.MBR属于磁盘,不属于任何分区. MBR有

java知识查漏补缺

一.重写(override)和重载(overload)的区别 二者除了名字相似,其实没什么联系 范围不同:重写发生在同一个类的不同方法之间.重载发生在父类和子类自荐. 前提: 重写要求:方法名相同,参数列表不同,对于返回值类型不要求相同. 重载要求:方法名形同,参数列表也相同.重载是实现多态的关键,注意如果父类中的方法是private类型,那么子类中对应方法不算重载,而相当于是定义了一个新方法. 二.final的用法 修饰类:该类不能被继承 修饰方法:该方法不能被重写 修饰属性:该属性初始化后不

网络连接相关基础知识笔记

一.常说的TCP/IP的含义 TCP/IP协议簇并不仅仅指TCP协议和IP协议,实际它包括了一系列协议组成的集合,如:TCP,IP,UDP,FTP,SMTP,DNS,ARP,PPP等 TCP与UDP协议都属于传输层协议,但有很大不同,TCP是面向连接的协议,提供的是可靠的数据流服务,TCP采用"带重传的肯定确认"机制来实现传输的可靠性,实现了一种"虚电路",因为从物理上来说,并不是真正在两台主机间建立了连接,这种连接只是存在于逻辑上的.最大的开销出现在通信前建立连接

图像增强相关基础知识

图像增强处理-1 图像增强是图像处理中一个重要的内容,在图像生成,传输或变换的过程中,由于多种因素的影响,造成图像质量下降,图像模糊,特征淹没,给分析和识别带来困难.因此,按特定的需要将图像中感兴趣的特征友选择地突出,衰减不需要的特征,提高图像的可懂度是图像增强的主要内容.图像增强不考虑图像降质的原因,而且改善后的图像也不一定逼近原图像,这是它与图像复原本质的区别.图像增强的主要目的有两个:一是改善图像的视觉效果,提高图像的清晰度:二是将图像转换成一种更适合人类或机器进行分析处理的形式,一边从图

MySQL相关操作知识

1.解决客户端联不上MySQL服务器的问题: GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '' WITH GRANT OPTION; FLUSH PRIVILEGES; 2.登陆MySQL: mysql -u root -p 123456 3.查看所有数据库:show databases; //注意s和分号 4.选择数据库:use 库名 5.查看当前选择的数据库:select database(); //注意分号 6.列出所选数

java 知识收集

1,若方法传入的对象参数为空,则在方法中改变参数并不会改变声明的对象 public void setList(List<String> list){ list = new ArrayList<String>() ; } @Test public void t4(){ List<String> list = null ; setList(list); System.out.println(list );//输出 null } 2,不要再foreach遍历的时候删除 jav