1.1 安裝
一、安裝方式
1、正常安裝,安裝方式為‘只有我’
2、正常安裝,安裝方式為‘任何人’
二、安裝路徑
1、缺省路徑安裝
2、自定義安裝路徑(非C盤)
1)通過瀏覽,選擇自定義路徑
2)手動(dòng)輸入路徑(存在路徑、不存在的路徑)
3)輸入路徑的格式不正確
4)通過瀏覽的盤符,手動(dòng)輸入不存在的文件夾
5)指定路徑下已有同名文件
6)中文路徑(中文路徑、中英文混合路徑)
7)包含空格的路徑(空格、下劃線等合法路徑)
8)非法路徑(輸入特殊字符)
三、安裝環(huán)境:
1、沒安裝過
2、已安裝過老版本(系統(tǒng)正在使用、系統(tǒng)未使用)
3、已安裝了最新版本
4、卸載系統(tǒng)重新安裝
5、安裝一半,異常退出(比如:在線安裝斷網(wǎng)、本地安裝點(diǎn)取消、斷電等)可重新安裝
6、磁盤空間不足
7、刪除了部分文件(可正常安裝、修復(fù)、卸載系統(tǒng))
9、殺毒軟件
10、未達(dá)到最低配置時(shí)安裝
三、修復(fù)
1、利用安裝軟件進(jìn)行修復(fù)
2、利用修復(fù)文件進(jìn)行修復(fù)
四、安裝時(shí)快捷鍵使用情況
五、安裝完成
1、安裝成功,檢查版本信息是否正確
2、安裝完成,文件屬性為非只讀
3、安裝完成,快捷方式檢查,創(chuàng)建快捷方式正確
六、安裝完成進(jìn)入系統(tǒng)方式
1、通過桌面快捷方式進(jìn)入
2、通過‘開始’——‘所有程序’——系統(tǒng)快捷方式進(jìn)入
1.2 卸載
一、卸載方式
1、通過控制面板卸載
2、通過安裝程序卸載
3、通過‘開始’——‘所有程序’——‘XX系統(tǒng)卸載’
二、非法卸載
1、系統(tǒng)正在運(yùn)行時(shí)
2、系統(tǒng)正升級(jí)時(shí)
三、卸載完成后
1、桌面快捷方式消失
2、‘開始’——‘所有程序’中快捷方式消失
3、安裝路徑下此文件夾已被刪除
請(qǐng)根據(jù)下表和頁面截圖,設(shè)計(jì)《發(fā)表QQ說說》的功能點(diǎn)及
測(cè)試用例:
圖1 功能列表
圖2 QQ空間加載后,說說功能區(qū)展開截圖
圖3 光標(biāo)進(jìn)入文本框后截圖
圖4 文字超出規(guī)定后的效果截圖
圖5. 添加圖片的兩種模式本地上傳和我的相冊(cè)
圖6. 僅發(fā)表圖片后的效果
圖7.刪除圖片
圖8. 發(fā)表多張圖片
簡(jiǎn)介
通常來說,
Python不是一種高性能的語言,在某種意義上,這種說法是真的。但是,隨著以Numpy為中心的數(shù)學(xué)和科學(xué)軟件包的生態(tài)圈的發(fā)展,達(dá)到合理的性能不會(huì)太困難。
當(dāng)性能成為問題時(shí),運(yùn)行時(shí)間通常由幾個(gè)函數(shù)決定。用C重寫這些函數(shù),通常能極大的提升性能。
在本系列的第一部分中,我們來看看如何使用NumPy的C API來編寫C語言的Python擴(kuò)展,以改善模型的性能。在以后的
文章中,我們將在這里提出我們的解決方案,以進(jìn)一步提升其性能。
文件
這篇文章中所涉及的文件可以在Github上獲得。
模擬
作為這個(gè)練習(xí)的起點(diǎn),我們將在像重力的力的作用下為N體來考慮二維N體的模擬。
以下是將用于存儲(chǔ)我們世界的狀態(tài),以及一些臨時(shí)變量的類。
# lib/sim.py class World(object): """World is a structure that holds the state of N bodies and additional variables. threads : (int) The number of threads to use for multithreaded implementations. STATE OF THE WORLD: N : (int) The number of bodies in the simulation. m : (1D ndarray) The mass of each body. r : (2D ndarray) The position of each body. v : (2D ndarray) The velocity of each body. F : (2D ndarray) The force on each body. TEMPORARY VARIABLES: Ft : (3D ndarray) A 2D force array for each thread's local storage. s : (2D ndarray) The vectors from one body to all others. s3 : (1D ndarray) The norm of each s vector. NOTE: Ft is used by parallel algorithms for thread-local storage. s and s3 are only used by the Python implementation. """ def __init__(self, N, threads=1, m_min=1, m_max=30.0, r_max=50.0, v_max=4.0, dt=1e-3): self.threads = threads self.N = N self.m = np.random.uniform(m_min, m_max, N) self.r = np.random.uniform(-r_max, r_max, (N, 2)) self.v = np.random.uniform(-v_max, v_max, (N, 2)) self.F = np.zeros_like(self.r) self.Ft = np.zeros((threads, N, 2)) self.s = np.zeros_like(self.r) self.s3 = np.zeros_like(self.m) self.dt = dt |
在開始模擬時(shí),N體被隨機(jī)分配質(zhì)量m,位置r和速度v。對(duì)于每個(gè)時(shí)間步長(zhǎng),接下來的計(jì)算有:
合力F,每個(gè)體上的合力根據(jù)所有其他體的計(jì)算。
速度v,由于力的作用每個(gè)體的速度被改變。
位置R,由于速度每個(gè)體的位置被改變。
第一步是計(jì)算合力F,這將是我們的瓶頸。由于世界上存在的其他物體,單一物體上的力是所有作用力的總和。這導(dǎo)致復(fù)雜度為O(N^2)。速度v和位置r更新的復(fù)雜度都是O(N)。
如果你有興趣,這篇維基百科的文章介紹了一些可以加快力的計(jì)算的近似方法。
純Python
在純Python中,使用NumPy數(shù)組是時(shí)間演變函數(shù)的一種實(shí)現(xiàn)方式,它為優(yōu)化提供了一個(gè)起點(diǎn),并涉及測(cè)試其他實(shí)現(xiàn)方式。
# lib/sim.py def compute_F(w): """Compute the force on each body in the world, w.""" for i in xrange(w.N): w.s[:] = w.r - w.r[i] w.s3[:] = (w.s[:,0]**2 + w.s[:,1]**2)**1.5 w.s3[i] = 1.0 # This makes the self-force zero. w.F[i] = (w.m[i] * w.m[:,None] * w.s / w.s3[:,None]).sum(0) def evolve(w, steps): """Evolve the world, w, through the given number of steps.""" for _ in xrange(steps): compute_F(w) w.v += w.F * w.dt / w.m[:,None] w.r += w.v * w.dt |
合力計(jì)算的復(fù)雜度為O(N^2)的現(xiàn)象被NumPy的數(shù)組符號(hào)所掩蓋。每個(gè)數(shù)組操作遍歷數(shù)組元素。
可視化
這里是7個(gè)物體從隨機(jī)初始狀態(tài)開始演化的路徑圖:
性能
為了實(shí)現(xiàn)這個(gè)基準(zhǔn),我們?cè)陧?xiàng)目目錄下創(chuàng)建了一個(gè)腳本,包含如下內(nèi)容:
import lib
w = lib.World(101)
lib.evolve(w, 4096)
我們使用cProfile模塊來測(cè)試衡量這個(gè)腳本。
python -m cProfile -scum bench.py
前幾行告訴我們,compute_F確實(shí)是我們的瓶頸,它占了超過99%的運(yùn)行時(shí)間。
428710 function calls (428521 primitive calls) in 16.836 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 16.837 16.837 bench.py:2(<module>) 1 0.062 0.062 16.756 16.756 sim.py:60(evolve) 4096 15.551 0.004 16.693 0.004 sim.py:51(compute_F) 413696 1.142 0.000 1.142 0.000 {method 'sum' ... 3 0.002 0.001 0.115 0.038 __init__.py:1(<module>) ... |
在Intel i5臺(tái)式機(jī)上有101體,這種實(shí)現(xiàn)能夠通過每秒257個(gè)時(shí)間步長(zhǎng)演化世界。
簡(jiǎn)單的C擴(kuò)展 1
在本節(jié)中,我們將看到一個(gè)C擴(kuò)展模塊實(shí)現(xiàn)演化的功能。當(dāng)看完這一節(jié)時(shí),這可能幫助我們獲得一個(gè)C文件的副本。文件src/simple1.c,可以在GitHub上獲得。
關(guān)于NumPy的C API的其他文檔,請(qǐng)參閱NumPy的參考。Python的C API的詳細(xì)文檔在這里。
樣板
文件中的第一件事情是先聲明演化函數(shù)。這將直接用于下面的方法列表。
static PyObject *evolve(PyObject *self, PyObject *args);
接下來是方法列表。
static PyMethodDef methods[] = {
{ "evolve", evolve, METH_VARARGS, "Doc string."},
{ NULL, NULL, 0, NULL } /* Sentinel */
};
這是為擴(kuò)展模塊的一個(gè)導(dǎo)出方法列表。這只有一個(gè)名為evolve方法。
樣板的最后一部分是模塊的初始化。
PyMODINIT_FUNC initsimple1(void) {
(void) Py_InitModule("simple1", methods);
import_array();
}
另外,正如這里顯示,initsimple1中的名稱必須與Py_InitModule中的第一個(gè)參數(shù)匹配。對(duì)每個(gè)使用NumPy API的擴(kuò)展而言,調(diào)用import_array是有必要的。
數(shù)組訪問宏
數(shù)組訪問的宏可以在數(shù)組中被用來正確地索引,無論數(shù)組被如何重塑或分片。這些宏也使用如下的代碼使它們有更高的可讀性。
#define m(x0) (*(npy_float64*)((PyArray_DATA(py_m) + \
(x0) * PyArray_STRIDES(py_m)[0])))
#define m_shape(i) (py_m->dimensions[(i)])
#define r(x0, x1) (*(npy_float64*)((PyArray_DATA(py_r) + \
(x0) * PyArray_STRIDES(py_r)[0] + \
(x1) * PyArray_STRIDES(py_r)[1])))
#define r_shape(i) (py_r->dimensions[(i)])
在這里,我們看到訪問宏的一維和二維數(shù)組。具有更高維度的數(shù)組可以以類似的方式被訪問。
在這些宏的幫助下,我們可以使用下面的代碼循環(huán)r:
for(i = 0; i < r_shape(0); ++i) {
for(j = 0; j < r_shape(1); ++j) {
r(i, j) = 0; // Zero all elements.
}
}
命名標(biāo)記
上面定義的宏,只在匹配NumPy的數(shù)組對(duì)象定義了正確的名稱時(shí)才有效。在上面的代碼中,數(shù)組被命名為py_m和py_r。為了在不同的方法中使用相同的宏,NumPy數(shù)組的名稱需要保持一致。
計(jì)算力
特別是與上面五行的Python代碼相比,計(jì)算力數(shù)組的方法顯得頗為繁瑣。
static inline void compute_F(npy_int64 N, PyArrayObject *py_m, PyArrayObject *py_r, PyArrayObject *py_F) { npy_int64 i, j; npy_float64 sx, sy, Fx, Fy, s3, tmp; // Set all forces to zero. for(i = 0; i < N; ++i) { F(i, 0) = F(i, 1) = 0; } // Compute forces between pairs of bodies. for(i = 0; i < N; ++i) { for(j = i + 1; j < N; ++j) { sx = r(j, 0) - r(i, 0); sy = r(j, 1) - r(i, 1); s3 = sqrt(sx*sx + sy*sy); s3 *= s3 * s3; tmp = m(i) * m(j) / s3; Fx = tmp * sx; Fy = tmp * sy; F(i, 0) += Fx; F(i, 1) += Fy; F(j, 0) -= Fx; F(j, 1) -= Fy; } } } |
請(qǐng)注意,我們使用牛頓第三定律(成對(duì)出現(xiàn)的力大小相等且方向相反)來降低內(nèi)環(huán)范圍。不幸的是,它的復(fù)雜度仍然為O(N^2)。
演化函數(shù)
該文件中的最后一個(gè)函數(shù)是導(dǎo)出的演化方法。
static PyObject *evolve(PyObject *self, PyObject *args) { // Declare variables. npy_int64 N, threads, steps, step, i; npy_float64 dt; PyArrayObject *py_m, *py_r, *py_v, *py_F; // Parse arguments. if (!PyArg_ParseTuple(args, "ldllO!O!O!O!", &threads, &dt, &steps, &N, &PyArray_Type, &py_m, &PyArray_Type, &py_r, &PyArray_Type, &py_v, &PyArray_Type, &py_F)) { return NULL; } // Evolve the world. for(step = 0; step< steps; ++step) { compute_F(N, py_m, py_r, py_F); for(i = 0; i < N; ++i) { v(i, 0) += F(i, 0) * dt / m(i); v(i, 1) += F(i, 1) * dt / m(i); r(i, 0) += v(i, 0) * dt; r(i, 1) += v(i, 1) * dt; } } Py_RETURN_NONE; } |
在這里,我們看到了Python參數(shù)如何被解析。在該函數(shù)底部的時(shí)間步長(zhǎng)循環(huán)中,我們看到的速度和位置向量的x和y分量的顯式計(jì)算。
性能
C版本的演化方法比Python版本更快,這應(yīng)該不足為奇。在上面提到的相同的i5臺(tái)式機(jī)中,C實(shí)現(xiàn)的演化方法能夠?qū)崿F(xiàn)每秒17972個(gè)時(shí)間步長(zhǎng)。相比Python實(shí)現(xiàn),這方面有70倍的提升。
觀察
注意,C代碼一直保持盡可能的簡(jiǎn)單。輸入?yún)?shù)和輸出矩陣可以進(jìn)行類型檢查,并分配一個(gè)Python裝飾器函數(shù)。刪除分配,不僅能加快處理,而且消除了由Python對(duì)象不正確的引用計(jì)數(shù)造成的內(nèi)存泄露(或更糟)。
下一部分
在本系列文章的下一部分,我們將通過發(fā)揮C-相鄰NumPy矩陣的優(yōu)勢(shì)來提升這種實(shí)現(xiàn)的性能。之后,我們來看看使用英特爾的SIMD指令和OpenMP來進(jìn)一步推進(jìn)。
今天我主要來說下過年時(shí)候自己做的一些
性能測(cè)試,由于時(shí)間緊迫,所以最終選擇了全部從log方面入手,從而最終達(dá)到一氣呵成的效果。
分別有這樣幾個(gè)大項(xiàng):
1. Android應(yīng)用啟動(dòng)消耗時(shí)間 我們分別在Activity的生命周期方法內(nèi)添加Log.e(tag,message),如下效果:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("AppStartTime","AppOnCreate"); ... } @Override protected void onResume() { super.onResume(); Log.e("AppStartTime","AppOnResume"); ... } |
,這里的tag我們使用AppStartTime,那么我們需要在應(yīng)用啟動(dòng)之后在command內(nèi)輸入:
adb logcat -v time -v threadtime *:E | grep ActivityStartTime>StartTimeFile.txt
2. cpu和內(nèi)存消耗
在command中輸入如下命令:
adb
shell top -n 400 | grep <your package name>Cpu_MemoryFile.txt
3. GC
在command中輸入如下命令:
adb logcat -v time -v threadtime *:D | grep GC>GCFile.txt
這里需要注意的是,GC分析的時(shí)候需要關(guān)注三個(gè)值。
average_GC_Freed
average_GC_per
average_GC_time
4. 網(wǎng)絡(luò)流量
在被測(cè)應(yīng)用中增加一個(gè)獲取所有應(yīng)用的網(wǎng)絡(luò)流量的service,添加一個(gè)getAppTrafficList( )方法,代碼如下:
publicvoidgetAppTrafficList(){ PackageManagerpm=getPackageManager(); List<PackageInfo>pinfos=pm .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES |PackageManager.GET_PERMISSIONS); for(PackageInfoinfo:pinfos){ String[]premissions=info.requestedPermissions; if(premissions!=null&&premissions.length>0){ for(Stringpremission:premissions){ if("android.permission.INTERNET".equals(premission)){ intuId=info.applicationInfo.uid; longrx=TrafficStats.getUidRxBytes(uId); longtx=TrafficStats.getUidTxBytes(uId); if(rx<0||tx<0){ continue; }else{ Log.e("網(wǎng)絡(luò)流量",info.applicationInfo.loadLabel(pm)+Formatter.formatFileSize(this,rx+tx) } } } } } } |
如果還要其他數(shù)據(jù),那么全部可以按照以上的方法去獲取。然后我們來看如何使用python一次性分析這些文件從而直接獲取report。
首先引入第三方繪制pdf的模塊:
# -*- coding: utf-8 -*-
from reportlab.graphics.shapes import *
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics import renderPDF
然后我們需要一個(gè)讀文件的方法:
def FileRead(path):
data_list = []
number_list = []
number = 0
for line in open(path):
data_list.append(line)
number =number+1
number_list.append(number)
return data_list,number_list
接著我們需要一個(gè)制作pdf的方法:
def MakePDF(times,list,reportname,pdfname):
drawing = Drawing(500,300) lp = LinePlot() lp.x = 50 lp.y = 50 lp.height = 125 lp.width = 300 lp.data = [zip(times, list)] lp.lines[0].strokeColor = colors.blue lp.lines[1].strokeColor = colors.red lp.lines[2].strokeColor = colors.green drawing.add(lp) drawing.add(String(350,150, reportname,fontSize=14,fillColor=colors.red)) renderPDF.drawToFile(drawing,pdfname,reportname) #這里的times和list兩個(gè)參數(shù)都是list,是時(shí)間和監(jiān)控獲取的數(shù)據(jù)一一對(duì)應(yīng)的關(guān)系 這些我們都有了之后,我們來看下分析AppStartTime的方法: def analysisStartFile(list): totalcount =0 totaltime =0 time_list =[] totalcount_list = [] for i in range(len(list)): if 'AppStartTime' in list[i]: totalcount =totalcount+1 totalcount_list.append(totalcount) if float(list[i+4].split(' ')[1][-6:])-float(list[i].split(' ')[1][-6:])>0: totaltime=totaltime+float(list[i+4].split(' ')[1][-6:])-float(list[i].split(' ')[1][-6:]) time_list.append(float(list[i+4].split(' ')[1][-6:])-float(list[i].split(' ')[1][-6:])) return totalcount_list,'%.2f'%float(totaltime/totalcount),time_list |
所有的分析數(shù)據(jù)的思維都是使用split()方法分隔空格之后做分析。因?yàn)樽x取文件之后是將所有的數(shù)據(jù)存在list中,但是當(dāng)我們?nèi)ビ玫臅r(shí)候由于空格在其中就變得非常的麻煩,那么我們可以先使用split將空格去掉,然后使用if key in list的方法進(jìn)行過濾再做分析。
最后在main()方法中基本就是如下的順序執(zhí)行方法:
if __name__== '__main__':
list1,list2 = FileRead(<your file path>)
print list1,list2
list_count,average_start_time,time_list = analysisStartFile(list1)
MakePDF(list_count,time_list,'average time:'+str(average_start_time)+'s',"啟動(dòng)性能報(bào)告.pdf")
最終我們就能夠批量的生成如下圖的報(bào)告了。
一點(diǎn)點(diǎn)必要的廢話
JavaScript的發(fā)展大體上經(jīng)歷了下面幾個(gè)比較大的階段:
第一階段:石器時(shí)代。
基本上沒有任何框架和工具,而且各種瀏覽器混戰(zhàn),API相當(dāng)混亂,開發(fā)和
測(cè)試都非常痛苦。
第二階段:刀耕火種。
出現(xiàn)了一些簡(jiǎn)單的、小型的工具,比如prototype/mootools之類的。
第三階段:農(nóng)耕文明。
2005年左右,Ajax、JSON等技術(shù)開始興起,并且以非常快的速度普及。這個(gè)階段出現(xiàn)了jQuery之類的神器,但是還是有大量的問題沒有解決,開發(fā)和測(cè)試依然非常痛苦,各種工具很亂,
學(xué)習(xí)過程漫長(zhǎng)。
第四階段:規(guī)模化、結(jié)構(gòu)化。
前端代碼的規(guī)模越來越大,結(jié)構(gòu)化、模塊化的呼聲越來越高,開始出現(xiàn)專業(yè)的“前端工程師”這樣的職業(yè)。各個(gè)
互聯(lián)網(wǎng)大佬都開始組建自己的UED部門,比如
騰訊的CDC、淘寶的UED、網(wǎng)易的UEDC。
對(duì)于前端開發(fā)來說,這一階段已經(jīng)發(fā)生了思想上飛躍。此時(shí)前端考慮的問題已經(jīng)不僅僅是“如何把界面做得好看”這么簡(jiǎn)單了,對(duì)前端的要求已經(jīng)提升到了“用戶體驗(yàn)”的層次,界面“好看”只是其中一部分,還要做交互設(shè)計(jì),怎么讓用戶操作更方便、怎么讓界面更人性化,如此等等。 在這個(gè)階段出現(xiàn)了很多重量級(jí)的框架,大體上分2個(gè)體系:一個(gè)是以jQuery為內(nèi)核的前端框架,例如jQueryUI之類的各類UI;另一個(gè)就是自成體系的ExtJS。
(有人可能會(huì)說還有Flex、SilverLight、JavaFX之類的東西呢!這里專門說JS,那些先不管,謝謝。)
第五階段:工業(yè)化、多平臺(tái)。
JavaScript代碼不僅僅規(guī)模更加龐大,而且要支持各種平臺(tái)。2008年之后,安卓異軍突起,加上iPhone的強(qiáng)勢(shì)插入,
移動(dòng)平臺(tái)上的UI 設(shè)計(jì)日益收到重視。移動(dòng)平臺(tái)的迅速崛起進(jìn)一步刺激了桌面UI體系的演進(jìn),jQeury推出了jQuery Mobile,ExtJS推出了自己的Touch版本,其它各種衍生框架也都出現(xiàn)了Touch版本。
我們知道,科技領(lǐng)域的工業(yè)化是以機(jī)器代替人力為核心特征的,對(duì)比前端代碼的工業(yè)化,我們立刻就會(huì)發(fā)現(xiàn),自動(dòng)化程度依然不夠。雖然出現(xiàn)了像WebStorm這樣的前端開發(fā)神器,但是對(duì)于
自動(dòng)化測(cè)試、
性能測(cè)試之類的需求,依然沒有成熟的、統(tǒng)一的工具。
近來TDD(
Test Driving Develop)的概念越來越熱,加上來自
Google的AnguarJS框架開始流行,TDD正在被廣泛接受。因此,在這個(gè)階段,必須解決工具的問題,而自動(dòng)化測(cè)試工具就是其中需求最強(qiáng)烈的一個(gè)工具。
好,廢話結(jié)束,開始玩兒JsTestDriver。
JsTestDriver簡(jiǎn)介
完整介紹參見官方的頁面
安裝Eclipse插件
請(qǐng)使用Eclipse的插件安裝工具
注意:
1、Eclipse版本不能太低。
2、如果在線安裝不成功,可以把插件下載到本地,然后再用Eclipse的插件安裝工具從本地安裝。
3、只安裝JS Test Driver Plugin for Eclipse,其它的不要安裝,否則會(huì)報(bào)沖突。
安裝完成之后,開始配置JsTestDriver,步驟如下:
第一步:配置JsTestDriver服務(wù)器
在Eclipse的菜單中選擇Window->Preferences,在左側(cè)找到JS Test Driver。
第二步:打開JsTestDriver的控制面板
在Eclipse頂部的菜單中選擇Window->Show View,找到JsTestDriver并雙擊,這樣JsTestDriver的控制面板就顯示出來了。
好,到這里安裝配置就算完成了,接下來我們來做一個(gè)最簡(jiǎn)單的例子試試手感。 最簡(jiǎn)單的例子
第一步:在Eclipse中新建一個(gè)WEB項(xiàng)目,名字隨意。
第二步:在WebContent目錄下新建js和js-test兩個(gè)目錄。js目錄用來放你的js源代碼,js-test用來放JsTestDriver的測(cè)試用例代碼。
第三步:在js目錄下新建一個(gè)myjs.js,內(nèi)容如下:
myapp = {};
myapp.Greeter = function() { };
myapp.Greeter.prototype.greet = function(name) {
return "Hello " + name + "!";
};
在js-test的目錄下新建一個(gè)testMyJS.js,內(nèi)容如下:
GreeterTest = TestCase("GreeterTest");
GreeterTest.prototype.testGreet = function() {
var greeter = new myapp.Greeter();
assertEquals("Hello World!", greeter.greet("World"));
};
以上測(cè)試用例的代碼和Java中的JUnit比較類似。這里我們先不管上面代碼的具體含義,先想辦法讓工具跑起來再說,我們繼續(xù)。
第四步:創(chuàng)建JsTestDriver配置文件。
直接在WebContent目錄下創(chuàng)建一個(gè)jsTestDriver.conf,內(nèi)容如下:
server: http://localhost:8259
load:
- jasmine/*.*
- jasmine-adapter/JasmineAdapter.js
- js/*.js
- js-test/*.js
注意上面的端口號(hào),必須和前面設(shè)置的端口號(hào)一致。
這種配置文件的風(fēng)格叫做YAML,JsTestDriver配置文件的完整說明
第五步:開始運(yùn)行。
點(diǎn)擊Eclipse工具欄中的運(yùn)行按鈕左側(cè)的小三角,選擇Run Configrations,如下圖:
配置成以下形式:
一、前言
Web自動(dòng)化
測(cè)試一直是一個(gè)比較迫切的問題,對(duì)于現(xiàn)在web開發(fā)的
敏捷開發(fā),卻沒有相對(duì)應(yīng)的
敏捷測(cè)試,故開此主題,一邊研究,一邊將Web自動(dòng)化測(cè)試應(yīng)用于
工作中,進(jìn)而形成能夠獨(dú)立成章的博文,希望能夠?yàn)閲鴥?nèi)web自動(dòng)化測(cè)試的發(fā)展做一點(diǎn)綿薄的貢獻(xiàn)吧,笑~
二、Watir搭建流程
圖1-1 需要安裝的工具
因?yàn)榘惭b
Ruby還需要用到其他的一些開發(fā)工具集,所以建議從網(wǎng)站下載,而且使用該安裝包的話,它會(huì)幫你把環(huán)境變量也設(shè)置完畢,我使用的版本是:railsinstaller-2.2.4.exe,建議下載最新版本。
圖1-2 RailsInstaller工具包安裝界面
開始安裝RailsInstaller工具包,安裝到默認(rèn)位置即可。
圖1-3 安裝完畢界面
這個(gè)對(duì)勾建議打上,它會(huì)幫你配置git和ssh,安裝過程中ruby等一系列環(huán)境變量也配置OK了,挺好~
圖1-4 測(cè)試Ruby安裝情況
安裝好railsinstaller-2.2.4.exe后,打開cmd命令行,輸入命令:ruby –v,如果,出現(xiàn)圖1-4所示ruby的版本情況,則說明ruby已經(jīng)安裝完畢,我們也可以輸入命令測(cè)試一下gem的版本:gem –v,如圖1-4所示,gem也是安裝成功。
圖1-5 gem安裝情況
使用命令:gem list,查看一下,如圖1-5,你會(huì)發(fā)現(xiàn),railsinstaller安裝完畢后,默認(rèn)是不包含Watir自動(dòng)化測(cè)試工具的,所以我們現(xiàn)在要開始安裝watir。
圖1-6 gem命令
先簡(jiǎn)單看一眼gem怎么用,如上圖1-6所示,
圖1-7 安裝watir命令
使用命令:gem install watir,進(jìn)行安裝watir,如果順利的話,下面會(huì)出現(xiàn)很多的successfully等文字;不過在國內(nèi),你一般是看不到successfully等文字的,因?yàn)閔ttps://rubygems.org/已經(jīng)被墻了,現(xiàn)在我們要對(duì)gem的源進(jìn)行修改一下,來達(dá)到安裝watir的目的。

圖1-8 RubyGems鏡像網(wǎng)址
首先使用命令:gem sources -l,查看一下gem的當(dāng)前源,一般都是:https://rubygems.org/
然后我們使用命令:gem sources --remove https://rubygems.org/
接著輸入命令:gem sources -a https://ruby.taobao.org/
參考上圖。
圖1-9 查看gem的源
現(xiàn)在再看一下gem的源這是是否正確:gem sources -l,如果只有:https://ruby.taobao.org/,一個(gè)源,則說明配置正確。然后再使用命令安裝Watir:gem install watir,這次應(yīng)該就能夠安裝成功了。
圖1-10 commonwatir和watir版本
我們可以再次使用命令:gem list,可以看到,list里面有好多與watir相關(guān)的內(nèi)容,這里主要關(guān)心兩個(gè)工具,如上圖所示,commonwatir和watir,這里需要給commonwatir和watir降版本到3.0.0,如果不進(jìn)行降級(jí),會(huì)出現(xiàn)NameError錯(cuò)誤,命令如下:
圖1-11 watir降級(jí)到3.0.0
輸入命令:gem uninstall watir -v 5.0.0
輸入命令:gem install watir -v 3.0.0
圖1-12 commonwatir降級(jí)到3.0.0
輸入命令:gem uninstall commonwatir -v 4.0.0
輸入命令:gem install commonwatir -v 3.0.0
圖1-13 ruby測(cè)試代碼
require "watir"
puts "Open IE..."
ie=Watir::IE.new
ie.goto(http://www.baidu.com/)
puts "IE is opened - enjoy it :)"
在文本編輯器中新建一個(gè)test.rb文件,輸入以上代碼,強(qiáng)烈建議手動(dòng)輸入,空格不慎也會(huì)導(dǎo)致運(yùn)行失敗。
圖1-14 ruby文件編碼
編碼也要注意,使用UTF-8編碼。
圖1-15 測(cè)試效果
將test.rb保存完畢后,在cmd命令行輸入命令:ruby test.rb如果ruby代碼沒有報(bào)錯(cuò),程序就會(huì)自動(dòng)打開IE瀏覽器,自動(dòng)輸入http://www.baidu.com/,打開百度頁面。至此,《Windows環(huán)境搭建Web自動(dòng)化測(cè)試框架Watir(基于Ruby)第1章》編寫完畢。
三、本章總結(jié)
我們通過一系列的配置,將ruby和watir部署到windows平臺(tái)上,下一步,我們就可以編寫各種各樣的測(cè)試腳本,針對(duì)不同的web應(yīng)用,進(jìn)行不同的測(cè)試。
51Testing: 陳曄老師,您好,聽說您在工作期間創(chuàng)立了"移動(dòng)測(cè)試會(huì)"免費(fèi)公益沙龍,移動(dòng)測(cè)試會(huì),目前又和網(wǎng)易,cstqb,支付寶等都有深入合作,你是如何合理的分配您的時(shí)間,同時(shí)能完成這么多事情? 陳曄:說到這個(gè)我還是很慚愧的,行業(yè)中很多朋友都和我說,要多陪陪女兒,要多陪陪家里,這點(diǎn)上面我的確做的不夠。不過關(guān)注我微信的都知道,我還兼職美食家,每天都在吃不同的東西,我還是有那么一點(diǎn)點(diǎn)追求的。大家可以去看我自己寫的一年的行程,我?guī)缀趺恐茈p休日都排滿,不是去大會(huì)演講就是去學(xué)校給學(xué)生公益的做技術(shù)指導(dǎo)。最忙的莫過于我開始寫書的時(shí)候也是我女兒剛出生的那個(gè)時(shí)間點(diǎn),在這個(gè)過程中其實(shí)evernote給了我很大的幫助,我會(huì)把每天的事情列出來,然后每天逐個(gè)擊破。不過也和我小時(shí)習(xí)慣晚睡有吧,所以幾乎那個(gè)時(shí)候我都是每天2點(diǎn)左右睡的。因?yàn)檎娴挠泻芏嗍虑槭峭砩献鲂时容^高。
51Testing: 作為國內(nèi)Android與iOS最早的工程師之一,您有什么成功的秘訣和我們分享嗎? 陳曄:其實(shí)要說從我從公司走向行業(yè)到現(xiàn)在其實(shí)也就2年的時(shí)間,并不是很長(zhǎng)。當(dāng)然成功肯定不敢當(dāng),現(xiàn)在只是剛開始。至于秘訣的話。我個(gè)人總結(jié)出來以下幾條。
1.考慮問題盡量目光放長(zhǎng)遠(yuǎn),不要自己局限自己
很多人在公司,忙業(yè)務(wù)忙技術(shù),但是看問題的角度并沒有跳出公司去看。往往最后都是盲人摸象,無法看到一個(gè)總體,從而自己在限制自己。
2.定制短期的計(jì)劃
可以有長(zhǎng)期的目標(biāo),但是計(jì)劃肯定是短期的。一方面長(zhǎng)期的話很多人無法堅(jiān)持下去。另外一方面就是,在我整個(gè)經(jīng)歷中我已經(jīng)很強(qiáng)烈的感受到一點(diǎn),"計(jì)劃趕不上變化"是有道理的。我們需要的就是很強(qiáng)的
學(xué)習(xí)能力,然后去以不變應(yīng)萬變。
3.踏實(shí)點(diǎn)
不要每天去聊qq,聊薪資,去聊點(diǎn)虛的,更不要想著出名賺外快。無論作為一個(gè)測(cè)試,你將來轉(zhuǎn)作什么崗位,只要你還是做IT的,那么你還是需要有技術(shù)基礎(chǔ),否則都是紙上談兵罷了。現(xiàn)在行業(yè)的發(fā)展越來越快,對(duì)于技術(shù)的要求也越來越高。所以不要去問一些大而全的問題,先好好學(xué)習(xí)技術(shù)基礎(chǔ)才是王道。
陳曄:首先第一點(diǎn),不懂代碼,不去看源碼的還是不要來移動(dòng)互聯(lián)網(wǎng)做測(cè)試了,很快就會(huì)被淘汰了。
其實(shí)從現(xiàn)在來看,可能很多人會(huì)覺得大數(shù)據(jù)、智能家居等會(huì)是未來的方向。但我覺得就測(cè)試而言,無論方向什么,我們還是要抓住技術(shù)的基礎(chǔ),也許Android和iOS哪天都會(huì)倒,也許將來又是新的語言和技術(shù),但作為一個(gè)移動(dòng)互聯(lián)網(wǎng)的測(cè)試,我們必須用最快的速度去接收和學(xué)習(xí),為什么我一直強(qiáng)調(diào)學(xué)習(xí)能力很重要,就是這個(gè)道理。如果作為移動(dòng)互聯(lián)網(wǎng)測(cè)試的你,每天還是渾渾噩噩,只會(huì)用工具,覺得不看代碼就能夠?qū)?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">測(cè)試用例,那么我勸你要么快點(diǎn)努力學(xué)習(xí),要么就快點(diǎn)轉(zhuǎn)行業(yè)吧,不用多久肯定淘汰。
隨著發(fā)展,測(cè)試人員需要提升自己的技術(shù),讓自己八面玲瓏。我個(gè)人覺得移動(dòng)互聯(lián)網(wǎng)測(cè)試未來的戰(zhàn)斗就是和數(shù)據(jù)以及新事物的戰(zhàn)斗。任何測(cè)試都需要用數(shù)據(jù)來說,性能、壓力、用戶體驗(yàn)等,而如何獲取更準(zhǔn)確的、顆粒度更細(xì)的數(shù)據(jù)來反映問題也是對(duì)測(cè)試的一種挑戰(zhàn)。而隨著移動(dòng)互聯(lián)網(wǎng)飛速的發(fā)展,每天都會(huì)有新的技術(shù)、新的語言出現(xiàn),我們隨時(shí)要用120%的熱情和專注去接收這一切。
最后我想說兩點(diǎn)。第一點(diǎn),請(qǐng)客觀的認(rèn)清自己的能力,不要浪費(fèi)時(shí)間在聊天上,請(qǐng)花時(shí)間在學(xué)習(xí)上面,不要覺得好像測(cè)試的要求不應(yīng)該那么高。不是國內(nèi)要求高,而是大部分測(cè)試都在非正常的要求下工作,現(xiàn)在一旦要求回歸正軌之后就出現(xiàn)各種抱怨,抱怨不能改變?nèi)魏问虑椋?qǐng)記住。第二點(diǎn),站在盡量高的高度去看問題,然后給自己做規(guī)劃吧。不要回頭看,自己花了10年一直在重復(fù)工作。
51Testing:在您從事移動(dòng)互聯(lián)網(wǎng)測(cè)試的工作過程中,是否遇到過什么困難?要如何解決?
陳曄:工作過程中遇到的最大的困難莫過于要接觸很多自己不懂的東西。移動(dòng)互聯(lián)網(wǎng)現(xiàn)在發(fā)展非常快,開發(fā)技術(shù)快,
測(cè)試技術(shù)更快。在學(xué)習(xí)一個(gè)新技術(shù)的時(shí)候,我建議大家盡量先去看官方網(wǎng)站,畢竟官方網(wǎng)站的消息是最新的,不要去到qq上去毫無目的的去問。目前國內(nèi)上google不是很方便,但我依然很推薦大家遇見問題,自主的能夠多上google、stackoverflow和github等網(wǎng)站看看。這樣慢慢的培養(yǎng)自己自主解決問題的能力,自然而然學(xué)習(xí)能力就會(huì)有提升。
陳曄:APP的自動(dòng)化我就一句話,一定要分層,而且要分的細(xì)。不要把所有的風(fēng)險(xiǎn)都?jí)涸赨I自動(dòng)化或者手工測(cè)試上看,或者說壓在打好包的APP上面。分層要講就非常多了。從界面到代碼,可能還涉及到一些軟硬件結(jié)合。從前端的功能到后端的接口。界面上細(xì)分我們還可以看到natvie的測(cè)試和webview的測(cè)試方式很不同,從接口層面來講,我們用python的requests或者
java的httpclient直接測(cè)試接口,和我們?nèi)フ{(diào)用開發(fā)的接口去做測(cè)試又是兩個(gè)層面。所以總而言之,一定要分層,將風(fēng)險(xiǎn)平均化,才能夠在快速迭代的移動(dòng)互聯(lián)網(wǎng)的項(xiàng)目各個(gè)階段保證好質(zhì)量。
51Testing: 您認(rèn)為APP測(cè)試區(qū)別與其他應(yīng)用測(cè)試需要特別關(guān)注的內(nèi)容有哪些?
陳曄: APP的測(cè)試目前相對(duì)傳統(tǒng)互聯(lián)網(wǎng)的測(cè)試需要特別關(guān)注的點(diǎn)我覺得有如下一些:
1. 平臺(tái)特性
Android、iOS,WP等平臺(tái)各自有各自的特性,不僅僅是表面大家知道的分辨率,還有就是應(yīng)用每個(gè)操作在系統(tǒng)內(nèi)部有什么變化,這些我們都需要去了解
2. 網(wǎng)絡(luò)變化
移動(dòng)的網(wǎng)絡(luò)變化很大,弱網(wǎng)絡(luò)情況下我們的應(yīng)用的邏輯是否會(huì)有問題這個(gè)很重要。昨天的工作中我還發(fā)現(xiàn)我們自己的應(yīng)用在弱網(wǎng)絡(luò)下js重復(fù)加載的問題。
3. 碎片化
這個(gè)就是我第一點(diǎn)中提到的特性,不過還是需要單獨(dú)拿出來列一下。
4. 移動(dòng)無線的安全
移動(dòng)無線的安全隨著發(fā)展,越來越變的重要。對(duì)于APP而言,除了網(wǎng)絡(luò)層面的安全以外,還有很多和自身特性有關(guān)的安全,比如Activity啟動(dòng)參數(shù)注入,contentprovider的數(shù)據(jù)共享,iOS遠(yuǎn)程ssh登陸等。這些對(duì)測(cè)試而言挑戰(zhàn)也很大
5. 移動(dòng)無線的性能
很多人在最初很容易就覺得移動(dòng)無線的性能和服務(wù)器的并發(fā)是一個(gè)東西,很多人都在問一個(gè)應(yīng)用很多人在用的時(shí)候怎么測(cè)試性能,這個(gè)其實(shí)還是服務(wù)器上的性能問題。而這里我要說的是APP本身的性能問題。其關(guān)注點(diǎn)很多,比如電量,流量等,深入的話還有內(nèi)存泄漏,界面渲染,h5和自定義控件性能等
6. 自動(dòng)化和持續(xù)集成
雖然以前測(cè)試也都是有自動(dòng)化和持續(xù)集成。但是為什么我要列在這里呢。原因在于移動(dòng)互聯(lián)網(wǎng)的測(cè)試中自動(dòng)化和持續(xù)集成要求很高,沒有持續(xù)集成的項(xiàng)目根本在移動(dòng)互聯(lián)網(wǎng)是沒有辦法很好的運(yùn)作起來的。而移動(dòng)互聯(lián)網(wǎng)目前涉及到的語言和技術(shù)又比較雜,故而對(duì)測(cè)試又是一個(gè)很大的挑戰(zhàn)。
51Testing: 在移動(dòng)互聯(lián)網(wǎng)測(cè)試的過程中,往往會(huì)用到很多測(cè)試工具,目前安卓端和IOS端比較普遍使用的自動(dòng)化工具是什么? 可以給我們推薦點(diǎn)比較實(shí)用的小工具嗎?
陳曄: 這個(gè)問題,工具實(shí)在太多太多了,已經(jīng)列舉不過來了。比較實(shí)用的小工具的話,我倒是可以推薦幾個(gè):
抓包:fiddler,charles,burpsuite
Android自動(dòng)化框架:APPium,Robotium,Calabash
iOS:APPium,Calabash,KIF,GHUnit,instruments
51Testing: 很多手機(jī)測(cè)試人員都會(huì)比較困惑,手機(jī)APP怎么去做壓力測(cè)試比較好?您能說一下您的看法嗎?
陳曄: 手機(jī)APP的壓力測(cè)試,其實(shí)壓力測(cè)試在這個(gè)過程中我覺得分成兩部分。一個(gè)是實(shí)用壓力的方式去測(cè)試APP的穩(wěn)定性,這個(gè)在Android的monkey和iOS中使用js編寫monkey都可以進(jìn)行ANR和NPE的測(cè)試。另外一方面就是和場(chǎng)景緊緊相關(guān)的壓力測(cè)試,這種壓力測(cè)試就需要自動(dòng)化去支持。往往對(duì)應(yīng)用施加壓力之后,查看應(yīng)用的使用流暢度、逼近系統(tǒng)分配內(nèi)存峰值時(shí)候的情況,包括控件是否能夠正常渲染等。
51Testing:對(duì)于APP測(cè)試,您有什么獨(dú)到的區(qū)別于教科書的見解?
陳曄: 我不敢說區(qū)別于教科書,但我能說下區(qū)別于很多人YY中的想法的見解。移動(dòng)APP的測(cè)試現(xiàn)在根本不存在什么全自動(dòng)化,也不存在非常好的錄制回放的工具。要測(cè)試好移動(dòng)APP需要扎實(shí)的技術(shù)基礎(chǔ),任何抱著"有什么工具,有什么框架能夠做自動(dòng)化,做安全,做性能,做壓力測(cè)試"想法的都是流氓。在移動(dòng)APP測(cè)試目前更多的是需要用開源的工具和框架,然后結(jié)合自己團(tuán)隊(duì)的情況以及自己對(duì)于被測(cè)產(chǎn)品的技術(shù)和業(yè)務(wù)理解去二次開發(fā),最后投入到項(xiàng)目團(tuán)隊(duì)和持續(xù)集成中去,這是現(xiàn)在很流行的做法,也是我個(gè)人覺得最好的做法。也許將來會(huì)有好的平臺(tái),好的工具,但是多學(xué)點(diǎn)來豐富自己也不是什么壞事。
51Testing: 聽說您最近也有負(fù)責(zé)公司測(cè)試人員的招募工作,應(yīng)該對(duì)面試方面應(yīng)該也有一定的經(jīng)驗(yàn)了,對(duì)于正在找工作的測(cè)試新人,您有什么面試經(jīng)驗(yàn)要和他們分享嗎?
陳曄: 最近是一直在招聘,基本上這段時(shí)間沒有停過。其實(shí)我覺得移動(dòng)互聯(lián)網(wǎng)的測(cè)試面試與其他可能還是有點(diǎn)差別的,但是注意點(diǎn)還是一樣的。
1. 簡(jiǎn)歷要真實(shí)
不要?jiǎng)硬粍?dòng)就精通,動(dòng)不動(dòng)就各種工具和框架或者語言都往簡(jiǎn)歷上寫,簡(jiǎn)歷上寫的太多未必是好事兒。我建議還是把真實(shí)的情況寫上去比較好。所以不要老抱怨面試官問一些不切實(shí)際的問題,先看看自己簡(jiǎn)歷寫的如何。
2. 技術(shù)要扎實(shí)
不要太浮躁,對(duì)一些技術(shù)和業(yè)務(wù)不能只知其一,覺得了解了一些就很了不起。目前移動(dòng)互聯(lián)網(wǎng)僅僅這樣肯定是不行的。
3. 了解清楚需求以及知道自己要什么
不要只看到公司名字就覺得高大上,僅僅知道公司是不夠的,好好確認(rèn)自己要去的部門、項(xiàng)目、團(tuán)隊(duì)。大公司也有爛部門,小公司也有好項(xiàng)目和好團(tuán)隊(duì)。這些都不是固定的,而是需要自己去了解的。
51Testing: 作為一名有豐富經(jīng)驗(yàn)的測(cè)試員,您對(duì)想從事手機(jī)測(cè)試新人有哪些建議?怎么樣做可以讓新手做的更好,更迅速的成長(zhǎng)為這個(gè)領(lǐng)域的高手?
陳曄: 1. 不要道聽途說。比如什么公司好啦,什么工資高了,什么行業(yè)有前景等。別人說終究就是別人說的,要是真的想了解,那么盡量通過自己去體驗(yàn)去感受去了解,要做到不要聽風(fēng)就是雨。
2. 好好學(xué)習(xí)code基礎(chǔ)。在移動(dòng)互聯(lián)網(wǎng)做測(cè)試,不寫code可以,但是要懂,要會(huì)。否則對(duì)于被測(cè)應(yīng)用的實(shí)現(xiàn)都不了解,還談什么測(cè)試呢?我們有一句話"先學(xué)開發(fā),后學(xué)測(cè)試"
3. 鍛煉自己的學(xué)習(xí)能力。包括看原生文檔,學(xué)習(xí)開源工具和代碼。不要看到英文就退縮,這樣你是無法在移動(dòng)互聯(lián)網(wǎng)的路上走出屬于自己的路的。
以上這些就是一些前提,如果這些前提做不到,那么就不用談后面或者其他的事情了。接著我們談下要怎么做。比如你要開始做android和iOS的應(yīng)用測(cè)試了,那么基本上你要根據(jù)如下的順序。
1). 先看官方文檔中的系統(tǒng)介紹,對(duì)于平臺(tái)有一個(gè)全面的了解
2). 仔細(xì)的查看文檔中和測(cè)試有關(guān)的工具和框架,并自己實(shí)踐(文檔理論上是非常詳細(xì)的)
3). 學(xué)習(xí)相關(guān)平臺(tái)的開發(fā)技術(shù)
4). 仔細(xì)了解自己產(chǎn)品項(xiàng)目的需求
5). 仔細(xì)審視自己產(chǎn)品的代碼(不要說看不到代碼什么的,不看代碼等于瞎子在測(cè)試)
6). 好好看看一些流行框架的原理和實(shí)現(xiàn)
7). 用分層的思想好好設(shè)計(jì)測(cè)試策略
簡(jiǎn)單來講這樣的路線是最好的,目前這些是移動(dòng)互聯(lián)網(wǎng)測(cè)試的基礎(chǔ)要求,代碼能力,編寫腳本能力,靜態(tài)分析能力等。我希望大家了解一點(diǎn),如果你們覺得這些要求很高,那是因?yàn)榇蟛糠秩嗽趪鴥?nèi)長(zhǎng)期低要求或者被叫獸忽悠已經(jīng)習(xí)慣了,當(dāng)拿出正常的要求的時(shí)候,很多人就會(huì)覺得很高。事實(shí)是這只是基礎(chǔ)要求。
51Testing: 由于時(shí)間關(guān)系,本次訪談?wù)浇Y(jié)束,非常感謝陳曄老師抽出寶貴時(shí)間參加我們的訪談和對(duì)小編工作的支持,讓小編對(duì)移動(dòng)互聯(lián)網(wǎng)測(cè)試領(lǐng)域了解了不少,相信這次的內(nèi)容也將會(huì)給測(cè)試員帶來頗多的收益。希望以后能有更多的機(jī)會(huì),能讓您分享測(cè)試心得!
按照常規(guī)的做法,當(dāng)一個(gè)缺陷修復(fù)完畢后,通常會(huì)對(duì)修復(fù)后的代碼進(jìn)行兩種形式的
測(cè)試。首先是確認(rèn)測(cè)試,以驗(yàn)證該修復(fù)程序?qū)嶋H上已經(jīng)修復(fù)了缺陷,二是
回歸測(cè)試,以確保修復(fù)部分本身沒有破壞已有的功能。需要注意的是,當(dāng)新的功能添加到現(xiàn)有的應(yīng)用程序時(shí)也適用這一相同的原理。在添加新功能的情況下,測(cè)試可以驗(yàn)證新功能的
工作是否按要求和設(shè)計(jì)規(guī)范,例如回歸測(cè)試就可以表明,新的代碼并沒有破壞任何現(xiàn)有的功能。
也有可能應(yīng)用程序的新版本同時(shí)包含了修復(fù)先前報(bào)告的缺陷以及具有新的功能。對(duì)于“修復(fù)”部分,我們通常會(huì)有一系列的缺陷的測(cè)試腳本(DTS)用來運(yùn)行以確認(rèn)是否修復(fù),而對(duì)于新的功能,我們將有一系列具體的測(cè)試腳本用來測(cè)試變更控制通知(CCNS) 。
此外,隨著新的功能和更多組件的增加,軟件應(yīng)用程序變得越來越大,回歸測(cè)試包,也就是一個(gè)
測(cè)試用例庫,被開發(fā)并運(yùn)用于每次應(yīng)用程序的新版本發(fā)布。
選擇回歸測(cè)試包的測(cè)試
如先前所述,對(duì)于每個(gè)應(yīng)用軟件的新版本而言,需要執(zhí)行三組測(cè)試集:回歸測(cè)試,特定版本的測(cè)試和缺陷的測(cè)試腳本。選擇測(cè)試用例的回歸測(cè)試包不是一件容易的事。選擇測(cè)試集以及回歸測(cè)試包需要仔細(xì)的思考和注意力。
人們會(huì)認(rèn)為,每一個(gè)為特定版本的測(cè)試而寫的測(cè)試用例將成為回歸測(cè)試包的一部分,并在下個(gè)版本出來后用于執(zhí)行。所以,也就是說,隨著程序代碼越來越多的新版本的出現(xiàn),回歸測(cè)試包會(huì)變得越來越大。如果我們將回歸測(cè)試自動(dòng)化,這并不應(yīng)該是一個(gè)問題,但對(duì)于手動(dòng)執(zhí)行一個(gè)大的回歸測(cè)試包,這可能會(huì)導(dǎo)致時(shí)間上的限制以及新功能可能會(huì)因沒有時(shí)間而無法進(jìn)行測(cè)試。
這些回歸測(cè)試包通常包含覆蓋核心功能的測(cè)試,在整個(gè)應(yīng)用程序的演變過程中都不發(fā)生改變。話雖如此,一些老的測(cè)試用例可能會(huì)不再適用,因?yàn)橛行┕δ芸赡芤驯粍h除,并通過新的功能所取代。因此,回歸測(cè)試包需要定期更新,以反映應(yīng)用程序的更改。
回歸測(cè)試包是來自于針對(duì)早期版本的需求規(guī)格軟件的腳本測(cè)試的組合,也包括隨機(jī)測(cè)試。回歸測(cè)試包應(yīng)在最低限度涵蓋典型的用例場(chǎng)景的基本工作流程。 “最重要的測(cè)試”,即對(duì)很重要的應(yīng)用領(lǐng)域的測(cè)試應(yīng)該總是被包含在回歸測(cè)試包中。例如,一個(gè)銀行應(yīng)用程序應(yīng)該包含對(duì)其安全穩(wěn)健性的測(cè)試,而一個(gè)高訪問量網(wǎng)站的Web應(yīng)用程序則應(yīng)該對(duì)其進(jìn)行性能相關(guān)的測(cè)試案例。
成功的測(cè)試案例,即與應(yīng)用程序早期版本中的缺陷測(cè)試相關(guān)的測(cè)試也是列入回歸測(cè)試包的很好的候選對(duì)象。
自動(dòng)化回歸測(cè)試
在可能情況下,回歸測(cè)試必須自動(dòng)化。用相同的變量和條件一遍又一遍的運(yùn)行相同的測(cè)試,不會(huì)產(chǎn)生任何新的缺陷。重復(fù)的工作會(huì)造成執(zhí)行測(cè)試者的喪失興趣和注意力不集中,可能在執(zhí)行回歸測(cè)試的過程中錯(cuò)失發(fā)現(xiàn)潛在缺陷的機(jī)會(huì)。此外自動(dòng)化回歸測(cè)試的另一個(gè)優(yōu)點(diǎn)是,可以添加多個(gè)測(cè)試用例到該回歸測(cè)試包而不對(duì)花費(fèi)時(shí)間產(chǎn)生太大影響。自動(dòng)回歸測(cè)試包可以連夜執(zhí)行或與手動(dòng)測(cè)試并行運(yùn)行,并能釋放資源。
Reporter.ReportEvent EventStatus, ReportStepName, Details [, in]
Argument
Type
Descrīption
EventStatus
Number or pre-defined constant
狀態(tài)值:
0、或 micPass:將本步驟的運(yùn)行結(jié)果狀態(tài)設(shè)置為“Pass”,并向Result中產(chǎn)生報(bào)告信息。
如果想在報(bào)告中生成“通過”報(bào)告,用本狀態(tài)值。
1、或 micFail: 將本步驟的運(yùn)行結(jié)果狀態(tài)設(shè)置為“Fail”,并向Result中產(chǎn)生報(bào)告信息。當(dāng)腳本中運(yùn)行本語句時(shí),整個(gè)
測(cè)試的結(jié)果狀態(tài)是“fails”。
如果想在報(bào)告中生成“失敗”報(bào)告,用本狀態(tài)值。如果運(yùn)行了本語句,則整個(gè)測(cè)試的狀態(tài)為“Fail”。
2、或 micDone:僅向Result中產(chǎn)生報(bào)告信息,但不影響整個(gè)測(cè)試的結(jié)果狀態(tài)。
如果想在報(bào)告中生成“完成”報(bào)告,用本狀態(tài)值。
3、或 micWarning: S向Result中產(chǎn)生報(bào)告信息,但是不會(huì)中斷測(cè)試的運(yùn)行,也不影響測(cè)試的 pass/fail status。
如果想在報(bào)告中生成“警告”報(bào)告,用本狀態(tài)值。運(yùn)行這個(gè)語句后,整個(gè)測(cè)試結(jié)果狀態(tài)為“Warning”。
ReportStepName
String
將在報(bào)告中顯示的步驟名稱(object name).
Details
String
報(bào)告的詳細(xì)信息。這些信息是本條報(bào)告的“Details”信息。
我裝的是比較新的版本,6.0.5,網(wǎng)上搜到的教程多是針對(duì)4.x版本的,裝6.0.5還是會(huì)碰上不少問題。
主要參考這個(gè)文檔安裝的。但因?yàn)閥um安裝更方便,所以盡量yum安裝
mysql:
yum -y install mysql mysql-server
chkconfig mysqld on
service mysqld start
yum install開頭是失敗。提示GPG key" atomicrocketturtle.com一類的錯(cuò)誤。把/etc/yum.repos.d/automic.repo 移到temp目錄中,然后yum update,再安裝就好了。
為了保險(xiǎn)起見,安裝jdk6,沒有裝jdk7.
yum search jdk|grep 1.6
然后安裝 java-1.6.0-openjdk
tomcat6:
安裝這些
tomcat6,tomcat6-lib,tomcat6-webapps,tomcat6-servlet,tomcat6-javadoc,tomcat6-docs-webapp,tomcat6-jsp,tomcat6-admin-webapps
然后chkconfig,service操作
安裝時(shí)按照 https://confluence.atlassian.com/display/JIRA060/Using+the+JIRA+Configuration+Tool#UsingtheJIRAConfigurationTool-starting
因?yàn)闆]有圖形界面,就借鑒幫助中的圖形界面配置我們的命令行界面。
mysql進(jìn)去
create user jira identified by 'jira';
grant all privileges on jiradb.* to jira@localhost identified by 'jira' with grant option;
flush privileges;
我認(rèn)為mysql是3306的接口,反復(fù)試了幾次,老是失敗。
netstat|grep mysql
原來mysqld的接口不是3306。這樣就成功了,難道3306已經(jīng)被占用了嗎,但是netstat|grep 3306沒有找到。
通過“locate java”和ll可以得到j(luò)ava的home,
/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre
那就設(shè)這個(gè)為JAVA_HOME吧。