功能说明

  1. 通过接口调用运行自动化测试,并且持久化保存测试数据和抓取的数据,数据库使用了 mongdb,技术使用了 mybatis
  2. 使用模拟器为测试终端,并且支持多开,数据库记录模拟器运行状态,每次跑完后把状态置为空闲,
  3. 使用了 spring boot 的定时任务,间隔性扫描端口和数据库,更新模拟器状态和重启已经死掉的模拟量

项目结构

controller 入口

@RestController
public class WechatSpider  extends  BaseSpider {

    @Override
    protected void execute() {
        super.execute();
    }

    @Override
    protected String onPackageName() {
        return "com.tencent.mm";
    }

    @RequestMapping(value = "/splder",method = RequestMethod.GET)
    public void addWechat(){
        System.out.println("start");
        super.execute();
    }

    @Override
    protected String onActivityName() {
        return "com.tencent.mm.ui.LauncherUI";
    }
    @Override
    protected void onStart(AndroidDriver<AndroidElement> androidDriver) {
        ThreadUtil.sleep(10);
        System.out.println("appium start");

        //获取加号按钮点击
        AndroidElement moreButton = ElementUtil.findElementById(androidDriver, "com.tencent.mm:id/g1");
        if (moreButton == null) {
            return ;
        }
        moreButton.click();

        //获取添加朋友按钮点击
        List<AndroidElement> moreListView = ElementUtil.findElementsById(androidDriver, "com.tencent.mm:id/g2");
        if (moreListView.isEmpty() && moreListView.size() <= 1) {
            return ;
        }
        AndroidElement addFriendButton = moreListView.get(1);
        addFriendButton.click();

        //获取输入框点击
        AndroidElement searchButton = ElementUtil.findElementById(androidDriver, "com.tencent.mm:id/hk");
        if (searchButton == null) {
            return ;
        }
        searchButton.click();

        //获取输入框输入文本
        AndroidElement searchTextView = ElementUtil.findElementById(androidDriver, "com.tencent.mm:id/hk");
        if (searchTextView == null) {
            return ;
        }
        searchTextView.sendKeys("18211111111");

        //获取输入后的搜索按钮
        AndroidElement searchStartButton = ElementUtil.findElementById(androidDriver, "com.tencent.mm:id/ke");
        searchStartButton.click();
    }
}

核心工具类
先获取数据库可以模拟器设备列表,并通过 node 去启动 appium

public abstract class BaseSpider {

    final Logger mLogger = LoggerFactory.getLogger(getClass());

    @Autowired
    protected AndroidDeviceService mAndroidDeviceService;
    @Autowired
    protected AppiumService mAppiumService;
    @Autowired
    protected LoginInfoService mLoginInfoService;



    protected void execute() {

        LoginInfo loginInfo = mLoginInfoService.findNotCrawl(onPackageName());
        if (loginInfo == null) {
            return;
        }
        mLogger.info("prepare to processing : {}", getClass().getSimpleName());
        AndroidDevice androidDevice = mAndroidDeviceService.findAvailable(onPackageName(), onSeconds());
        if (androidDevice == null) {
            mLogger.info("current time do not have available Android Device");
            return;
        }

        if (StringUtils.isEmpty(onPackageName())) {
            return;
        }
        AppiumDriverLocalService appiumServer = mAppiumService.startAppiumServer();
        if (appiumServer == null) {
            mLogger.info("Appium initial failure");
            return;
        }
        AndroidDriver<AndroidElement> androidDriver;
        try {
            androidDriver = WebDriverUtil.getAndroidDriver(appiumServer.getUrl().toString(),androidDevice.deviceId, "com.tencent.mm", onActivityName());
        } catch (Exception e) {
            mLogger.error("can not create Android driver. session is created");
            return;
        }

        try {
            onStart(androidDriver);
        } catch (Exception e) {

            mLogger.error("error target : {}", e);
            mLogger.error("start error", e);
        }
        try {
//            onDestroy(androidDriver, appiumServer, androidDevice);
        } catch (Exception e) {
            mLogger.error("destroy error", e);
        }

        mLogger.info("process over : {}", getClass().getSimpleName());

    }

先备注明天继续写


↙↙↙阅读原文可查看相关链接,并与作者交流