web自动化框架我已经搭建完了,正在进行测试,之前搭建是基于jenkins+maven+svn,进行的持续集成,这次要在web端搭建三套自动化框架模型:
一、基于selenium的web自动化框架
二、基于Httpclient的接口自动化框架
三、基于appuim的app自动化框架
欢迎有对这些小工具API熟悉或者已经有以上框架开发经验的朋友跟我共同探讨开发,
下面开始介绍本管理系统:
需求:是基于对数据库的增、删、改、查,来完成管理的目的,具体需求这里就不介绍了,这个系统还很简单,基本没什么业务,我把它看成一个单元组件;
准备工作:
分析需求,编写业务逻辑,罗列技术难点,画业务流程图
创建web项目,基于MVC分层原理,创建包:
jsp > 控制层(servlet) >业务层(service)>数据层(dao)
根据业务需要以及流程图倒入所需jar包,我这里给出pom.xml:
jsp主要页面实现:
<%@page import="cn.wyx.pagebean.beans.PageBean"%> <%@page import="cn.wyx.customer.beans.Customer"%> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'list.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <table align="center" border="1" > <tr> <td>uid</td><td>cname</td><td>gender</td><td>birthday</td><td>cellphone</td><td>email</td><td>description</td> </tr> <% PageBean<Customer> pb = (PageBean<Customer>)request.getAttribute("pb"); List<Customer> customers = pb.getBeanList(); for(Customer customer:customers){ out.print("<tr>"); out.print("<td>"+customer.getUid()+"</td>"); out.print("<td>"+customer.getCname()+"</td>"); out.print("<td>"+customer.getGender()+"</td>"); out.print("<td>"+customer.getBirthday()+"</td>"); out.print("<td>"+customer.getCellphone()+"</td>"); out.print("<td>"+customer.getEmail()+"</td>"); out.print("<td>"+customer.getDescription()+"</td>"); out.print("<td><a href='/day_20/CustomerServlet?method=preEdit&uid="+customer.getUid()+"'>修改</a></td>"); out.print("<td><a href='/day_20/CustomerServlet?uid="+customer.getUid()+"&method=deleteByUid'>删除</a></td>"); out.print("</tr>"); } %> </table> <center> 在${pb.pc}页/共${pb.tp}页 <a href="${pb.url }&pc=1">首页</a> <c:if test="${pb.pc>1 }"> <a href="${pb.url }&pc=${pb.pc-1 }">上一页</a> </c:if> <%-- 分页逻辑分析: 首先确定一共多少个页码:百度为例 10个页码 其次确定当前页:pc 百度为例 6 以百度为例确定页码的开始(begin)与结束(end)位置 当点击7页时 begin变为2 end变为11 这样可以计算出begin和end: begin=pc-5; end=pc+4; 如果页面总页数不足10页: begin=1; end=tp; 如果总页数大于10: begin=pc-5; end=pc+4; 但是这里还需要考虑两种情况; 头溢出:即当前页pc小于6; 尾溢出:即当前页大于tp-4; --%> <% int begin,end; if(pb.getTp()<=10){ begin=1;end=pb.getTp(); } else if(pb.getPc()<6){ begin=1; end = 10; }else if(pb.getPc()>pb.getTp()-4){ begin=pb.getTp()-9; end=pb.getTp(); } else{ begin=pb.getPc()-5; end = pb.getPc()+4; } for(int i =begin;i<=end;i++){ if(i==pb.getPc()){out.print("["+i+"]");} else {out.print("<a href='"+pb.getUrl()+"&pc="+i+"'>["+i+"]</a>");} } %> <c:if test="${pb.pc<pb.tp }"> <a href="${pb.url }&pc=${pb.pc+1}">下一页</a> </c:if> <a href="${pb.url }&pc=${pb.tp}">尾页</a> </center> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'query.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <font size="40px" color="#eee">高级搜索</font> <form action="${pageContext.request.contextPath}/CustomerServlet"method="get"> <input type="hidden" name="method" value="query"/> 客户姓名:<input type="text" name="cname" value=""/> 性别:<input type="text" name="gender" value=""/> 电话:<input type="text" name="cellphone" value=""/> 邮箱:<input type="text"name="email" value=""/> <input type="submit" value="搜索"/> </form> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'welcome.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <frameset rows="120,*"> <frame name="top" src="index.jsp"/> <frame name="down" src="msg.jsp"/> </frameset> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <a href="${pageContext.request.contextPath}/CustomerServlet?method=find" target="down">查询客户信息</a> <a href="${pageContext.request.contextPath}/add.jsp" target="down">添加客户</a> <a href="${pageContext.request.contextPath}/query.jsp" target="down">高级搜索</a> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'add.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/CustomerServlet"method="post"> <input type="hidden" name="method" value="add"/> 客户姓名:<input type="text" name="cname" value=""/> 性别:<input type="text" name="gender" value=""/> 生日:<input type="text" name="birthday" value=""/> 电话:<input type="text" name="cellphone" value=""/> 邮箱:<input type="text"name="email" value=""/> 描述:<input type="text" name="description" value=""/> <input type="submit" value="添加客户"/> </form> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'update.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/CustomerServlet"method="post"> <input type="hidden" name="method" value="update"/> <input type="hidden" name="uid" value="${customer.uid}"/> 客户姓名:<input type="text" name="cname" value="${customer.cname}"/> 性别:<input type="text" name="gender" value="${customer.gender}"/> 生日:<input type="text" name="birthday" value="${customer.birthday}"/> 电话:<input type="text" name="cellphone" value="${requestScope.customer.cellphone}"/> 邮箱:<input type="text"name="email" value="${requestScope.customer.email}"/> 描述:<input type="text" name="description" value="${customer.description}"/> <input type="submit" value="保存修改"/> </form> </body> </html>
servlet代码:
package cn.wyx.customer.customerServlet; import java.io.IOException; import java.io.UnsupportedEncodingException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.wyx.baseServlet.BaseServlet; import cn.wyx.beanUtils2.BeanUtils2; import cn.wyx.customer.beans.Customer; import cn.wyx.customer.customerService.CustomerService; import cn.wyx.pagebean.beans.PageBean; public class CustomerServlet extends BaseServlet { private static final long serialVersionUID = 1L; CustomerService service = new CustomerService(); public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @SuppressWarnings("unchecked") Customer form = BeanUtils2.MapToBean(Customer.class, request.getParameterMap()); form.setUid(BeanUtils2.uuid()); service.add(form); request.setAttribute("msg", "客户添加成功!"); request.getRequestDispatcher("/msg.jsp").forward(request, response); } public void find(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int pc = getPc(request); int ps = 10; PageBean<Customer> pb = service.findAll(pc,ps); String url = getUrl(request); pb.setUrl(url); request.setAttribute("pb",pb); request.getRequestDispatcher("/list.jsp").forward(request, response); } public int getPc(HttpServletRequest request){ String pc = request.getParameter("pc"); if(pc==null||pc.trim().isEmpty())return 1; return Integer.parseInt(pc); } public void preEdit(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ String uid = request.getParameter("uid"); Customer customer = service.findByUid(uid); request.setAttribute("customer",customer); request.getRequestDispatcher("/update.jsp").forward(request, response); } public void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @SuppressWarnings("unchecked") Customer customer = BeanUtils2.MapToBean(Customer.class, request.getParameterMap()); service.updateByUid(customer); request.setAttribute("msg","修改成功"); request.getRequestDispatcher("/msg.jsp").forward(request, response); } public void deleteByUid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uid = request.getParameter("uid"); service.deleteByUid(uid); request.setAttribute("msg", "删除成功!"); request.getRequestDispatcher("/msg.jsp").forward(request, response); } @SuppressWarnings("unchecked") public void query(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ //一键表单数据封装 Customer customer = BeanUtils2.MapToBean(Customer.class, request.getParameterMap()); //处理get请求编码问题 Customer cus = enCoding(customer); //获取当前所在页面页码 int pc = getPc(request); //设置每行记录数 int ps = 10; // 调用service方法返回PageBean对象 PageBean<Customer> pb = service.query(cus,pc,ps); //获取url String url = getUrl(request); System.out.println(url); //向PageBean中封装url pb.setUrl(url); //保存PageBean到request域中 request.setAttribute("pb", pb); //转发到list.jsp request.getRequestDispatcher("/list.jsp").forward(request, response); } @SuppressWarnings("null") private Customer enCoding(Customer customer) throws UnsupportedEncodingException { String cname = customer.getCname(); String gender = customer.getGender(); String cellphone = customer.getCellphone(); String email = customer.getEmail(); if(cname!=null||cname.trim().isEmpty()){ cname = new String(cname.getBytes("ISO-8859-1"), "utf-8"); customer.setCname(cname); } if(gender!=null||gender.trim().isEmpty()){ gender = new String(gender.getBytes("ISO-8859-1"), "utf-8"); customer.setGender(gender); } if(cellphone!=null||cellphone.trim().isEmpty()){ cellphone = new String(cellphone.getBytes("iso-8859-1"), "utf-8"); customer.setCellphone(cellphone); } if(email!=null||email.trim().isEmpty()){ email = new String(email.getBytes("iso-8859-1"), "utf-8"); customer.setEmail(email); } return customer; } private String getUrl(HttpServletRequest request) { String contextPath = request.getContextPath(); String servletPath = request.getServletPath(); String paramPath = request.getQueryString(); if(paramPath.contains("&pc=")){ int index = paramPath.lastIndexOf("&pc="); paramPath = paramPath.substring(0, index); } return contextPath+servletPath+"?"+paramPath; } }
dao层代码:
package cn.wyx.customer.customerDao; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.wyx.TxQueryRunner.TxQueryRunner; import cn.wyx.customer.beans.Customer; import cn.wyx.pagebean.beans.PageBean; public class CustomerDao { QueryRunner qRunner = new TxQueryRunner(); public void add(Customer form) { String sql="insert into t_customer values(?,?,?,?,?,?,?)"; Object[]parms = {form.getDescription(),form.getEmail(),form.getCellphone(),form.getBirthday(),form.getGender(),form.getCname(),form.getUid()}; try { qRunner.update(sql,parms); } catch (SQLException e) { throw new RuntimeException(e); } } //向数据库插入数据 // @Test // public void insert(){ // // for (int i = 100,x=0; i < 400; x++,i++) { // if(x>9){x=0;} // Customer customer = new Customer(); // customer.setBirthday("198"+x+"-0"+i); // customer.setCellphone(13944952+""+i); // customer.setCname("cust_"+i); // customer.setDescription("超级用户"); // customer.setGender((i%2==0)?"男":"女"); // customer.setEmail("cust_"+i+"@126.com"); // customer.setUid(BeanUtils2.uuid()); // add(customer); // } // } public PageBean<Customer> findAll(int pc,int ps){ try { PageBean<Customer> pb = new PageBean<Customer>(); pb.setPs(ps); pb.setPc(pc); String trSql ="select count(*) from t_customer"; Number num = (Number)qRunner.query(trSql,new ScalarHandler<Object>()); int tr = num.intValue(); pb.setTr(tr); String BeanListSql="select * from t_customer order by cname limit ?,?"; Object[]params = {(pc-1)*ps,ps};//公式分析:第一页1-1=0 0*任何数都为0 从0行开始显示,显示ps行; List<Customer> BeanList = qRunner.query(BeanListSql,new BeanListHandler<Customer>(Customer.class),params); pb.setBeanList(BeanList); return pb; } catch (SQLException e) { throw new RuntimeException(e); } } public Customer finbByUid(String uid){ String sql="select * from t_customer where uid=?"; try { Customer customer = qRunner.query(sql, new BeanHandler<Customer>(Customer.class), uid); return customer; } catch (SQLException e) { throw new RuntimeException(e); } } public void updateByUid(Customer customer) { String sql="update t_customer set cname=?,gender=?,birthday=?,cellphone=?,email=?,description=? where uid=?"; Object[]params = {customer.getCname(),customer.getGender(),customer.getBirthday(),customer.getCellphone(),customer.getEmail(),customer.getDescription(),customer.getUid()}; try { qRunner.update(sql, params); } catch (SQLException e) { throw new RuntimeException(e); } } public void deleteByUid(String uid) { String sql="delete from t_customer where uid=?"; try { qRunner.update(sql,uid); } catch (SQLException e) { throw new RuntimeException(e); } } public PageBean<Customer> query(Customer customer, int pc, int ps) { try{ //创建PageBean对象,用于封装从数据库中获取的数据,以及客户端传递的数据 PageBean<Customer> pb = new PageBean<Customer>(); //根据条件获取tr总记录数 //为了代码重用,所以对sql语句进行了拼接,让wheresql可以随意进行灵活拼接,只需要进行前后sql语句修改; StringBuilder countsql = new StringBuilder("select count(*) from t_customer"); StringBuilder wheresql = new StringBuilder(" where 1=1 "); //创建list集合 List<Object> params = new ArrayList<Object>(); //从Customer对象中获取各个属性,并进行条件判断,看看是否有值 //如果有值,就添加到wheresql中,并向list集合中添加该属性 //便于调用query方法传递参数 String cname = customer.getCname(); if(cname!=null && !cname.trim().isEmpty()){ wheresql.append(" and cname like ?"); params.add("%"+cname+"%"); } String gender = customer.getGender(); if(gender!=null && !gender.trim().isEmpty()){ wheresql.append(" and gender like ?"); params.add("%"+gender+"%"); } String cellphone = customer.getCellphone(); if(cellphone!=null && !cellphone.trim().isEmpty()){ wheresql.append(" and cellphone like ?"); params.add("%"+cellphone+"%"); } String email = customer.getEmail(); if(email!=null && !email.trim().isEmpty()){ wheresql.append(" and email like ?"); params.add("%"+email+"%"); } //ScalarHandler接口返回的是Object,最好用Number接受,因为不知道返回的具体类型; Number num = (Number)qRunner.query(countsql.append(wheresql).toString(), new ScalarHandler<Object>(), params.toArray()); int tr = num.intValue(); //获取List<Customer>customers即每页数据 StringBuilder customersql= new StringBuilder("select * from t_customer"); StringBuilder limitsql = new StringBuilder(" limit ?,?"); params.add((pc-1)*ps); params.add(ps); List<Customer> beanList = qRunner.query(customersql.append(wheresql).append(limitsql).toString(), new BeanListHandler<Customer>(Customer.class), params.toArray()); //添加数据到PageBean中封装带回给servlet pb.setBeanList(beanList); pb.setPc(pc); pb.setPs(ps); pb.setTr(tr); return pb; }catch(SQLException e){ throw new RuntimeException(e); } } }
package cn.wyx.customer.beans; public class Customer { private String uid; private String cname; private String gender; private String birthday; private String cellphone; private String email; private String description; @Override public String toString() { return "Customer [uid=" + uid + ", cname=" + cname + ", gender=" + gender + ", birthday=" + birthday + ", cellphone=" + cellphone + ", email=" + email + ", description=" + description + "]"; } public Customer() { super(); } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getCellphone() { return cellphone; } public void setCellphone(String cellphone) { this.cellphone = cellphone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
package cn.wyx.pagebean.beans; import java.util.List; /** * 分析: * 页面需要显示的数据都有哪些,当前页、总页数、当前页数据; * 当前页pc通过页面传递给servlet; * 总页数,需要总记录数tr/每页记录数ps * 当前页数据,需要知道limit(当前页-1)*每页记录数,每页记录数; * String url:要把从request中得到的url,封装到PageBean带回给页面,从而在页面读取并添加参数; * */ public class PageBean<T> { private int pc;//当前页 private int ps;//每页记录数 page size private int tr;//总记录数 //private int tp;//总页数,总页数=总记录除以每页记录数 private List<T> BeanList; private String url; public void setUrl(String url){ this.url=url; } public String getUrl(){ return this.url; } public int getPc() { return pc; } public void setPc(int pc) { this.pc = pc; } public int getPs() { return ps; } public void setPs(int ps) { this.ps = ps; } public int getTr() { return tr; } public void setTr(int tr) { this.tr = tr; } public int getTp() { int tp=tr/ps; return tr/ps!=0 ? tp+1:tp; } // public void setTp(int tp) { // this.tp = tp; // }不允许被设置,因为这个是计算出来的,不然会跟每页记录数冲突; public List<T> getBeanList() { return BeanList; } public void setBeanList(List<T> beanList) { BeanList = beanList; } }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <c3p0-config> 3 <default-config> 4 <property name="driverClass">com.mysql.jdbc.Driver</property> 5 <property name="jdbcUrl">jdbc:mysql://192.168.0.2:3306/customer</property> 6 <property name="user">root</property> 7 <property name="password">123</property> 8 9 <property name="initialPoolSize">10</property> 10 <property name="maxIdleTime">30</property> 11 <property name="maxPoolSize">20</property> 12 <property name="minPoolSize">5</property> 13 <property name="maxStatements">200</property> 14 </default-config> 15 16 <named-config name="mysql"> 17 <property name="acquireIncrement">50</property> 18 <property name="initialPoolSize">100</property> 19 <property name="minPoolSize">50</property> 20 <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching --> 21 <property name="maxStatements">0</property> 22 <property name="maxStatementsPerConnection">5</property> 23 </named-config> 24 25 <named-config name="oracle"> 26 <property name="acquireIncrement">50</property> 27 <property name="initialPoolSize">100</property> 28 <property name="minPoolSize">50</property> 29 <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching --> 30 <property name="maxStatements">0</property> 31 <property name="maxStatementsPerConnection">5</property> 32 </named-config> 33 </c3p0-config>
当然这个项目还有很多相关自写的支持类,cn.wyx.....包下的都是我的jar,由于比较复杂所以就不贴出来了,可以根据我的类名进行百度,一般都可查;