1、基本操作
# -*- coding: utf-8 -*- import sqlite3 def mykey(x): return x[3] conn=sqlite3.connect("D:\\demo\\my_db.db") sql = "CREATE TABLE IF NOT EXISTS mytb ( a char , b int , c real, d DATE)" # a char , b int , c real 表示该表有三个字段, # a 是字符串类型, b 是整数类型, c 是实数类型。 conn.execute( sql ) cs = conn.cursor() #cs.execute("DELETE FROM mytb WHERE A='张三' ") cs.execute("DELETE FROM mytb ") #删除所有记录 ''''' cs.execute( "INSERT INTO mytb ( a,b,c,d ) values('Zhang San',25, 120, '2014-03-04')" ) cs.execute( "INSERT INTO mytb ( a,b,c,d ) values( 'Wang Wu',24, 110, '2014-05-01')" ) cs.execute( "INSERT INTO mytb ( a,b,c,d ) values( 'Li Si',23, 130, '2014-04-06')" ) ''' #批量注入,batchdata是一个列表,列表里每一个元素都是一个元组 batchdata=[('Zhang San',25, 120, '2014-03-04'), ( 'Wang Wu',24, 110, '2014-05-01'), ( 'Li Si',23, 130, '2014-04-06')] cs.executemany('INSERT INTO mytb values (?,?,?,?)',batchdata) conn.commit() #将加入的记录保存到磁盘,非常重要! cs.execute("SELECT name, sql FROM sqlite_master WHERE type='table'") recs = cs.fetchall( ) print ( recs ) cs.execute( "SELECT * FROM mytb ")#打开数据表 recs = cs.fetchall()#取出所有记录 print ( "there is ", len(recs)," notes." ) print recs recs.sort(key = mykey) print recs cs.close() conn.close() |
以上代码参考Python中使用SQLite数据库简明教程,有少量改动
1.软件安装
(1)编译安装
root 账号登陆后,依次执行以下命令:
下载安装包:http://pan.baidu.com/s/1bn9vtFL
cd /tmp
tar zxvf lrzsz-0.12.20.tar.gz && cd lrzsz-0.12.20 ./configure && make && make install
上面安装过程默认把lsz和lrz安装到了/usr/local/bin/目录下,现在我们并不能直接使用,下面创建软链接,并命名为rz/sz:
cd /usr/bin
ln -s /usr/local/bin/lrz rz
ln -s /usr/local/bin/lsz sz
(2)yum安装
root 账号登陆后执行以下命令:
yum install -y lrzsz
2.使用说明
sz命令发送文件到本地:
#sz filename
rz命令本地上传文件到服务器:
#rz
执行该命令后,在弹出框中选择要上传的文件即可。
OCCI(
Oracle C++ Call Interface):C++程序与Oracle数据库实现交互的应用程序接口,它以动态连接库的形式提供给用户。OCCI对OCI实行了对象级的封装,其底层仍是OCI
1 安装Linux下的oracle客户端
2 下载对应的oracle-instantclient-basic-10.2.0.4-1.i386.zip将其拷贝至Linux的Oracle账户并解压至instantclient_10_2目录
实现OCCI的六大步骤:
1 创建环境变量Environment
2 创建连接对象Connection
4 执行SQL语句(execute()函数,executeUpdate()函数,executeQuery()函数)
5 处理结果集ResultSet(查询结果)
6 关闭连接
在Linux的Oracle数据库下创建一个表用于操作
create table user_info ( user_id int not null primary key, user_name varchar2(100) ); //AddOcci.cc #include <iostream> #include <string> #include <occi.h> #pragma comment(lib,"oci.lib") #pragma comment(lib,"ociw32.lib") #pragma comment(lib,"oraocci10.lib") using namespace std; using namespace oracle::occi; /******************************* *******************************/ int main() { //创建环境变量 //Environment Environment *env = Environment::createEnvironment(Environment::OBJECT); //username是oracle的用户名 //userpass是oracle的密码 //connstr是oracle的连接字符串 string username = "hahaya"; string userpass = "hahaya"; string connstr = "192.168.0.6:1521/orcl"; //创建连接 //connection Connection *conn = env->createConnection(username, userpass, connstr); if(conn == NULL) { cout << "access oracle failed..." << endl; return 0; } //创建一个SQL语句的执行对象 //statement Statement *st = conn->createStatement(); st->setSQL("insert into user_info values(1, 'hahaya')"); st->executeUpdate(); //关闭连接 env->terminateConnection(conn); Environment::terminateEnvironment(env); return 0; } |
执行AddOcci程序之前:
执行AddOcci程序之后:
//ListOcci.cc #include <iostream> #include <string> #include <occi.h> #pragma comment(lib,"oci.lib") #pragma comment(lib,"ociw32.lib") #pragma comment(lib,"oraocci10.lib") using namespace std; using namespace oracle::occi; /******************************* *查询表中数据 *******************************/ int main() { Environment *env = Environment::createEnvironment(Environment::OBJECT); string username = "hahaya"; string userpass = "hahaya"; string connstr = "192.168.0.6:1521/orcl"; Connection *conn = env->createConnection(username, userpass, connstr); Statement *st = conn->createStatement(); st->setSQL("select * from user_info"); ResultSet *rs = st->executeQuery(); while(rs->next()) { cout << "user id:" << rs->getInt(1) << "user name:" << rs->getString(2) << endl;; } st->closeResultSet(rs); env->terminateConnection(conn); Environment::terminateEnvironment(env); return 0; } |
执行ListOcci之前:
执行DelOcci结果:
<span style="font-family:FangSong_GB2312;font-size:18px;">import java.text.*; import java.util.*; import java.io.*; import javax.servlet.http.*; import javax.servlet.*; import com.bjpowernode.exam.model.*; import com.bjpowernode.exam.manager.*; public class SearchStudentServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sBeginDate = request.getParameter("beginDate"); String sEndDate = request.getParameter("endDate"); Date beginDate = new Date(); Date endDate = new Date(); try { beginDate = new SimpleDateFormat("yyyy-MM-dd").parse(sBeginDate); endDate = new SimpleDateFormat("yyyy-MM-dd").parse(sEndDate); }catch(Exception e) { e.printStackTrace(); } StudentManager studentManager = new StudentManagerImpl(); List<Student> studentList = studentManager.findStudentList(beginDate, endDate); //将学生列表设置到requet范围中 //request.setAttribute("student_list", studentList); //转发,转发是在服务器端转发的,客户端是不知道的 //request.getRequestDispatcher("/student_list.jsp").forward(request, response); //将studentList放到session中 HttpSession session = request.getSession(); session.setAttribute("student_list", studentList); //重定向,不会共享request //以下写法错误,该 "/"代表了8080端口 //response.sendRedirect("/student_list.jsp"); response.sendRedirect(request.getContextPath() + "/student_list.jsp"); } }</span> |
这个里面尝试了两种调到后面的Jsp方法,在servlet中调用转发、重定向的语句如下:
实现转发:
<span style="font-family:FangSong_GB2312;font-size:18px;">//转发,转发是在服务器端转发的,客户端是不知道的
request.getRequestDispatcher("/student_list.jsp").forward(request, response);</span>
分析:请求转发是服务器内部把对一个request/response的处理权,移交给另外一个对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。 传输的信息不会丢失。
实现重定向:
<span style="font-family:FangSong_GB2312;font-size:18px;">//重定向,不会共享request //以下写法错误,该 "/"代表了8080端口 response.sendRedirect("/student_list.jsp"); response.sendRedirect(request.getContextPath() + "/student_list.jsp");</span> |
深入(分析理解)
转发过程
客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法,把请求转发给指定的student_list.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完成的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在student_list中都能取出来,因此,student_list能把结果getAttribute()出来,getAttribute()出来后执行完把结果返回给客户端。整个过程是一个请求,一个响应。
重定向过程
客户发送一个请求到服务器,服务器匹配servlet,这都和请求转发一样,servlet处理完之后调用了sendRedirect()这个方法,这个方法是response的方法,所以,当这个servlet处理完之后,看到response.senRedirect()方法,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问student_list.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求student_list.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。
浅出(表象)
转发
当用RequestDispatcher请求转发后,地址栏为http://localhost:8080/test/TestServlet
这真好应正了上面的分析,我们起初请求的就一个servlet,至于你服务器端怎么转,流程怎么样的,我客户端根本就不知道,我发了请求后我就等着响应,那你服务器那边愿意怎么转就怎么转,我客户端不关心也没法知道,所以当服务器端转发到jsp后,它把结果返回给客户端,客户端根本就不知道你这个结果是我真正访问的servlet产生的,还是由servlet转发后下一个组件产生的。
重定向
当用sendRedirect重定向后,地址栏为http://localhost:8080/test/student_list.jsp
因为这个时候,客户端已经知道了他第二次请求的是student_list.jsp,服务器已经告诉客户端要去访问student_list.jsp了,所以地址栏里会显示想要访问的结果。
总结
转发在服务器端完成的;重定向是在客户端完成的
转发的速度快;重定向速度慢
转发的是同一次请求;重定向是两次不同请求
转发不会执行转发后的代码;重定向会执行重定向之后的代码
转发地址栏没有变化;重定向地址栏有变化
转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成
Forward是在服务器端的跳转,就是客户端一个请求发给服务器,服务器直接将请求相关的参数的信息原封不动的传递到该服务器的其他jsp或servlet去处理,而sendredirect是在客户端的跳转,服务器会返回给客户端一个响应报头和新的URL地址,原来的参数什么的信息如果服务器端没有特别处理就不存在了,浏览器会访问新的URL所指向的servlet或jsp,这可能不是原先服务器上的webservce了。
目标:目前越来越多的应用要支持
移动设备,html5的推出,方便了页面对移动app的支持,那么我们该如何有效的去
测试同时支持app和
web的代码?web的测试可以使用浏览器的一些工具来辅助测试,比如ff的一些插件捕捉请求,抓包,可以来分析数据,进而验证数据的正确性与否,但是移动app该如何进行测试,如何去抓包,捕捉这些请求,客户端上是无法实现的。那么有别的方法吗?如果客户端测试你仅仅只用一个客户端来完成说明你out了。介绍一种方法来实现在pc上抓包,监控app的所有请求,测试app的代码。
需要的技术:设置热点,抓包工具(这里使用fiddler),http请求的基本知识
搭建热点:
1.在文本中写出一下脚本:
@echo off @netsh wlan set hostednetwork mode=allow ssid=tuanqa key=123456 @netsh wlan start hostednetwork @echo on @echo press any key to stop hosted network @pause @netsh wlan stop hostednetwork @pause |
保存为wifi.bat
2.管理员的权限运行这个脚本,会出现一个dos的窗口,不要关闭。打开无线的开关(笔记本上的)找到网络设置,出现了一个新的无线连接我命名为
test,选中本地连接右键 属性 共享 选中共享给test 勾选允许其他网络访问。切换到刚才打开的dos 窗口 按任意键 窗口消失,再次以管理员身份运行,这个时候会发现多了一个wifi网络tuanqa 密码123456.
3.pc上运行fiddle,设置:tools》fiddle option》connections 监听端口设置成8888.手机连接tuanqa ,在高级设置里面设置代理 本机的dnsip 端口8888。
4.修改pc上的hosts ,让访问打到自己的测试环境,这个时候app上的操作请求 会被fiddle捕捉。
这样对于移动app的测试就可以向web页面的测试一样了,使用工具分析数据和请求了。
昨天参加了
单元测试的分享,加上最近项目做的挺多,以及慢慢体会<<Systematic software Testing>>(英文版)书中感觉,总结如下,其中有些点还不透彻.
软件测试过程中,产品需求到交付测试执行这个流程中,测试设计是重中之重,结合自己的
工作经验,个人认为:测试设计就是软件需求转换成测试需求,通过建模,从测试角度罗列功能对象,了解,分析被测对象,并不断和相关者沟通,确认,最终得到验证该模型的
测试用例过程.
引用Rick D. Craig and Stefan P. Jaskiel大师的一张图,说的是白盒测试+黑盒测试能改进软件的质量达60%,如图:
所以,测试之前很有必要对测试对象进行分析设计,以下是我在
黑盒测试设计以及白盒(目前做SDK项目)测试设计的心得:
黑盒设计经验总结:
1.设计过程是一个反复沟通,反复确认的过程.多问几个为什么
2.关注重点和难点,单个测试风险和整体测试风险,80%的精力集中到重点和难点,一定不要低估这个地方.
3.白盒的手段,黑盒的思想.看代码为补充.
4.白盒的思想,黑盒的手段,基于功能点分析.
5.黑盒思想,黑盒手段,场景很重要.
6.根据线上bug设计保持最新状态,个人认为:测试设计有效性,以项目上线1-3个月为维度,调整设计,激发测试思想.
7.探索性测试为补充(取消法,后退法,逆向思考很重要)
8.单元脚本也是测试设计的参考
9.测试设计历程(个人理解):基于需求的设计->基于经验的设计->基于风险的设计.
10.设计评审很重要,测试设计很有必要专门安排时间
11.设计过程关注单模块,多模块之间的耦合(bug都来自此)
12.根据不同项目,熟练使用测试用例方法,增强测试用例发现bug几率.(一般情况,开发自测测到的点不容易发现问题,考虑没测到的点容易发现问题.).
13.设计过程考虑测试类型,安全,性能,兼容.
14.不同产品测试设计特性不同,web产品(缺陷容忍度高)电信,金融产品(业务复杂,流程重.修复长,具体到某个sql字段)移动app产品(适配).
白盒或者说接口设计经验总结:
1. 熟悉代码,一个SDK的代码量不是很多,通过不断和开发沟通,弄清楚分支,然后特定场景是否有异常处理;
2. 如果一个SDK有UI层,有接口层,先做UI层的黑盒测试 设计,然后做接口层基于接口入参,出参设计,以及基于核心function的测试设计,因为在做黑盒也就是业务层的设计时,反馈给开发,提升开发代码的兼容和遗漏.SDK目前个人归纳为这么四类: 有UI层的SDK, 集成mtop接口的SDK,包含so包的SDK,以及只包含
java层的SDK,不同的SDK产品,测试设计的重点不同. UI层的SDK侧重适配测试, 集成mtop的SDK侧重异常处理,包含so包的侧重接口和适配,java层的sdk侧重接口.
3.SDK设计,看代码同时除了
学习设计模式外,更重要是为做测试设计分析服务,发现沟通漏洞.
4.基于底层的function设计,有些逻辑复杂的,要细分,想办法把每个节点测试到.
5.测试过程中,白盒测试不要脱离了黑盒测试,有些系统复杂的,白盒测试单个节点测试了没问题,但是联调有问题.
6.SDK Demo测试不能覆盖所有的逻辑,一定要针对Demo也要有测试思路,争取全面覆盖接口分支,代码逻辑分支.
7.写好的用例后,加入持续集成,能有度量工具对代码度量(satement coverage,分支度量,路径度量),关注未测试到的代码.
最后,推荐这几天一直在看的几篇文章,很有思考价值: <<不能成为专业测试的十大理由>>,
<<怎样做测试?>>
<<测试人员需要经历的阶段>>