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,分支度量,路徑度量),關注未測試到的代碼.
最后,推薦這幾天一直在看的幾篇文章,很有思考價值: <<不能成為專業測試的十大理由>>,
<<怎樣做測試?>>
<<測試人員需要經歷的階段>>