• 承接一楼,不仅要懂技术,还要懂产品,懂运营
    产品运营的书的话,建议看看《人人都是产品经理》 《运营之光》《增长黑客》等等
    上班地铁上看看还蛮轻松的

  • 看了一下我以前的写法,如下:

    results = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
    for line in results:
    print line

    仅供参考,很久没写了,也不知道现在能不能用了

    里面有些方法,希望能够提供帮助
    https://github.com/NJ-zero/Android-Excel

  • 求助一个诡异的问题 at July 23, 2019

    同步一下解决方案:
    新增了一个字段featurevaluestring ,将 uint64 转 string 后,前端取 featurevaluestring 字段,显示无误

    感谢3楼

  • 使用课上用的方法

    By close = By.id("close")

    如何做到兼容ios和android?

    • 搜索从yaml中读取数据

    Github 地址:https://github.com/NJ-zero/Test_appium_demo

    yaml文件如下:

    input:
    - pdd
    - alibaba
    exp:
    - 拼多多
    - 阿里巴巴

    脚本如下:

    @ParameterizedTest
    @CsvSource({
    "pdd,拼多多","alibaba,阿里巴巴"
    })
    public void search(String key,String name){
    String res = searchPage.search(key).getall().get(0);
    assertThat(res,equalTo(name));
    }

    @ParameterizedTest
    @CsvFileSource(resources="/data/SearchTest.csv")
    public void searchbycsv(String en,String cn){
    System.out.println(en);
    System.out.println(cn);
    String res = searchPage.search(en).getall().get(0);
    }

    @ParameterizedTest
    @MethodSource("Getyaml")
    public void searchbyyaml(String en,String cn){
    System.out.println(en);
    System.out.println(cn);
    String res = searchPage.search(en).getall().get(0);
    assertThat(res,equalTo(cn));

    }

    static Stream<Arguments> Getyaml() {
    Config conf = Config.load("/data/testdata.yaml");
    return Stream.of(arguments(conf.input.get(0),conf.exp.get(0)),
    arguments(conf.input.get(1),conf.exp.get(1)));
    }
  • node版本是个大坑,千万不要

    brew install node

    看作者的建议

    最终版本

    xxxxMacBook-Pro:~ xxo$ node -v
    v8.14.0
    xxxxMacBook-Pro:~ xxo$ npm -v
    6.4.1

    参考MAC下STF安装及踩坑

  • page

    一共三个page: home page search page zixuan page

    • home page

      public class MainPage extends BasePage {
      By profile= By.id("user_profile_icon");
      By search= By.id("home_search");

      public static MainPage start(){
      android_driver.start();
      return new MainPage();
      }

      public ProfilePage getprofile(){
      android_driver.getcurrentdriver().findElement(profile).click();
      return new ProfilePage();
      }

      public SearchPage gotosearch(){
      find(search).click();
      return new SearchPage();
      }

      public ZixuanPage gotozixuan(){
      android_driver.getcurrentdriver().findElement(By.xpath("//*[@text='自选']")).click();
      return new ZixuanPage();
      }
      }
    - searchpage

    ``` java
    public class SearchPage extends BasePage{

    public SearchPage search(String key){
    find(By.className("android.widget.EditText")).sendKeys(key);
    return this;
    }

    public MainPage cancle(){
    android_driver.getcurrentdriver().findElement(By.id("action_close")).click();
    return new MainPage();
    }

    public ArrayList<String> getall(){
    ArrayList<String> array = new ArrayList<String>();
    for(WebElement e:android_driver.getcurrentdriver().findElements(By.id("stockName"))){
    array.add(e.getText());
    }
    return array;
    }

    public ZixuanPage cancletozixuan(){
    /*
    返回自选页
    */

    find(By.id("action_close")).click();
    return new ZixuanPage();

    }

    public SearchPage add(String key){
    find(By.className("android.widget.EditText")).sendKeys(key);
    android_driver.getcurrentdriver().findElements(By.id("follow_btn")).get(0).click();
    return this;
    }
    }
    • zixuanpage
    public class ZixuanPage extends BasePage {

    public SearchPage gotosearch(){
    find(By.id("action_create_cube")).click();
    return new SearchPage();
    }

    public ZixuanPage canceladd(String name){
    TouchAction action = new TouchAction(android_driver.getcurrentdriver());
    String text = String.format("//*[@text='%s']",name);
    WebElement added = android_driver.getcurrentdriver().findElement(By.xpath(text));
    action.longPress(added).release().perform();
    find(By.xpath("//*[@text='删除']")).click();
    return this;
    }

    public ArrayList<String> getall(){
    ArrayList<String> array = new ArrayList<String>();
    for(WebElement e:android_driver.getcurrentdriver().findElements(By.id("portfolio_stockName"))){
    array.add(e.getText());
    }
    return array;
    }

    }

    测试

    • zixuantest
    public class ZixuanTest {

    static MainPage mainPage;
    static SearchPage searchPage;
    static ZixuanPage zixuanpage;

    @BeforeAll
    public static void before(){
    mainPage=MainPage.start();
    zixuanpage=mainPage.gotozixuan();

    }

    @ParameterizedTest
    @CsvSource({"alibaba,阿里巴巴",
    "qtt,趣头条",
    "pdd,拼多多"
    })
    public void add(String stockname,String cn_name) {
    SearchPage searchPage = zixuanpage.gotosearch();
    searchPage.add(stockname);
    zixuanpage = searchPage.cancletozixuan();
    ArrayList<String> stocks=new ArrayList<String>();
    stocks =zixuanpage.getall();
    assertTrue(stocks.contains(cn_name));

    }

    @ParameterizedTest
    @CsvSource({"阿里巴巴",
    "趣头条",
    "拼多多"})
    public void cancel(String name){
    zixuanpage.canceladd(name);
    }
    }
  • 老师,请教:

    1. 如何比较好的做到,用例执行失败的情况下不影响下一个用例的执行
    2. 定位常用的元素是直接写在page文件中,还是维护在其他文件如yaml、txt等
    3. 一套脚本如何比较做到同时适用android和ios
  • 两天了居然没人回答,那我就第一个吧,抛砖引玉。

    检测覆盖率

    用到的第三方插件是 pytest-cov
    Github地址
    安装方法

    pip install pytest-cov

    使用方法:

    pytest   --cov=xxxxx

    最终结果如下: