• 谈下2019年的当前测试行情怎么样?

  • 如果一个公司有web, APP(Android 和IOS)的产品都需要测试, 使用的框架是selenium \ Appium .一般是将APP和Web的UI自动化写到同一个项目中好,还是分开写2个项目,一个是APP的项目,一个是Web的?

  • 作业: 使用的Junit5框架
    用例类:

    public class AuthorityTest {

    static WebDriver driver;

    @BeforeAll
    public static void before(){
    Driver.start();
    driver=Driver.getCurrentDriver();
    }

    @Test
    public void test(){
    String source=null;
    driver.get("https://testerhome.com/");
    MainPage mainPage=new MainPage();
    source= mainPage.gotoCorporationPage().gotoHogwartsPage().TopicNotAccess();
    assertThat(source.contains("访问被拒绝,你可能没有权限或未登录"), equalTo(true));
    }

    @AfterAll
    public static void after(){
    driver.close();
    driver.quit();
    }
    }

    PO页面类--基础类

    /**
    * 基础导航类-所有PO页面类的父类
    */

    public class NavBarPage {

    public void click(By by) {
    Driver.find(by).click();
    }

    public void sendkeys(By by, String key) {
    Driver.find(by).sendKeys(key);
    }

    public void clear(By by) {
    Driver.find(by).clear();
    }

    public void actionSendENTER() {
    Actions action = new Actions(Driver.getCurrentDriver());
    action.sendKeys(Keys.ENTER).perform();
    }

    }

    /**
    * 主页面
    */

    public class MainPage extends NavBarPage {
    By searchBy = By.cssSelector(".form-group > input");
    By corporation = By.cssSelector("#main-nav-menu a[href$='teams']");


    public SearchResultPage gotoSearchResultPage(String keyword) {

    clear(searchBy);
    sendkeys(searchBy, keyword);
    actionSendENTER();
    return new SearchResultPage();
    }


    public CorporationPage gotoCorporationPage() {
    click(corporation);
    return new CorporationPage();
    }
    }
    /**
    * 霍格测试学院页面
    */

    public class HogwartsPage extends NavBarPage {
    By firstTopic = By.cssSelector(".media-heading > a[title$='定向班第一期_Selenium 入门实战_20190217']");
    By userName = By.cssSelector("#user_login");

    public String TopicNotAccess() {
    click(firstTopic);
    WebDriverWait wait = new WebDriverWait(Driver.getCurrentDriver(), 5);
    wait.until(ExpectedConditions.presenceOfElementLocated(userName));
    return Driver.getCurrentDriver().getPageSource();
    }
    }
    /**
    * 社团页面
    */



    public class CorporationPage extends NavBarPage {
    By hogwarts = By.cssSelector(".media-heading > a[href$='hogwarts']");

    public HogwartsPage gotoHogwartsPage() {
    click(hogwarts);
    return new HogwartsPage();
    }

    }

    public class Driver {

    public static WebDriver driver;


    public static void start() {
    System.setProperty("webdriver.chrome.driver", "/Users/888/Documents/chromedriver");
    driver = new ChromeDriver();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    }

    public static WebElement find(By by) {
    WebElement element = null;
    try {
    element = driver.findElement(by);
    } catch (Exception e) {
    //todo: getPageSource +xpath
    //弹框处理
    element = driver.findElement(by);
    }
    return element;
    }

    public static WebDriver getCurrentDriver() {
    return driver;
    }

    }
  • 直接sendKeys被输入法拦截 是什么意思?什么情况下会拦截?

  • 补交作业:
    github: https://github.com/chunrong50/training

    SelfChooseTest

    mport driver.Driver;
    import org.junit.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.CsvSource;
    import page.MainPage;
    import page.SelfChoosePage;

    import java.util.ArrayList;

    import static org.hamcrest.CoreMatchers.equalTo;
    import static org.hamcrest.MatcherAssert.assertThat;

    public class SelfChooseTest {
    static MainPage mainPage;
    static SelfChoosePage selfChoosePage;


    @BeforeAll
    static void before() {
    Driver.start();
    mainPage = new MainPage();
    }

    /**
    * 自选主页中搜索股票,然后加自选,判断自选是否成功
    *
    * @param stock
    * @param expection
    */


    @ParameterizedTest
    @CsvSource({"alibaba,阿里巴巴"
    })
    public void addChoiceTest(String stock, String expection) {
    selfChoosePage = mainPage.gotoSelfChoicePage();
    selfChoosePage.addStock(stock);
    ArrayList<String> arrayList = selfChoosePage.getAllStockName();
    assertThat(arrayList.get(0), equalTo(expection));
    }


    @AfterAll
    static void after() {
    selfChoosePage.gotoSearchPage().searchKey("alibaba").rmSelected();
    }
    }

    SelfChoosePage

    package page;

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;

    import java.util.ArrayList;

    /**
    * Created by jfpay on 19/1/15.
    */

    public class SelfChoosePage extends BasePage {
    private By search = By.id("action_create_cube");
    private By stock = By.id("portfolio_stockName");


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


    public StockDetailPage gotoDetailPage(String stockName) {
    find(By.xpath("//*[@text='" + stockName + "' and @id='portfolio_stockName']"));
    return new StockDetailPage();
    }


    /**
    * 通过搜索功能添加自选
    *
    * @param stock
    * @return
    */


    public SelfChoosePage addStock(String stock) {
    SearchPage searchPage = gotoSearchPage().searchKey(stock);
    searchPage.addSelected();
    searchPage.gotoMainPage().gotoSelfChoicePage();
    return this;

    }


    /**
    * 在自选->股票的详情页删除股票
    *
    * @param stock
    * @return
    */

    public SelfChoosePage rmStock(String stock) {
    ArrayList<String> arrayList = getAllStockName();
    for (String text : arrayList)
    if (stock.equals(text)) {
    find(By.xpath("//*[@text," + text + "]")).click();
    break;
    }


    return this;
    }

    /**
    * @return 所有自选股票的名称
    */


    public ArrayList<String> getAllStockName() {
    ArrayList<String> arrayList = new ArrayList<String>();
    wait(6);
    for (WebElement e : finds(stock))
    arrayList.add(e.getText());
    return arrayList;
    }


    }

    SearchPage

    package page;

    import driver.Driver;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;

    import java.util.*;

    /**
    * Created by jfpay on 19/1/15.
    * 搜索页面
    */

    public class SearchPage extends BasePage {
    private By searchInput = By.id("search_input_text");
    private By allstockName = By.id("stockName");
    private By select = By.xpath("//*[contains(@resource-id,'follow') and contains(@resource-id,'_btn')]");
    private By cancle = By.xpath("//*[contains(@resource-id,'action_close') and contains(@text,'取消')]");

    public SearchPage searchKey(String keyWord) {
    find(searchInput).sendKeys(keyWord);

    return this;

    }

    /**
    * 获取搜索列表的文本内容
    *
    * @return
    */



    public ArrayList<String> getAll() {
    ArrayList<String> listName = new ArrayList<String>();

    for (WebElement e : finds(allstockName)) {
    listName.add(e.getText());
    }
    return listName;
    }

    public SearchPage getBystock() {
    return this;
    }

    /**
    * 获取搜索结果加自选/删自选
    *
    * @return 自选处的resource-id的属性值
    */

    public String addSelected() {

    WebElement e = null;
    e = finds(select).get(0);

    e.click();
    if (!e.isDisplayed()) {
    find(select);
    }
    return e.getAttribute("resourceId");

    }

    public String rmSelected() {
    WebElement e = null;
    String attribute = null;
    e = finds(select).get(0);
    attribute = e.getAttribute("resourceId");
    if (attribute.contains("followed_btn")) {
    e.click();
    }
    return attribute;
    }


    public MainPage gotoMainPage() {
    find(cancle).click();
    return new MainPage();
    }


    }

    BasePage

    package page;

    import driver.Driver;
    import io.appium.java_client.android.AndroidElement;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.ui.ExpectedConditions;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;

    public class BasePage {
    By next = By.id("md_buttonDefaultNegative");
    By comment = By.id("md_buttonDefaultPositive");

    /**
    * 元素定位方法
    *
    * @param locator
    * @return
    */

    public static WebElement find(By locator) {
    ArrayList<String> other = new ArrayList<String>();
    other.add("md_buttonDefaultNegative"); //弹框--下次再说的id
    WebElement element;

    try {

    element = Driver.getCurrentDriver().findElement(locator);
    } catch (Exception e) {
    System.out.println("not found,entry catch");
    // e.printStackTrace();
    //更好的根据弹框列表进行批量检索
    for (String s : other) {
    if (Driver.getCurrentDriver().getPageSource().contains(s))
    Driver.getCurrentDriver().findElement(By.id(s)).click();
    }
    element = Driver.getCurrentDriver().findElement(locator);
    }
    return element;
    }


    public static List<AndroidElement> finds(By locator) {
    ArrayList<String> other = new ArrayList<String>();
    other.add("md_buttonDefaultNegative"); //弹框--下次再说的id
    List<AndroidElement> elements = new ArrayList<AndroidElement>();

    try {
    elements = Driver.getCurrentDriver().findElements(locator);
    } catch (Exception e) {
    System.out.println("not found");
    e.printStackTrace();
    //更好的根据弹框列表进行批量检索
    for (String s : other) {
    if (Driver.getCurrentDriver().getPageSource().contains(s))
    Driver.getCurrentDriver().findElement(By.id(s)).click();
    }
    elements = Driver.getCurrentDriver().findElements(locator);
    }
    return elements;
    }


    /**
    * 隐试等待,单位秒
    *
    * @param i
    */

    public static void wait(int i) {
    Driver.getCurrentDriver().manage().timeouts().implicitlyWait(i, TimeUnit.SECONDS);

    }
    }

  • 我换成模拟器就没问题了.可能手机问题

  • 老师.遇到了2个问题,麻烦您解答下.

    1. uiautomatorviewer 打开报错如下: 这个什么原因造成的. 2 .现在Appium-desktop 也无法开启,报错如下:

    [AndroidDriver] Performed fast reset on the installed 'com.xueqiu.android' application (stop and clear)
    [AndroidBootstrap] Watching for bootstrap disconnect
    [ADB] Forwarding system: 4724 to device: 4724
    [ADB] Running '/Users/jfpay/Downloads/android-sdk-macosx/platform-tools/adb -P 5037 -s TGPZHAHILNZ56T7P forward tcp:4724 tcp:4724'
    [UiAutomator] Starting UiAutomator
    [UiAutomator] Moving to state 'starting'
    [UiAutomator] Parsing uiautomator jar
    [UiAutomator] Found jar name: 'AppiumBootstrap.jar'
    [ADB] Running '/Users/jfpay/Downloads/android-sdk-macosx/platform-tools/adb -P 5037 -s TGPZHAHILNZ56T7P push /Applications/Appium.app/Contents/Resources/app/node_modules/appium-android-driver/bootstrap/bin/AppiumBootstrap.jar /data/local/tmp/'
    [ADB] Attempting to kill all uiautomator processes
    [ADB] Getting all processes with uiautomator
    [ADB] Running '/Users/jfpay/Downloads/android-sdk-macosx/platform-tools/adb -P 5037 -s TGPZHAHILNZ56T7P shell ps'
    [ADB] No 'uiautomator' process has been found
    [UiAutomator] Starting UIAutomator
    [ADB] Creating ADB subprocess with args: ["-P",5037,"-s","TGPZHAHILNZ56T7P","shell","uiautomator","runtest","AppiumBootstrap.jar","-c","io.appium.android.bootstrap.Bootstrap","-e","pkg","com.xueqiu.android","-e","disableAndroidWatchers",false,"-e","acceptSslCerts",false]
    [UiAutomator] UiAutomator exited unexpectedly with code 0, signal null
    [UiAutomator] Moving to state 'stopped'

  • 第一个回复数的点赞数
    curl -s https://testerhome.com/topics/17292 2>/dev/null | grep -m1 "Reply" | grep -o "data-count=\"[0-9]*\"" | awk -F '\"' '{print $2}'

  • 作业:

    数据驱动部分
    public class BuysParams {
    /**
    * 用户购买信息参数
    * @return
    */

    @DataProvider
    public Object[][] getUserProducts(){
    return new Object[][]{
    {1,0,-2}, // 用户未登录
    {1,0,-1}, //用户购买数量是否大于0
    {2,2,1}, //购买成功
    {2,9,0}, //库存不足
    {3,2,0} //库存不足
    };
    }
    }

    测试case
    public class BuysTest {
    Login login=new Login();
    Shopping shoping=new Shopping();
    @BeforeClass
    public void beforeMethod(){
    login.userLogin("zhangsan","123456");
    login.isLogin=true;
    }

    @Test(dataProvider = "getUserProducts" ,dataProviderClass = BuysParams.class)
    public void TestBuys(int id,int num,int expected){
    if(expected==-2)
    login.isLogin=false;
    else
    login.isLogin=true;
    int act= shoping.buys(id,num);
    Assert.assertEquals(act,expected);
    }
    @AfterClass
    public void afterMethod(){
    login.userLogin("","");
    }
    }

  • 你好,请教下这个多维度的图形化HTML怎么在Jenkins上展示,我这边展示时样式、图标都无法加载。 但是本地生成的index.html 可以直接浏览器打开。也尝试过System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "") ,这个设置, 仍无效。 但是我的其他项目的hmtl文件可以在jenkins上展示。 这个问题怎么处理,麻烦您看下,非常感谢