• /**
    * 实现自动登陆jenkins,并自动更新每个后续请求的cookie,
    * 以触发demo job的构建为例
    * http://jenkins.testing-studio.com:8081/job/demo/
    */

    @Test
    public void test1(){
    String loginapi = "http://jenkins.testing-studio.com:8081/j_acegi_security_check";
    HashMap paramsMap = new HashMap();
    paramsMap.put("j_username","xinxi");
    paramsMap.put("j_password","xxxxxx");
    paramsMap.put("from","/");
    paramsMap.put("json","{\"j_username\": \"xinxi\", \"j_password\": \"123321\", " +
    "\"remember_me\": false, \"from\": \"/\"}");
    paramsMap.put("Submit","登录");
    Response response = (Response) given().redirects().follow(false).params(paramsMap).get(loginapi).then().extract();
    final Map<String, String> logincookie = response.getCookies();
    System.out.println("获取登录的Cookies:" + logincookie);
    System.out.println("开始创建filters" );
    filters(new Filter() {
    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext filterContext) {
    requestSpec.cookies(logincookie);
    Response response = filterContext.next(requestSpec, responseSpec);
    return response;
    }
    });
    Map headerMap = new HashMap();
    headerMap.put("Connection","keep-alive");
    headerMap.put("Host","jenkins.testing-studio.com:8081");
    headerMap.put("Referer","http://jenkins.testing-studio.com:8081/job/demo/");
    headerMap.put("Accept","text/javascript, text/html, application/xml, text/xml, */*");
    headerMap.put("Origin","http://jenkins.testing-studio.com:8081");
    String buildapi = "http://jenkins.testing-studio.com:8081/job/demo/build";
    given().log().all().headers(headerMap).post(buildapi).then().statusCode(201).extract();
    }



    /**
    * 实现http://jenkins.testing-studio.com:9001/base64base64.json
    * 解密并进行结果断言
    */

    @Test
    public void test2(){
    filters(new Filter() {
    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {
    Response response = ctx.next(requestSpec, responseSpec);
    System.out.println("origin response");
    System.out.println(response.getBody().asString());
    System.out.println("decode response");
    String str = deepdecodeBase64(response.getBody().asString());
    Response newResponse = new ResponseBuilder().clone(response)
    .setContentType(ContentType.JSON)
    .setBody(str)
    .build();
    System.out.println("response filter");
    System.out.println(newResponse.getBody().asString());
    return newResponse;

    }
    });

    String url = "http://jenkins.testing-studio.com:9001/base64base64.json";
    Response response = (Response) given().auth().basic("hogwarts", "123456").
    get(url).then().extract();
    Assert.assertEquals(response.path("data.items.quote.findAll{it.symbol=='SH000001'}.size()"),1);
    }


    /***
    * 递归解析base64
    * @param str
    * @return
    */

    public static String deepdecodeBase64(String str){
    if (str.contains("{") && str.contains("}") ){
    return str;
    }else {
    String newStr = new String(Base64.decodeBase64(str));
    return deepdecodeBase64(newStr);
    }
    }

  • public class Demo2 {

    public Map paramsMap;
    public String apipath;
    public Map cookiesMap;

    @BeforeMethod
    public void preData(){
    useRelaxedHTTPSValidation();
    apipath = "https://stock.xueqiu.com/v5/stock/batch/quote.json";
    paramsMap = new HashMap();
    paramsMap.put("symbol","SH000001,SZ399001,SZ399006,HKHSI,HKHSCEI,HKHSCCI,.DJI,.IXIC,.INX");
    cookiesMap = new HashMap();
    cookiesMap.put("xq_a_token","9c75d6bfbd0112c72b385fd95305e36563da53fb");
    cookiesMap.put("xq_r_token","9ad364aac7522791166c59720025e1f8f11bf9eb");

    }


    /**
    * 测试点:
    * 1.断言状态码==200
    * 2.断言items_size > 0
    * 3.断言结果中SH000001存在
    */

    @Test
    public void test_xueqiu(){
    given().params(paramsMap).cookies(cookiesMap).when().get(apipath).then().log().all().statusCode(200).
    body("data.items.size()",greaterThan(0)).
    body("data.items.find { data -> data.quote }.quote.symbol",equalTo("SH000001"));
    }
    }
  • @Test
    public void test2() {
    String url = "http://testerhome.com/api/v3/topics.json";
    int limit = 20;
    given().queryParam("limit", limit).get(url).then().statusCode(200).
    body("topics.findAll { it.title == '美团技术沙龙北京站:千万级日活 App 的质量保证' }.user.name[0]",equalTo("美团点评"));
    }
  • uiautomator2只能做android项目,atx可以做android和ios.u2是atx下的一个子项目,个人理解

  • iOS 自动化性能采集 at 2018年09月12日

    demo代码里边有需要的性能文件代码,需要在打包前用shell脚本自动化插入到被测代码中.
    关于性能报告需要用一个自己写一个服务.
    我再整理下脚本代码,最终做的形态是执行shell脚本插入被测代码和生成性能报告,写好的话我会放到git上的

  • iOS 自动化性能采集 at 2018年09月12日

    嗯 后续会再写一个性能测试的帖子,会根据一些实际的工作项目

  • iOS 自动化性能采集 at 2018年09月08日

    这个monkey类似app的自动遍历吧,通过配置一些策略可以让monkey更精准到达页面,目前monkey还有优化中,大致可以通过monkey产生的性能数据,看出当前app的性能高峰值.

  • Android Monkey 小记 at 2018年09月03日

    多谢 又学习了

  • 作业1

    仅遍历首页maxDepth设置为2
    selectedList配置遍历控件规则

    ---
    pluginList:
    - "com.testerhome.appcrawler.plugin.FlowDiff"
    logLevel: "TRACE"
    saveScreen: true
    showCancel: true
    reportTitle: "AppCrawler测试报告"
    screenshotTimeout: 20
    tagLimitMax: 2
    currentDriver: "android"
    maxTime: 10800
    maxDepth: 1
    resultDir: ""
    capability:
    newCommandTimeout: 120
    launchTimeout: 120000
    platformVersion: ""
    platformName: ""
    autoWebview: "false"
    autoLaunch: "true"
    noReset: "false"
    deviceName: "demo"
    appPackage: "com.xueqiu.android"
    appActivity: ".view.WelcomeActivityAlias"
    app: ""
    appium: "http://127.0.0.1:4723/wd/hub"
    fullReset: false
    noReset: true
    automationName: uiautomator2

    selectedList:
    - xpath: //*[@clickable="true"]//android.widget.TextView[string-length(@text)>0 and string-length(@text)<20]
    - xpath: //android.widget.EditText
    - xpath: //*[contains(name(), 'Image')]

    ...

    作业2
    yaml中配置triggerActions进入手机号登录流程

    #触发器
    triggerActions:
    - xpath: //*[contains(@resource-id, "com.xueqiu.android:id/user_profile_icon")]
    action: click
    times: 2

    - xpath: //*[contains(@resource-id, "com.xueqiu.android:id/tv_login")]
    action: click
    times: 2

    - xpath: //*[contains(@class, "android.widget.EditText") and contains(@resource-id, "com.xueqiu.android:id/register_phone_number")]
    action: 18513571179
    times: 1
    - xpath: //*[contains(@class, "android.widget.EditText") and contains(@resource-id, "com.xueqiu.android:id/register_code")]
    action: 1234
    times: 1

    - xpath: //*[contains(@resource-id, "com.xueqiu.android:id/button_next")]
    action: click
    times: 2

    作业三
    maxDepth设置为3

    #触发器
    triggerActions:
    - xpath: //*[contains(@resource-id, "com.xueqiu.android:id/tab_name") and contains(@text, "行情")]
    action: click
    times: 2

    selectedList:
    - xpath: //*[@clickable="true"]//android.widget.TextView[string-length(@text)>0 and string-length(@text)<20]
    - xpath: //android.widget.EditText
    - xpath: //*[contains(name(), 'Image')]
  • mark一下遇到问题

    1.iOS移动端浏览器测试
    问题:使用iOSSafari打开www.baidu.com,定位By.id("kw"),报错元素找不到

    解决方案:
    (1)查看appium log日志,www.baidu.com重定了到https://m.baidu.com/?from=844b&vit=fps地址
    所以kwpc上页面元素
    (2)m.baidu.com查找元素,m,kw对应的index-kw
    driver.get("http://www.baidu.com");
    Thread.sleep(2000);
    driver.findElement(By.id("index-kw")).sendKeys("tester");
    driver.findElement(By.id("index-bn")).click();
    Thread.sleep(2000);

    2.wda签名失败
    问题:提示Unable to launch WebDriverAgent because of xcodebuild failure: xcodebuild failed with code 65,提示签名失败
    解决方案:打开wda项目,在设置中配置签名证书
    参考简书:https://testerhome.com/topics/8074

    3.个人免费签名证书
    这个链接是在我简书上看到一片关于个人免费签名证书
    https://www.jianshu.com/p/540e722b8eff
    个人证书有效期是7,只能使用3个设备

    4.wda编译失败
    问题:提示'RoutingHTTPServer/RoutingConnection.h' file not found
    解决方案:wda项目跟目录下,下载依赖.输入sh ./Scripts/bootstrap.sh