|
4#
楼主 |
发表于 2017-5-15 09:17:55
|
只看该作者
本帖最后由 307641452 于 2017-5-16 22:20 编辑
功能已经都实现了,今晚把视线的方式发上来,大家有兴趣的可以讨论下。前台的功能就不用细说了,无非是把组的id或者用例id传到后台,保存到数据库,如果是组id,那么就在任务表里面生成一条新记录,如果是用例,就把用例全都写到用例的临时表里面。
1.后台会有一个随着tomcat一起启动的监听器,只要实现ServletContextListener这个接口,然后在web.xml中配置一下listener即可;这个网上有很多资料,一查就会了。
这个监听器的作用很简单,就是启动后台扫描数据库任务表、临时用例表的一个进程(只写出关键部分):
- public void contextDestroyed(ServletContextEvent arg0) {
-
- if (taskThread != null && taskThread.isInterrupted()) {
- taskThread.interrupt();
- }
复制代码
2.后台扫描进程启动之后,会优先扫描任务表来执行组的任务,这里有个小功能,就是有些任务还没执行就被用户删掉了,所以说扫描到了任务之后会先判断是否被删除了,如果是就物理删除,如果不是就执行这个组里面的所有关联用例;
如果没扫描到组任务,就会去扫描临时用例表,扫描到了就执行。
如果都没有扫描到,那么睡眠3s再次扫描,关键代码如下:
- while (!this.isInterrupted()) {// 线程未中断执行轮询
-
- //获取执行列表中最早的一个
- List<AtpTask> temptasklist=new ArrayList<AtpTask>();
- List<CaseTemp> tempcaselist =new ArrayList<CaseTemp>();
- temptasklist=atdao.findTaskBystatus(CommonUtils.newtask);
-
- if(temptasklist.size()==0){//没有要运行的组,则扫描是否有要运行的用例:
-
- tempcaselist= tcdao.findByStatus(CommonUtils.newtempcase);
- if(tempcaselist.size()>0){
- //将所有新的临时用例设置成运行状态。
- for(int i=0;i<tempcaselist.size();i++){
- tcdao.setStatusById(tempcaselist.get(i).getIdtempcase(), CommonUtils.runningcase);
-
- }
- //运行用例
- test.RunCase();
- //运行完成后删掉所有跑完的用例
- tcdao.deleteByStatus(CommonUtils.runningcase);
-
- }else{
- // System.out.println("轮询任务线程未扫描到任何需要运行的套件和用例,5s后再次扫描.......");
- }
- }else if(temptasklist.size()==1){
-
- AtpTask atptask=new AtpTask();
- atptask=temptasklist.get(0);
- System.out.println("获得的对象为:"+atptask.toString());
- if(atptask.getDeleteflag()==1){//如果删除状态为1,就删掉他。
- System.out.println("进入删除task分支");
- //删除这条task—
- atdao.delete("idtask", atptask.getIdtask());
-
- }else{//运行这个task
-
- //根据获取的任务,拿到idsuit,然后查询到对应suit
- int idsuit=atptask.getIdsuit();
- Suit suit=new Suit();
- suit=sdao.findById("idsuit", idsuit);
-
- //根据该suit,获取到testng需要并发的数量
- int threadcount=1;//获取可执行状态后,将其置为false并跳出循环执行测试。
-
- //设置这个task的状态为1执行
- atdao.setStatusById(atptask.getIdtask(), CommonUtils.runningtask);
- threadcount=suit.getThreadcount()==0?1:suit.getThreadcount();
- //设置完状态后开始执行这个任务,
- System.out.println("获得的线程并发数为:"+threadcount);
- test.RunSuit(threadcount,atptask.getPath());//并发数为参数。
-
- //3.单次执行完成后把对应task置为完成状态。
- atdao.setStatusById(atptask.getIdtask(), CommonUtils.finishedtask);
- }
- }
- //所有任务都没有获取到,则等待2s再次扫描
- try{
- Thread.sleep(5000); //每隔3000ms执行一次
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
复制代码 3.运行testng就比较简单了,为了让朋友们看的明白些,我加了几行注释,大家看看代码就懂了:
- //执行组
- public void RunSuit(int threadcount,String midpath){
- PropUtil PropUtil = new PropUtil("FrameWork.properties");
- String reportdir=PropUtil.get("ReportDir");
- //设置运行的输出目录,每次运行目录均单独保存。
- SingleTestng.getTestNG().setOutputDirectory(reportdir+"\\"+midpath);
- //设置并发数量,参数由前段传入
- SingleTestng.getTestNG().setDataProviderThreadCount(threadcount);
- //设置要运行的类
- SingleTestng.getTestNG().setTestClasses(new Class[]{SuitTestControler.class});
- SingleTestng.getTestNG().run();
-
- }
- //执行多个用例
- public void RunCase(){
-
- PropUtil PropUtil = new PropUtil("FrameWork.properties");
- String defaultdir=PropUtil.get("ReportDir");
- SingleTestng.getTestNG().setOutputDirectory(defaultdir+"//"+"defaut-out");
-
- SingleTestng.getTestNG().setTestClasses(new Class[]{CaseTestControler.class});
- SingleTestng.getTestNG().run();
-
-
- }
复制代码 4.至于测试的类,了解selenium的人应该都能想到,就是把excel文件的关键字和参数读取到,然后利用反射机制去执行封装好的方法,代码较多就不全贴了:
- try {
- this.InitElementMap(filename);
- int actionnum=eu.getLastRowNum(eu.ActionSheet);
- for(int i=2;i<=actionnum;i++)
- {
-
- if(eu.getCellData(eu.ActionSheet, i, 0).equals("eleAction"))
- {
- System.out.println("进入行"+i+":eleAction");
- this.element=this.findelement(this.getLocator(eu.getCellData(eu.ActionSheet, i, 1)));
-
- method=EleAction.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2), WebElement.class,String.class);
- method.invoke(eleaction,this.element,eu.getCellData(eu.ActionSheet, i, 3));
- }
- else if(eu.getCellData(eu.ActionSheet, i, 0).equals("winAction"))
- {
- System.out.println("进入行"+i+":winAction");
- method=WinAction.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2), String.class);
- System.out.println(method.getName());
- method.invoke(winaction,eu.getCellData(eu.ActionSheet, i, 3));
- }
- else if(eu.getCellData(eu.ActionSheet, i, 0).equals("eleWait"))
- {
- System.out.println("进入行"+i+":eleWait");
- this.element=this.findelement(this.getLocator(eu.getCellData(eu.ActionSheet, i, 1)));
-
- method=EleWait.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2), WebElement.class,String.class);
- method.invoke(elewait,this.element,eu.getCellData(eu.ActionSheet, i, 3));
- }
- else if(eu.getCellData(eu.ActionSheet, i, 0).equals("winWait"))
- {
- System.out.println("进入行"+i+":winWait");
- method=WinWait.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2), String.class);
- method.invoke(winwait,eu.getCellData(eu.ActionSheet, i, 3));
- }
- else if(eu.getCellData(eu.ActionSheet, i, 0).equals("eleAssert"))
- {
- System.out.println("进入行"+i+":eleAssert");
- this.element=this.findelement(this.getLocator(eu.getCellData(eu.ActionSheet, i, 1)));
-
- method=EleAssert.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2),WebElement.class, String.class);
- method.invoke(eleassert,this.element,eu.getCellData(eu.ActionSheet, i, 3));
- }
- else if(eu.getCellData(eu.ActionSheet, i, 0).equals("winAssert"))
- {
- System.out.println("进入行"+i+":winAssert");
- method=WinAssert.class.getMethod(eu.getCellData(eu.ActionSheet, i, 2), String.class);
- method.invoke(winassert,eu.getCellData(eu.ActionSheet, i, 3));
- }else {
- System.out.println("第"+i+"行的数据有误,请检查主类名称是否正确!!!!!!!!!");
- Assert.assertTrue(false, "运行失败了:"+"第"+i+"行的数据有误,请检查主类名称是否正确!!!!!!!!!");
- logger.debug("第"+i+"行的数据有误,请检查主类名称是否正确!!!!!!!!!");
- }
- }
- } catch (Exception e) {
- ispass=false;
- Assert.assertTrue(false, "运行失败了:"+e.toString());
- e.printStackTrace();
- }finally{
- String ends = DateTimeUtil.formatedTime("yyyy-MM-dd HH:mm:ss:SSS");
- if (this.ispass) {
- logger.info("案例 【" + casename + "】 运行通过!");
- } else {
- String dateTime = DateTimeUtil.formatedTime("yyyy-MMdd-HHmmssSSS");
- StringBuffer sb = new StringBuffer();
- String captureName = sb.append(capturePath)
- .append(casename).append(dateTime).append(".png")
- .toString();
-
- captureScreenshot(captureName);
- logger.error("案例 【" + casename
- + "】 运行失败,请查看截图快照:" + captureName);
-
- }
- logger.info("======" + ends + ":案例【" + casename
- + "】结束======");
- afterTestStops = System.currentTimeMillis();
- logger.info("======本次案例运行消耗时间 " + (double)(afterTestStops - beforeTestStarts)
- / 1000 + " 秒!======");
- this.driver.quit();
- }
-
-
复制代码 上面的代码是运行每个用例都用到的反射代码,大致思路就是这样了,因为我是半路出家,去年才自学的java,代码写的很是没有艺术,朋友们见谅哈~
最近准备着手写一个跟这个平台类似的http接口测试平台,当然接口就简单的多了,只是没学过界面,写前端比较痛苦,相信一个月内可以搞定。
等到接口平台也写完了,就去看看jmeter的源码,如果看的懂,就改造改造也搞成bs模式的,以后测试人员只要录了脚本上传上去,开发就可以随便运行查看结果,省的我们测试人员老是被他们叫去跑脚本。
|
|