• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yxchun

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

使用 Java 语言编写测试脚本测试App

1、Java+Appium 环境

https://www.jianshu.com/p/1b959e0baae2

2、识别与操作控件元素

找到\Sdk\tools\bin下的uiautomatorviewer.bat双击

点击第一个图标,识别文件属性

  • driver.findElementBy?(属性).sendKeys("数据")
  • driver.findElementBy?(属性).clear()
  • driver.findElementBy?(属性).click()
  • driver.findElementBy?(属性).getText()

3、使用 Java 语言编写测试脚本

public class Appium003 {
    //AppiumDriver含义,建立于Appium的连接
    AppiumDriver driver;
    
  @Test
  public void f() {
  }
  @SuppressWarnings("rawtypes")
@BeforeClass
  public void beforeClass() {
     //创建DesiredCapabilities对象
      //指定测试设备信息
      DesiredCapabilities devices = new DesiredCapabilities();
      //使用的移动设备或模拟器的种类,如 iPhone Simulator,iPad Simulator,Android Emulator,Galaxy S4 等
      devices.setCapability("deviceName", "emulator-5554");
//     指定使用哪个移动操作系统平台,如 iOS,Android 或 FirefoxOS
      devices.setCapability("platformName","Android");
 //指定移动操作系统版本
      devices.setCapability("platformVersion","11");
//      指定 app 程序包名,即被测程序名
      devices.setCapability("appPackage","com.example.calculate");
      devices.setCapability("appActivity","com.example.simplecalculate.MainActivity");
    //A new session could not be created的解决方法
      devices.setCapability("appWaitActivity","com.example.simplecalculate.MainActivity");
      //每次启动时覆盖session,否则第二次后运行会报错不能新建session
      devices.setCapability("sessionOverride", true);
      //启动 App
      try {
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),devices);        driver.findElementById("com.example.calculate:id/guide_button_close").click();
      } catch (MalformedURLException e) {

        e.printStackTrace();
    }
            
  }

  @AfterClass
  public void afterClass() {
    
      driver.quit();
  }

}

@Listeners({TestReport.class})
public class Appium0202 {
    //AppiumDriver含义,建立于Appium的连接
//    AppiumDriver driver;
    AndroidDriver driver;
  @Test
  public void f() {
     /***
      * 方式一,数字是一次一次点击的输入
      * *****/
      System.out.println("进入-----------------------------------");
      driver.findElementById("android:id/button1").click();
      
      driver.findElementById("com.android.calculator2:id/digit2").click();
      driver.findElementById("com.android.calculator2:id/digit0").click();
      
      driver.findElementById("com.android.calculator2:id/plus").click();
      driver.findElementById("com.android.calculator2:id/digit2").click();
      driver.findElementById("com.android.calculator2:id/digit0").click();
      driver.findElementById("com.android.calculator2:id/equal").click();
    
      String result=driver.findElementByClassName("android.widget.EditText").getText();
      System.out.println(result);

      //断言
      Boolean res=result.contains("40");
      Assert.assertTrue(res);
      
      /****
       * 方式二:数字采用循环输入的方式
       * 
       * ****/
      //清除结果框里面的内容
      driver.findElementByClassName("android.widget.EditText").clear();
      
      String  numberA = "234";
      String  numberB = "432";
      String  plus = "plus"; 
      String  equal = "equal";
      for(int i=0;i<numberA.length();i++) {
          driver.findElementById("com.android.calculator2:id/digit"+numberA.charAt(i)).click();
      }
      
      driver.findElementById("com.android.calculator2:id/"+plus).click();
      
      for(int i=0;i<numberB.length();i++) {
          driver.findElementById("com.android.calculator2:id/digit"+numberB.charAt(i)).click();
      }      
      driver.findElementById("com.android.calculator2:id/"+equal).click();  
      
      result=driver.findElementByClassName("android.widget.EditText").getText();
      System.out.println("第二次的结果=="+result);
      Assert.assertEquals(result, "666");
      
      /***
       * 方法三:利用数组的方式,设计用例,详情见   Appium0203
       * ***/
  }
  
  @BeforeClass
  public void beforeClass() {
     //创建DesiredCapabilities对象
      //指定测试设备信息
      DesiredCapabilities devices = new DesiredCapabilities();
      //使用的移动设备或模拟器的种类,如 iPhone Simulator,iPad Simulator,Android Emulator,Galaxy S4 等
      devices.setCapability("deviceName", "emulator-5554");
//     指定使用哪个移动操作系统平台,如 iOS,Android 或 FirefoxOS
      devices.setCapability("platformName","Android");
 //指定移动操作系统版本
      devices.setCapability("platformVersion","11");
//      指定 app 程序包名,即被测程序名
      devices.setCapability("appPackage","com.android.calculator2");
      devices.setCapability("appActivity","com.android.calculator2.Calculator");
    //A new session could not be created的解决方法
      devices.setCapability("appWaitActivity","com.android.calculator2.Calculator");
      //每次启动时覆盖session,否则第二次后运行会报错不能新建session
      devices.setCapability("sessionOverride", true);
      //启动 App
      try {
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),devices);
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
              
  }

  @AfterClass
  public void afterClass() {
      driver.quit();
  }

}
方法三:利用数组的方式,设计用例

public
class Appium0203 { AndroidDriver driver; @Test(dataProvider = "getData") public void f(String number01,String operator,String number02,String expected) { /*** * 方法三:利用数组的方式,设计用例 * ***/ System.out.println("进入-----------------------------------"); //数字一 for(int i=0;i<number01.length();i++) { driver.findElementById("com.android.calculator2:id/digit"+number01.charAt(i)).click(); } //运算符号 String hao=""; switch (operator) { case "+": hao="plus"; break; case "-": hao="minus"; break; case "*": hao="mul"; break; case "/": hao="div"; break; default: hao="plus"; break; } driver.findElementById("com.android.calculator2:id/"+hao).click(); //数字二 for(int i=0;i<number02.length();i++) { driver.findElementById("com.android.calculator2:id/digit"+number02.charAt(i)).click(); } //点击= driver.findElementById("com.android.calculator2:id/equal").click(); String result = driver.findElementByClassName("android.widget.EditText").getText(); Assert.assertEquals(result, expected); //输出结果 System.out.println("结果=="+result); //driver.findElementById("com.android.calculator2:id/del").click(); } @DataProvider public Object[][] getData(){ Object data[][] = {{"234","+","432","666"},{"999","-","333","666"},{"2","*","88","176"}}; return data; } @BeforeClass public void beforeClass() { //创建DesiredCapabilities对象 //指定测试设备信息 DesiredCapabilities devices = new DesiredCapabilities(); //使用的移动设备或模拟器的种类,如 iPhone Simulator,iPad Simulator,Android Emulator,Galaxy S4 等 devices.setCapability("deviceName", "emulator-5554"); // 指定使用哪个移动操作系统平台,如 iOS,Android 或 FirefoxOS devices.setCapability("platformName","Android"); //指定移动操作系统版本 devices.setCapability("platformVersion","11"); // 指定 app 程序包名,即被测程序名 devices.setCapability("appPackage","com.android.calculator2"); devices.setCapability("appActivity","com.android.calculator2.Calculator"); //A new session could not be created的解决方法 devices.setCapability("appWaitActivity","com.android.calculator2.Calculator"); //每次启动时覆盖session,否则第二次后运行会报错不能新建session devices.setCapability("sessionOverride", true); //启动 App try { driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),devices); driver.findElementById("android:id/button1").click(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @AfterClass public void afterClass() { driver.quit(); } }
 方法四:读取外部文件中的测试数据

@Listeners({TestReport.class})
public class Appium0204 {
    //AppiumDriver含义,建立于Appium的连接
//    AppiumDriver driver;
    AndroidDriver driver;
    
  @Test(dataProvider = "getData")
  public void f(String number01,String operator,String number02,String expected) {
      /***
       * 方法四:读取外部文件中的测试数据
       * ***/
      System.out.println("进入-----------------------------------");
      
    //数字一
      for(int i=0;i<number01.length();i++) {
          driver.findElementById("com.android.calculator2:id/digit"+number01.charAt(i)).click();
      }
      //运算符号
      String hao="";
      switch (operator) {
    case "+": 
        hao="plus";
        break;
    case "-":
        hao="minus";
        break;
    case "*":
        hao="mul";
        break;
    case "/":
        hao="div";
        break;    
    default:
         hao="plus";
        break;
    }
      driver.findElementById("com.android.calculator2:id/"+hao).click();
      //数字二
      for(int i=0;i<number02.length();i++) {
          driver.findElementById("com.android.calculator2:id/digit"+number02.charAt(i)).click();
      }
      //点击=
      driver.findElementById("com.android.calculator2:id/equal").click();
    
      
      String result = driver.findElementByClassName("android.widget.EditText").getText();
      Assert.assertEquals(result, expected);
      //输出结果 
      System.out.println("结果=="+result);
      
  }
  
  @DataProvider
  public Object[][] getData() throws Exception{
      List<String[]> rows = new ArrayList<String[]>();
     //读取文件数据
      File file = new File("e:\\calc.txt");
      FileReader bytes = new FileReader(file);
      BufferedReader chars  = new BufferedReader(bytes);
      String row = null;
      while((row = chars.readLine())!=null) {
          String cols[] = row.split("\t");
          rows.add(cols);
      }
      bytes.close();
      Object[][] data = new Object[rows.size()][];
      for(int i=0;i<rows.size();i++) {
          data[i] = rows.get(i);
      }
      return data;
  }
  
  
  @BeforeClass
  public void beforeClass() {
     //创建DesiredCapabilities对象
      //指定测试设备信息
      DesiredCapabilities devices = new DesiredCapabilities();
      //使用的移动设备或模拟器的种类,如 iPhone Simulator,iPad Simulator,Android Emulator,Galaxy S4 等
      devices.setCapability("deviceName", "emulator-5554");
//     指定使用哪个移动操作系统平台,如 iOS,Android 或 FirefoxOS
      devices.setCapability("platformName","Android");
 //指定移动操作系统版本
      devices.setCapability("platformVersion","11");
//      指定 app 程序包名,即被测程序名
      devices.setCapability("appPackage","com.android.calculator2");
      devices.setCapability("appActivity","com.android.calculator2.Calculator");
    //A new session could not be created的解决方法
      devices.setCapability("appWaitActivity","com.android.calculator2.Calculator");
      //每次启动时覆盖session,否则第二次后运行会报错不能新建session
      devices.setCapability("sessionOverride", true);
      //启动 App
      try {
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),devices);
        driver.findElementById("android:id/button1").click();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }        
      
  }

  @AfterClass
  public void afterClass() {
      driver.quit();
  }

}

输出测试报告

测试报告默认存储位置: Java 项目名\test-output

 测试类中添加监听器@Listeners({TestReport.class})即可

如

@Listeners({TestReport.class})
public class Appium0204 {

TestReport.java

package com01;    //修改为正确的包名
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
 
public class TestReport extends TestListenerAdapter{
    private String reportPath;
 
    @Override
    public void onStart(ITestContext context) {
        File htmlReportDir = new File("test-output");
        if (!htmlReportDir.exists()) {
            htmlReportDir.mkdirs();
        }
        String reportName = formateDate()+"_result.html";
        reportPath = htmlReportDir+"/"+reportName;
        File report = new File(htmlReportDir,reportName);
        if(report.exists()){
            try {
                report.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        StringBuilder sb = new StringBuilder("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
                + "<title>自动化测试报告</title></head><body style=\"background-color:#99FFCC;\">"
                + "<div id=\"top\" align=\"center\"><p style=\"font-weight:bold;\">测试用例运行结果列表</p>"            
                + "<table width=\"90%\" height=\"80\" border=\"1\" align=\"center\" cellspacing=\"0\" rules=\"all\" style=\"table-layout:relative;\">"
                + "<thead>"
                + "<tr>"
                + "<th>测试用例名</th>"
                + "<th>测试用例结果</th>"
                + "</tr>"
                + "</thead>"
                + "<tbody style=\"word-wrap:break-word;font-weight:bold;\" align=\"center\">");
        String res = sb.toString();
        try {  
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"));  
        } catch (IOException e) {  
            e.printStackTrace();  
        } 
    }
    
    @Override
    public void onTestSuccess(ITestResult result) {
        StringBuilder sb = new StringBuilder("<tr><td>");
        sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
        sb.append("</td><td><font color=\"green\">Passed</font></td></tr>");
        String res = sb.toString();
        try {
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void onTestSkipped(ITestResult result) {
        StringBuilder sb = new StringBuilder("<tr><td>");
        sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
        sb.append("</td><td><font color=\"yellow\">Skipped</font>");
        sb.append("<p align=\"left\">测试用例<font color=\"red\">跳过</font>,原因:<br>");
        sb.append("<br><a style=\"background-color:#CCCCCC;\">");
        Throwable throwable = result.getThrowable(); 
                sb.append(throwable.getMessage()); 
                sb.append("</a></p></td></tr>");
        String res = sb.toString();
        try {
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void onTestFailure(ITestResult result) {
        StringBuilder sb = new StringBuilder("<tr><td>");
        sb.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName());
        sb.append("</td><td><font color=\"red\">Failed</font><br>");
        sb.append("<p align=\"left\">测试用例执行<font color=\"red\">失败</font>,原因:<br>");
        sb.append("<br><a style=\"background-color:#CCCCCC;\">");
        Throwable throwable = result.getThrowable();
        sb.append(throwable.getMessage());
        sb.append("</a></p></td></tr>");
        String res = sb.toString();
        try {
            Files.write((Paths.get(reportPath)),res.getBytes("utf-8"),StandardOpenOption.APPEND);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void onFinish(ITestContext testContext) {
        StringBuilder sb = new StringBuilder("</tbody></table><a href=\"#top\">返回顶部</a></div></body>");
        sb.append("</html>");
        String msg = sb.toString();
        try {
            Files.write((Paths.get(reportPath)),msg.getBytes("utf-8"),StandardOpenOption.APPEND);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static String formateDate(){
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd HHmmss");
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        return sf.format(date);
    }
}
View Code

断言

1 、Assert.assertTrue(boolean型结果)

 

Ø   写法类似于正则表达式,使用更方便。

Ø   Boolean rs=driver.findElementById(…).getText().contains();

 

Ø   Assert.assertTrue(rs);

2、  Assert.assertEquals(实际结果,预期结果)

 

Ø   用于测试期望结果的断言,即测试两个对象是否相等。

Ø   Stringactual=实际结果;

Ø   Stringexpected=预期结果;

Ø   Assert.assertEquals(actual, expected);

ü   Stringres=driver.findElementByClassName("android.widget.EditText").getText();

 

ü   Assert.assertEquals(res,"3");

模拟按键

8    模拟按键

    driver.pressKeyCode(keycode)
    必须使用 AmdroidDriver
    基本
    KEYCODE_0 按键'0' 7
 
    KEYCODE_1 按键'1' 8
    KEYCODE_2 按键'2' 9
    KEYCODE_3 按键'3' 10
    KEYCODE_4 按键'4' 11
    KEYCODE_5 按键'5' 12
    KEYCODE_6 按键'6' 13
    KEYCODE_7 按键'7' 14
    KEYCODE_8 按键'8' 15
    KEYCODE_9 按键'9' 16
    KEYCODE_A 按键'A' 29
    KEYCODE_B 按键'B' 30
    KEYCODE_C 按键'C' 31
    KEYCODE_D 按键'D' 32
    KEYCODE_E 按键'E' 33
    KEYCODE_F 按键'F' 34
    KEYCODE_G 按键'G' 35
    KEYCODE_H 按键'H' 36
    KEYCODE_I 按键'I' 37
    KEYCODE_J 按键'J' 38
    KEYCODE_K 按键'K' 39
    KEYCODE_L 按键'L' 40
    KEYCODE_M 按键'M' 41
    KEYCODE_N 按键'N' 42
    KEYCODE_O 按键'O' 43
    KEYCODE_P 按键'P' 44
    KEYCODE_Q 按键'Q' 45
    KEYCODE_R 按键'R' 46
    KEYCODE_S 按键'S' 47
    KEYCODE_T 按键'T' 48
    KEYCODE_U 按键'U' 49
    KEYCODE_V 按键'V' 50
    KEYCODE_W 按键'W' 51
    KEYCODE_X 按键'X' 52
    KEYCODE_Y 按键'Y' 53
    KEYCODE_Z 按键'Z' 54
    功能键
    KEYCODE_CALL 拨号键 5
    KEYCODE_ENDCALL 挂机键 6
    KEYCODE_HOME 按键 Home 3
    KEYCODE_MENU 菜单键 82
    KEYCODE_BACK 返回键 4
    KEYCODE_SEARCH 搜索键 84
    KEYCODE_CAMERA 拍照键 27
    KEYCODE_FOCUS 拍照对焦键 80
 
    KEYCODE_POWER 电源键 26
    KEYCODE_NOTIFICATION 通知键 83
    KEYCODE_MUTE 话筒静音键 91
    KEYCODE_VOLUME_MUTE 扬声器静音键 164
    KEYCODE_VOLUME_UP 音量增加键 24
    KEYCODE_VOLUME_DOWN 音量减小键 25
    控制键
    KEYCODE_ENTER 回车键 66
    KEYCODE_ESCAPE ESC 键 111
    KEYCODE_DPAD_CENTER 导航键 确定键 23
    KEYCODE_DPAD_UP 导航键 向上 19
    KEYCODE_DPAD_DOWN 导航键 向下 20
    KEYCODE_DPAD_LEFT 导航键 向左 21
    KEYCODE_DPAD_RIGHT 导航键 向右 22
    KEYCODE_MOVE_HOME 光标移动到开始键 122
    KEYCODE_MOVE_END 光标移动到末尾键 123
    KEYCODE_PAGE_UP 向上翻页键 92
    KEYCODE_PAGE_DOWN 向下翻页键 93
    KEYCODE_DEL 退格键 67
    KEYCODE_FORWARD_DEL 删除键 112
    KEYCODE_INSERT 插入键 124
    KEYCODE_TAB Tab 键 61
    KEYCODE_NUM_LOCK 小键盘锁 143
    KEYCODE_CAPS_LOCK 大写锁定键 115
    KEYCODE_BREAK Break/Pause 键 121
    KEYCODE_SCROLL_LOCK 滚动锁定键 116
    KEYCODE_ZOOM_IN 放大键 168
    KEYCODE_ZOOM_OUT 缩小键 169
    组合键
    KEYCODE_ALT_LEFT Alt+Left
    KEYCODE_ALT_RIGHT Alt+Right
    KEYCODE_CTRL_LEFT Control+Left
    KEYCODE_CTRL_RIGHT Control+Right
    KEYCODE_SHIFT_LEFT Shift+Left
    KEYCODE_SHIFT_RIGHT Shift+Right
View Code

 

posted on 2021-01-26 15:59  yxchun  阅读(893)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3