可测试性战术
可测试性战术的目标是允许在完成软件开发的一个增量后,轻松地对软件进行测试
定义
软件可测试性是指通过测试(通常是基于运行的测试)揭示软件缺陷的容易程度。在开发设计良好的系统的成本中,至少有40%是用在了测试上。如果软件设计师能够降低此成本,则将会收到巨大的回报。
要想对系统进行正确的测试,必须能够“控制”每个组件的内部状态及其输入,然后“观察”其输出。这通常通过使用“测试工具”进行,这是一种专门设计的软件,用于执行所测试的软件。这可能会如同在各种接口上回放已记录的数据一样简单,也可能会像测试发动机的燃烧室一样复杂。
可测试性战术
可测试性战术的目标是允许在完成软件开发的一个增量后,较轻松地对软件进行测试。
我们对两类用于测试的战术进行讨论:提供输入并捕获输出;内部监视。
输入/输出
有3种用于管理测试的输入和输出的战术。
-
记录/回放
记录/回放是指捕获跨接口的信息,并将其作为测试专用软件的输入。在正常操作中跨一个接口的信息保存在某个存储库中,它代表来自一个组件的输出和传到一个组件的输入。记录该信息使得能够生成对其中一个组件的测试输入,并保存用于以后的比较的测试输出。
例如在值传递时,将这些值记录下来,我这里只是输出,我们可以将它记录在文件中,或数据库等,可以在接收方在定义一个接收后变量的存储,以此达到记录/回放。
private void find1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
List<Data> list2=dao1.list1();
Gson gson2 = new Gson();
String json = gson2.toJson(list2);
System.out.println(json);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(json);
}
-
将接口与实现分离
将接口与实现分离允许实现的代替,以支持各种测试目的。点位实现允许在缺少被占位的组件时,对系统的剩余部分进行测试。用一个组件代替某个专门的组件能够使被代替的组件充当系统剩余部分的测试工具。
我理解为定义接口实现功能,实现接口与实现的隔离,可以通过某一部分的更替,来测试其他部分是否有问题。
其次功能分块也要明确
功能分块明确有利于在测试时进行每一块的测试,易于确认错误位置,如果分块不明确,我们就很难确认到底是那一块出错,因为一个程序比较复杂时,都是一点点拼出来的,自己都有时候很难搞清楚,更别提别人给你测试了,分块明确也有利于后期的修改等,好处很多。
代码:
dao层
package Dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import Data.Data; public class dao { public List<Data> list1(){ List<Data> list =new ArrayList<Data>(); try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/runoob?useSSL=false"; String username = "root"; String password = "12345678"; Connection conn = DriverManager.getConnection(url, username, password); String sql = "select * from tu"; Statement statement = conn.createStatement(); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) { Data book = new Data(); book.setHotwords(resultSet.getString("热词")); book.setNum(resultSet.getString("次数")); list.add(book); } resultSet.close(); statement.close(); conn.close(); }catch (Exception e) { e.printStackTrace(); } return list; } public List<Data> list2(){ List<Data> list =new ArrayList<Data>(); try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/runoob?useSSL=false"; String username = "root"; String password = "12345678"; Connection conn = DriverManager.getConnection(url, username, password); String sql = "select * from lianjie"; Statement statement = conn.createStatement(); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) { Data book = new Data(); book.setHotwords(resultSet.getString("热词")); book.setExplain(resultSet.getString("解释")); book.setWebsite(resultSet.getString("网址")); list.add(book); } resultSet.close(); statement.close(); conn.close(); }catch (Exception e) { e.printStackTrace(); } return list; } }
package Data; public class Data{
private String hotwords;
private String num;
private String explain;
private String website;
public String getExplain() {
return explain;
}
public void setExplain(String explain) {
this.explain = explain;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getHotwords() {
return hotwords;
}
public void setHotwords(String hotwords) {
this.hotwords = hotwords;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
servlet层
package Servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.gson.Gson; import Dao.dao; import Data.Data; @WebServlet("/servlet") public class servlet extends HttpServlet { private static final long serialVersionUID = 1L; dao dao1=new dao(); protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String method=request.getParameter("method"); if("1".equals(method)) { find1(request, response); }else if("2".equals(method)) { find2(request, response); } } private void find1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); List<Data> list2=dao1.list1(); Gson gson2 = new Gson(); String json = gson2.toJson(list2); System.out.println(json); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(json); } private void find2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); request.setAttribute("list",dao1.list2()); request.getRequestDispatcher("biao.jsp").forward(request, response); } }
特化访问路线/接口
具有特化的测试接口允许通过测试工具并独立于其正常操作,来捕获或指定组件的变量值。例如,可以通过特化的接口提供元数据,测试工具利用该接口推动其活动。应该将特化的访问路线和接口与针对所要求功能的访问路线和接口分离开。使构架中的测试接口分层意味着可以在架构的任何层次上应用测试用例,并且已经具备观察响应的测试功能。
如data层
但是是在整个系统中定义一个测试接口,可以获取到指定组件的变量值,如get函数。
package Data;
public class Data{
private String hotwords;
private String num;
private String explain;
private String website;
public String getExplain() {
return explain;
}
public void setExplain(String explain) {
this.explain = explain;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getHotwords() {
return hotwords;
}
public void setHotwords(String hotwords) {
this.hotwords = hotwords;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}
内部监视
- 内置监视器
组件可以维持状态、性能负载、容量、安全性或其他可通过接口访问的信息。此接口可以是该组件的一个永久接口,也可以是通过instrumentation技巧临时引入的接口,如面向方面编程或预处理宏。一个常见的技巧就是当监视状态被激活时记录事件。监视状态实际上会增加测试工作,因为随着监视的关闭,可能必须重复测试。尽管额外测试需要一定的开销,但这却使组件活动的可见性得以提高,这样做是值得的。
可以对文件运行的关键数据进行记录,如写入文件等来实现内部的监视,就像一个程序运行的日志一样,可以使程序运行状况更加一目了然。
学习于
作者:程序猿胖子
链接:https://www.jianshu.com/p/344c69a14d71
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。