#
摘要: Java對Excel表格的操作
目前軟件開發(fā)多采用B/S架構(gòu)。正B/S架構(gòu)可以給軟件的開發(fā)部署帶來很大的便利,但是與此同時這種架構(gòu)也帶來了一些問題,例如Web報表的處理等,在B/S架構(gòu)下,客戶端的開發(fā)并沒有豐富的、互動性能良好的界面組件供開發(fā)人員調(diào)用,而且調(diào)用客戶端機(jī)器上的設(shè)備也很不方便。這些缺陷將會導(dǎo)致B/S架構(gòu)的軟件在客戶端的一些功能開發(fā)陷入困境。
&n...
閱讀全文
1如何將字串 String 轉(zhuǎn)換成整數(shù) int?
A. 有兩個方法:
1). int i = Integer.parseInt([String]); 或
i = Integer.parseInt([String],[int radix]);
2). int i = Integer.valueOf(my_str).intValue();
注: 字串轉(zhuǎn)成 Double, Float, Long 的方法大同小異.
2 如何將整數(shù) int 轉(zhuǎn)換成字串 String ?
A. 有叁種方法:
1.) String s = String.valueOf(i);
2.) String s = Integer.toString(i);
3.) String s = "" + i;
注: Double, Float, Long 轉(zhuǎn)成字串的方法大同小異.
JAVA數(shù)據(jù)類型轉(zhuǎn)換 ynniebo [收藏]
關(guān)鍵字 類型轉(zhuǎn)換
出處
這是一個例子,說的是JAVA中數(shù)據(jù)數(shù)型的轉(zhuǎn)換.供大家學(xué)習(xí)引
package cn.com.lwkj.erts.register;
import java.sql.Date;
public class TypeChange {
public TypeChange() {
}
//change the string type to the int type
public static int stringToInt(String intstr)
{
Integer integer;
integer = Integer.valueOf(intstr);
return integer.intValue();
}
//change int type to the string type
public static String intToString(int value)
{
Integer integer = new Integer(value);
return integer.toString();
}
//change the string type to the float type
public static float stringToFloat(String floatstr)
{
Float floatee;
floatee = Float.valueOf(floatstr);
return floatee.floatValue();
}
//change the float type to the string type
public static String floatToString(float value)
{
Float floatee = new Float(value);
return floatee.toString();
}
//change the string type to the sqlDate type
public static java.sql.Date stringToDate(String dateStr)
{
return java.sql.Date.valueOf(dateStr);
}
//change the sqlDate type to the string type
public static String dateToString(java.sql.Date datee)
{
return datee.toString();
}
public static void main(String[] args)
{
java.sql.Date day ;
day = TypeChange.stringToDate("2003-11-3");
String strday = TypeChange.dateToString(day);
System.out.println(strday);
}
}
JAVA中常用數(shù)據(jù)類型轉(zhuǎn)換函數(shù)
雖然都能在JAVA API中找到,整理一下做個備份。
string->byte
Byte static byte parseByte(String s)
byte->string
Byte static String toString(byte b)
char->string
Character static String to String (char c)
string->Short
Short static Short parseShort(String s)
Short->String
Short static String toString(Short s)
String->Integer
Integer static int parseInt(String s)
Integer->String
Integer static String tostring(int i)
String->Long
Long static long parseLong(String s)
Long->String
Long static String toString(Long i)
String->Float
Float static float parseFloat(String s)
Float->String
Float static String toString(float f)
String->Double
Double static double parseDouble(String s)
Double->String
Double static String toString(Double)
++++++++++++++++++++++++++++++++++++++++++++++++++++++
數(shù)據(jù)類型
基本類型有以下四種:
int長度數(shù)據(jù)類型有:byte(8bits)、short(16bits)、int(32bits)、long(64bits)、
float長度數(shù)據(jù)類型有:單精度(32bits float)、雙精度(64bits double)
boolean類型變量的取值有:ture、false
char數(shù)據(jù)類型有:unicode字符,16位
對應(yīng)的類類型:Integer、Float、Boolean、Character、Double、Short、Byte、Long
轉(zhuǎn)換原則
從低精度向高精度轉(zhuǎn)換
byte 、short、int、long、float、double、char
注:兩個char型運(yùn)算時,自動轉(zhuǎn)換為int型;當(dāng)char與別的類型運(yùn)算時,也會先自動轉(zhuǎn)換為int型的,再做其它類型的自動轉(zhuǎn)換
基本類型向類類型轉(zhuǎn)換
正向轉(zhuǎn)換:通過類包裝器來new出一個新的類類型的變量
Integer a= new Integer(2);
反向轉(zhuǎn)換:通過類包裝器來轉(zhuǎn)換
int b=a.intValue();
類類型向字符串轉(zhuǎn)換
正向轉(zhuǎn)換:因為每個類都是object類的子類,而所有的object類都有一個toString()函數(shù),所以通過toString()函數(shù)來轉(zhuǎn)換即可
反向轉(zhuǎn)換:通過類包裝器new出一個新的類類型的變量
eg1: int i=Integer.valueOf(“123”).intValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Integer對象,然后再調(diào)用這個對象的intValue()方法返回其對應(yīng)的int數(shù)值。
eg2: float f=Float.valueOf(“123”).floatValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Float對象,然后再調(diào)用這個對象的floatValue()方法返回其對應(yīng)的float數(shù)值。
eg3: boolean b=Boolean.valueOf(“123”).booleanValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Boolean對象,然后再調(diào)用這個對象的booleanValue()方法返回其對應(yīng)的boolean數(shù)值。
eg4:double d=Double.valueOf(“123”).doubleValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Double對象,然后再調(diào)用這個對象的doubleValue()方法返回其對應(yīng)的double數(shù)值。
eg5: long l=Long.valueOf(“123”).longValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Long對象,然后再調(diào)用這個對象的longValue()方法返回其對應(yīng)的long數(shù)值。
eg6: char=Character.valueOf(“123”).charValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Character對象,然后再調(diào)用這個對象的charValue()方法返回其對應(yīng)的char數(shù)值。
基本類型向字符串的轉(zhuǎn)換
正向轉(zhuǎn)換:
如:int a=12;
String b;b=a+””;
反向轉(zhuǎn)換:
通過類包裝器
eg1:int i=Integer.parseInt(“123”)
說明:此方法只能適用于字符串轉(zhuǎn)化成整型變量
eg2: float f=Float.valueOf(“123”).floatValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Float對象,然后再調(diào)用這個對象的floatValue()方法返回其對應(yīng)的float數(shù)值。
eg3: boolean b=Boolean.valueOf(“123”).booleanValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Boolean對象,然后再調(diào)用這個對象的booleanValue()方法返回其對應(yīng)的boolean數(shù)值。
eg4:double d=Double.valueOf(“123”).doubleValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Double對象,然后再調(diào)用這個對象的doubleValue()方法返回其對應(yīng)的double數(shù)值。
eg5: long l=Long.valueOf(“123”).longValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Long對象,然后再調(diào)用這個對象的longValue()方法返回其對應(yīng)的long數(shù)值。
eg6: char=Character.valueOf(“123”).charValue()
說明:上例是將一個字符串轉(zhuǎn)化成一個Character對象,然后再調(diào)用這個對象的charValue()方法返回其對應(yīng)的char數(shù)值
前面的章節(jié)里對linux的文件的權(quán)限做了簡單的解釋。現(xiàn)在來看看常見的命令,從簡單的開始:
1 、切換目錄
cd
到/tmp 目錄:cd /tmp
到上層目錄:cd ..
2 、查看當(dāng)前目錄
pwd
3、 創(chuàng)建一個新的文件夾:
mkdir
創(chuàng)建一層目錄:

創(chuàng)建多層目錄:

4 、刪除目錄:
rmdir [-p] 如果需要層級刪除目錄,就需要帶上p(只能刪除空目錄)
5、查詢環(huán)境變量
echo $PATH 或者$PATH
6、切換用戶:
su 用戶名
7、移動文件

仔細(xì)閱讀上面的命令,你會發(fā)現(xiàn)mv還可以對文件進(jìn)行從命名,上面的命令將hellot.txt從a中移動到了b中,并改名為hello1.txt
8、查看文件與目錄
ls
ls -a 目錄名稱:列出目錄中所有的文件
ls -al 目錄名:列出長字符串,包含文件的一些詳細(xì)信息
如果沒有給定目錄名,那么就是當(dāng)前目錄
9、文件的復(fù)制:
cp [-adfilprsu] 源文件 目標(biāo)文件 //將源文件拷貝到目標(biāo)文件
cp src1,src2,... des //將多個源文件拷貝到目的文件夾
cp這個命令非常重要,不同的身份執(zhí)行對命令產(chǎn)生不同的效果,尤其是-a,-p參數(shù),對不同的身份來說,區(qū)別非常大。
例1:
使用root執(zhí)行:

如果我們要將文件的所有的屬性復(fù)制過來,則要加上參數(shù)-a
復(fù)制一個目錄到另外一個目錄 cp -r /src /desc
10 、移除文件或目錄
rm [-fir] 文件或目錄
-f 強(qiáng)制的意思,忽略不存在的文件,不會出現(xiàn)警告信息
-i互動模式:刪除前,會詢問是否刪除
-r :遞歸刪除
這里不再演示,記得之前的rmdir嗎,只能刪除空目錄,所以刪除非空目錄只能使用rm -r
11、文件類容查詢
cat
-b:列出行號
-n:列出行號,包括空白行

cat 是一次性將數(shù)據(jù)顯示到屏幕上,如果想一頁一頁的看怎么辦?
使用more命令
more在運(yùn)行的過程中,你有幾個按鍵可以按:
空格鍵:代表向下翻一頁
Enter:代表向下滾動一行
q:離開more
b:往回翻頁
12 、創(chuàng)建文件
touch
touch a.txt 就會在當(dāng)前目錄下創(chuàng)建a.txt
13、查找文件的命令
whereis ,find
whereis [-bmsu] 文件或目錄名
-b:二進(jìn)制文件
-m:只找在說明文件manual路徑下的問津
-s:只找source源文件
-u:查找不在上述三個選項中的其他特殊文件
whereis ifconfig
下面看看find命令
find [path] [option] [actioin]
查找/home下面屬于gavin的文件
find /home -user gavin
查找系統(tǒng)中不屬于任何人的文件
find / -nouser
查找文件名為passwd的這個文件
find / -name passwd
查找文件類型為socket的文件
find / -type s
14、磁盤和目錄的容量
df:列出文件系統(tǒng)的整體磁盤使用量
du:評估文件系統(tǒng)的磁盤使用量
15 創(chuàng)建鏈接文件
ln [-sf] 源文件 目標(biāo)文件
-s :創(chuàng)建軟連接,如果不加則是硬連接
-f:如果目標(biāo)文件存在,則刪除后再建
[root@localhost test2]# echo 'good'>a.txt
[root@localhost test2]# ls
a.txt
[root@localhost test2]# ln -s a.txt b
[root@localhost test2]# ls
a.txt b
[root@localhost test2]# ll
total 12
-rw-r--r-- 1 root root 5 Aug 8 01:09 a.txt
lrwxrwxrwx 1 root root 5 Aug 8 01:09 b -> a.txt
[root@localhost test2]# echo 'hello'>>b
[root@localhost test2]# cat b
good
hello
[root@localhost test2]# cat a.txt
good
hello
[root@localhost test2]# ln a.txt c
[root@localhost test2]# ll
total 20
-rw-r--r-- 2 root root 11 Aug 8 01:09 a.txt
lrwxrwxrwx 1 root root 5 Aug 8 01:09 b -> a.txt
-rw-r--r-- 2 root root 11 Aug 8 01:09 c
[root@localhost test2]# echo 'bad'>>c
[root@localhost test2]# cat c
good
hello
bad
[root@localhost test2]# cat a.txt
good
hello
bad
[root@localhost test2]# cat b
good
hello
bad
[root@localhost test2]# rm a.txt
rm: remove regular file `a.txt'? y
[root@localhost test2]# cat b
cat: b: No such file or directory
[root@localhost test2]# cat c
good
hello
bad
[root@localhost test2]#
運(yùn)行上面的命令行,相信你對ln的使用會非常清楚的。
15、掛載CD

16、文件壓縮
tar
-c:創(chuàng)建一個壓縮文件
-v:顯示壓縮過程
-f:給出壓縮文件名
-x:解壓文件
-t::查看壓縮包中又哪些文件

linux是一個多用戶,多任務(wù)的操作系統(tǒng),對于每一個文件它的屬性中都包括:文件所有者(owner),文件所屬組(group),其他用戶(other),還必須具備與這三個角色對應(yīng)的讀,寫,執(zhí)行的權(quán)限,如下圖:

在tmp目錄下面有一個a.txt文件,我們通過ls -l命令可以查看其詳細(xì)信息:
-:表示普通文件,d:表示目錄文件,l:鏈接文件,b:設(shè)備文件中可以供存儲的接口設(shè)備,c:設(shè)備文件中串行端口設(shè)備如鍵盤。
由于最前面是-:所以a.txt是普通文件。
再看 rw-r--r--部分,我們將其分為三組,分別對應(yīng)文件所有者,文件所屬組,其他用戶的權(quán)限.
其中r代表讀取權(quán)限,w:代表寫權(quán)限,x:代表執(zhí)行權(quán)限(這里沒出現(xiàn)),-:代表沒有某種權(quán)限。
那對上面的權(quán)限的解釋就是:
owner:可以讀和寫,不能執(zhí)行
group:可以讀取不能寫,不能執(zhí)行
other:可以讀取,不能寫,不能執(zhí)行
第一個root代表文件所有者,第二個root代表文件所屬組
那么現(xiàn)在我如果想修改文件所有者,文件所屬組,文件權(quán)限該怎么做,請繼續(xù)向下閱讀:
chgrp:修改用戶所屬組,chown:修改文件所有者,chmod:修改文件權(quán)限
假設(shè)我的系統(tǒng)中又一個叫g(shù)avin的組(通過/etc/group查看)

如上圖,通過chgrp命令將該文件的group修改為了gavin
下面修改其所有者:

修改其權(quán)限:

chmod 777 a.txt 這個777代表什么?
在linux中使用數(shù)字代表權(quán)限:
r:4 w:2 x:1
r-- =4+0+0=4;
rw- =4+2+0=6;
rwx =4+2+1=7
相信寫到這里大家都應(yīng)該明白了吧。
權(quán)限對于文件和文件夾的意義是不一樣的,
對于文件:
r:代表可以讀取文件的內(nèi)容,w:代表可以修改文件的內(nèi)容,x:可以執(zhí)行這個文件
對于文件夾:
r:可以獲取文件夾中又哪些文件,w:可以添加和刪除文件夾中的內(nèi)容,x:可以進(jìn)入文件夾,
如果某個角色對于一個文件夾的權(quán)限是rw-;
那么他僅僅可以使用ls獲取文件夾中的內(nèi)容,但是不可以使用cd進(jìn)入該文件夾。
文件的權(quán)限告一段落,現(xiàn)在來看看linux中的那些常見目錄中的內(nèi)容:
/bin 系統(tǒng)有很多放置執(zhí)行文件的目錄,但是/bin比較特殊,因為/bin放置的是在單用戶維護(hù)模式下還能夠被操作的命令,在/bin下面的命令可以被root和一般賬戶使用,如:cat,chmod,chown,data,mv,mkdir,cp ,bash等常用命令。
/boot 主要放置開機(jī)使用到的文件
/dev 在linux系統(tǒng)中任何設(shè)備與接口設(shè)備都是以文件的形式存在于這個目錄當(dāng)中,你只要訪問某個文件就相當(dāng)于訪問該設(shè)備
/etc 系統(tǒng)的主要配置文件幾乎都在這個文件夾類。
/home 這是系統(tǒng)默認(rèn)的用戶主文件夾
/lib 系統(tǒng)的函數(shù)庫非常多,二/lib放置的是開機(jī)會使用到的函數(shù)庫
/mnt 如果你想臨時掛在一些外部設(shè)備(光盤)一般建議放置到這個目錄。
/opt 這是給第三方軟件放置的目錄
/root 系統(tǒng)管理員的主文件夾
/tmp 這是讓一般用戶或者正在執(zhí)行的程序放置文件的地方,這個目錄是任何人都可以訪問的,所以你需要定期清理一下,當(dāng)然重要數(shù)據(jù)時不能放到這里來的。
關(guān)于文件權(quán)限的最后一點(diǎn)就是:文件默認(rèn)權(quán)限umask
現(xiàn)在我們已經(jīng)知道如何新建或者改變一個目錄的屬性了,不過你知道當(dāng)你新建一個新的文件或則目錄是,它的默認(rèn)權(quán)限是什么嗎?那就是于umask這東西有關(guān)了,那么umask是在搞什么呢,基本上,umask就是制定目前用戶在新建文件或目錄的時候權(quán)限的默認(rèn)值,如果獲得或設(shè)置umask,方法如下:
#umask 或則 umask -S

(四位數(shù),第一位我們先不管,表示特殊權(quán)限,我們從第二位開始看起)
在默認(rèn)權(quán)限上,文件和目錄是不一樣的,對于一個目錄,x權(quán)限是非常重要的 ,而對于一個文件,x權(quán)限在默認(rèn)是不應(yīng)該有的,因為文件大多是用來存儲數(shù)據(jù)的,所以在linux中,文件的默認(rèn)權(quán)限是666,目錄的默認(rèn)權(quán)限是777
要注意的是umask的分?jǐn)?shù)指的是“默認(rèn)值需要剪掉的權(quán)限”,
所以新建文件時權(quán)限:rw--r--r--
新建目錄:r-xr-xr-x
上一節(jié)初步介紹了什么是單元測試,為什么要做單元測試,以及junit4的初步使用,這里我們接著說一下junit4中的注解。
=============本節(jié)知識點(diǎn)============================
* Error和Failures
* Junit4 Annotation
==================================================================
1. 在講注解之前,先來認(rèn)識 Error和Failures這兩種錯誤有什么不同。
Errors:表示程序本身錯誤
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
int a=8/0; //這一句是有錯誤的
}
運(yùn)行方法,會有一下錯誤提示:

Failures: 是指測試失敗。
@Test
publicvoid testAdd() {
int z=new T().add(5,4); //這里修改了數(shù)值,把4該為3就正確了
assertEquals(8,z);
}
在來運(yùn)行這個方法,看一下錯誤提示:

所以,我們在寫測試程序的時候,要先保證Errors是沒有錯誤的,再來看Failures有沒有錯誤。
2. 下面介紹junit4 的常用注解
-----------------------------------------------------------------------------------------------
* @ Test:測試方法
A) (expected=XXEception.class)
B) (timeout=xxx)
*. @ Ignore: 被忽略的測試方法
*. @Before: 每一個測試方法之前云行。
*. @After : 每一個測試方法之后運(yùn)行。
*. @BefreClass 所有測試開始之前運(yùn)行。
*. @AfterClass 所有測試結(jié)果之后運(yùn)行。
------------------------------------------------------------------------------------------------
下面通過一個測試程序來解釋這些注解含義

package com.junit4.cc.test;
importstatic org.junit.Assert.*;
importstatic org.hamcrest.Matcher.*;
import org.junit.Test;
import com.junit4.cc.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.After;
import org.junit.Ignore;
publicclass TTest {
@BeforeClass //的所有方法運(yùn)行之前運(yùn)行。
publicstaticvoid beforeClass(){
System.out.println("------------beforeClass");
}
@AfterClass //在所有方法運(yùn)行之后運(yùn)行
publicstaticvoid afterClass(){
System.out.println("-------------afterClass");
}
@Before //每個測試方法運(yùn)行之前運(yùn)行
publicvoid before(){
System.out.println("=======before");
}
@After //每個測試方法運(yùn)行之后運(yùn)行
publicvoid after(){
System.out.println("=======after");
}
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
System.out.println("test Run through");
}
@Test ()
publicvoid testdivision(){
System.out.println("in Test Division");
}
@Ignore //表示這個方法是不被運(yùn)行的
@Test
(expected=java.lang.ArithmeticException.class,timeout=100) //timeout表示要求方法在100毫秒內(nèi)運(yùn)行完成,否則報錯
publicvoid testDivide(){
int z =new T().divide(8,2);
}
}

運(yùn)行結(jié)果如下:

標(biāo)記紅星(*)方法在每個方法開始和結(jié)尾都運(yùn)行一次。
標(biāo)記綠星(*)的方法只在所有方法的開始和結(jié)尾運(yùn)行一次。
junit有多種注解,我們常用的也就上面幾種。
這一節(jié)我們將學(xué)習(xí)進(jìn)行批量處理,假如我們有多的測試,怎樣進(jìn)行批量處理,請跟著我做。
---------------------------------------------
假如我們寫了兩個被測程序。如下:
T.java
package com.junit4.cc;
publicclass T {
publicint add(int x ,int y){
return x+y;
}
publicstaticvoid main(String args[]){
int z=new T().add(3,5);
System.out.println(z);
}
}
User.java
package com.junit4.cc;
publicclass User {
public String geName(){
return"劉若英"; //PS:她是我的偶像嘻嘻:)
}
}
------------------------------------測試類-------------------------
下面要對上面的兩個類寫測試類。(關(guān)于測試類的創(chuàng)建的方法,不懂的可以看我的第一篇《junit淺學(xué)筆記一》)
TTest.java 對應(yīng)的是T.java的測試類。
package com.junit4.cc.test;
importstatic org.junit.Assert.*;
import org.junit.Test;
import com.junit4.cc.*;
publicclass TTest {
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
}
}
UserTest.java 對應(yīng)的是User.java
package com.junit4.cc.test;
importstatic org.junit.Assert.*;
import org.junit.Test;
import com.junit4.cc.User;
publicclass UserTest {
@Test
publicvoid testGeName() {
assertEquals(new User().geName(),("劉若英"));
}
}
完成之后的列表如下:

要批量運(yùn)行上面兩個測試類,有兩個方法。
方法一
右鍵點(diǎn)擊測試包“com.junit4.cc.test”--->Run As--->Run Configurations.

這種方式設(shè)置簡單,但靈活度不高,假如有100個測試類。我只想運(yùn)行其中的某幾個測試類。下面看第二中方式。
方法二
方法引入一種“測試套件”的概念,JUnit提供了一種批量運(yùn)行測試類的方法,叫測試套件。
測試套件的寫法需要遵循以下原則:
1. 創(chuàng)建一個空類作為測試套件的入口;
2. 使用注解 org.junit.runner.RunWith 和 org.junit.runners.Suite.SuitClasses 修飾這個空類
3. 將org.junit.runners.Suite作為參數(shù)傳入給注解RunWith,以提示Junit為此類測試使用套件運(yùn)行器執(zhí)行。
4. 將需要放入此測試套件的測試類組成數(shù)組作為注解SuiteClasses的參數(shù)
5. 保證這個空類使用public修飾,而且存在公開的不帶任何參數(shù)的構(gòu)造函數(shù)
下面在測試包(com.junit4.cc.test)下面創(chuàng)建一個測試類,內(nèi)容如下:
AllTest.java
package com.junit4.cc.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
TTest.class,
UserTest.class //這里自由加入需要運(yùn)行的測試類
})
publicclass AllTest {
}
創(chuàng)建之后的列表:

運(yùn)行AllTest.java的結(jié)果(這里,兩個方法的運(yùn)行結(jié)果是一樣的):

ps:關(guān)于兩種方式的比較,第一種方法簡單,只用選擇測試包,就可以批量運(yùn)行里面的所有測試程序。第二種方式還有重新創(chuàng)建一個測試類,但它非常靈活,只用在這個類中加入需要運(yùn)行的類就可以靈活的運(yùn)行需要測試的類。
JUnit是一個回歸測試框架(regression testing framework)。Junit測試是程序員測試,即所謂白盒測試,因為程序員知道被測試的
軟件如何(How)完成功能和完成什么樣(What)的功能。Junit是一套框架,繼承TestCase類,就可以用Junit進(jìn)行自動測試了。
雖然大多情況下他是程序員的活,但作為測試人員還是有必要了解一下,畢竟也是測試工作,提高自己人技術(shù),擴(kuò)展思想是主要,邊學(xué)邊做筆記,這樣學(xué)過的東西才不會忘記,嘻嘻~!
========學(xué)習(xí)環(huán)境=================
java編輯器: Eclipse SDK 3.5.6
junit測試包:Eclipse中自帶了junit 4 測試包
=================================
1.我們打開eclipse 創(chuàng)建一個工程名字為:Junit4,
創(chuàng)建一個包,命名為:com.junit4.cc ,
包下面創(chuàng)建一個類 T
代碼如下:
package com.junit4.cc;
publicclass T {
publicint add(int x ,int y){
return x+y;
}
}
我們?nèi)绾蝸碜鰷y試,當(dāng)然了,上面的代碼一眼就可以看出結(jié)果,需要測試么,我們這里只是想說明問題,如果我們不用測試框架,我們會用寫一個main方法對上面的代碼進(jìn)行驗證。全部代碼如下。
package com.junit4.cc;
publicclass T {
publicint add(int x ,int y){
return x+y;
}
publicstaticvoid main(String args[]){
int z=new T().add(3,5); //向T類傳遞兩個參數(shù)3和5
System.out.println(z); //打印z進(jìn)行查看3和5是否做了加法運(yùn)算
}
}
云行上面的代碼,通過查看結(jié)果來判斷add方法是否正確。
---------------------------------------------------------------------------
上面的單元測試有很多弊端:
@ 需要花費(fèi)很多的時間來寫測試代碼
@ 測試代碼不可重用,一段測試代碼對應(yīng)一段被測代碼。被測代碼變,測試代碼就沒用了
@ 無法同時運(yùn)行多個測試代碼。假如有一百個被測試代碼,要一個一個的運(yùn)行測試代碼,用肉眼觀察結(jié)果,效率低還容易出錯。
這是我簡單總結(jié)的幾個缺點(diǎn)。
---------------------------------------------------------------------------
2. 那么我們就要使用單元測試框架來提交效率。
下面我們就使用eclipse來創(chuàng)建一個測試。還是測試上面的代碼為例子。
為了查看更加清晰,我們一般將測試代碼與被測試的代碼放在不同的包下面。
我們在Junit工程下面重新創(chuàng)建一個包,命名為:com.junit4.cc.test
----------------------------
創(chuàng)建一個測試類:TTest
注意:這里要創(chuàng)建的是一個測試類:在com.junit4.cc.test包上面右鍵點(diǎn)擊-->new-->Junit test Case

點(diǎn)擊“Next”會讓你選擇要測試的方法,選擇后點(diǎn)擊“Finish”則完成創(chuàng)建。
創(chuàng)建完成如下圖:

TTest.java代碼如下:
package com.junit4.cc.test;
importstatic org.junit.Assert.*;
import org.junit.Test;
import com.junit4.cc.*;
publicclass TTest {
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
}
}
3. 如果我們想要真正運(yùn)行TTest.java這個測試類,還要對這個工程引入junit測試包。
右鍵點(diǎn)擊工程(junit4)--->Properties

點(diǎn)擊“next ” 按鈕,celipse提供junit3和junit4兩個測試包,我們選擇junit4 點(diǎn)擊“finish”就將測試包引入。
4. 下面來運(yùn)行我們TTest.java測試代碼。

看到我們左側(cè)的綠色滾動條,說明我們的被代碼是沒有問題。
你可以試著修改下面代碼的參數(shù):
int z=new T().add(5,3);
assertEquals(8,z); //將5、3、8等數(shù)字任意修改,查看綠色滾動條的顏色,給出的提示是什么?
上一節(jié)初步介紹了什么是單元測試,為什么要做單元測試,以及junit4的初步使用,這里我們接著說一下junit4中的注解。
=============本節(jié)知識點(diǎn)============================
* Error和Failures
* Junit4 Annotation
==================================================================
1. 在講注解之前,先來認(rèn)識 Error和Failures這兩種錯誤有什么不同。
Errors:表示程序本身錯誤
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
int a=8/0; //這一句是有錯誤的
}
運(yùn)行方法,會有一下錯誤提示:

Failures: 是指測試失敗。
@Test
publicvoid testAdd() {
int z=new T().add(5,4); //這里修改了數(shù)值,把4該為3就正確了
assertEquals(8,z);
}
在來運(yùn)行這個方法,看一下錯誤提示:

所以,我們在寫測試程序的時候,要先保證Errors是沒有錯誤的,再來看Failures有沒有錯誤。
2. 下面介紹junit4 的常用注解
-----------------------------------------------------------------------------------------------
* @ Test:測試方法
A) (expected=XXEception.class)
B) (timeout=xxx)
*. @ Ignore: 被忽略的測試方法
*. @Before: 每一個測試方法之前云行。
*. @After : 每一個測試方法之后運(yùn)行。
*. @BefreClass 所有測試開始之前運(yùn)行。
*. @AfterClass 所有測試結(jié)果之后運(yùn)行。
------------------------------------------------------------------------------------------------
下面通過一個測試程序來解釋這些注解含義

package com.junit4.cc.test;
importstatic org.junit.Assert.*;
importstatic org.hamcrest.Matcher.*;
import org.junit.Test;
import com.junit4.cc.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.After;
import org.junit.Ignore;
publicclass TTest {
@BeforeClass //的所有方法運(yùn)行之前運(yùn)行。
publicstaticvoid beforeClass(){
System.out.println("------------beforeClass");
}
@AfterClass //在所有方法運(yùn)行之后運(yùn)行
publicstaticvoid afterClass(){
System.out.println("-------------afterClass");
}
@Before //每個測試方法運(yùn)行之前運(yùn)行
publicvoid before(){
System.out.println("=======before");
}
@After //每個測試方法運(yùn)行之后運(yùn)行
publicvoid after(){
System.out.println("=======after");
}
@Test
publicvoid testAdd() {
int z=new T().add(5,3);
assertEquals(8,z);
System.out.println("test Run through");
}
@Test ()
publicvoid testdivision(){
System.out.println("in Test Division");
}
@Ignore //表示這個方法是不被運(yùn)行的
@Test
(expected=java.lang.ArithmeticException.class,timeout=100) //timeout表示要求方法在100毫秒內(nèi)運(yùn)行完成,否則報錯
publicvoid testDivide(){
int z =new T().divide(8,2);
}
}

運(yùn)行結(jié)果如下:

標(biāo)記紅星(*)方法在每個方法開始和結(jié)尾都運(yùn)行一次。
標(biāo)記綠星(*)的方法只在所有方法的開始和結(jié)尾運(yùn)行一次。
junit有多種注解,我們常用的也就上面幾種。
檢查點(diǎn):簡單的來理解一下,上一章講到,我們對用戶名和密碼進(jìn)行了參數(shù)化,那么怎樣來判斷jmeter有沒有正確調(diào)用test.dat里面的文件呢。當(dāng)然,我們可以從結(jié)果圖表中查看。但我還是想在“登錄”這個地方進(jìn)行一下檢查。
jmeter里面的檢查點(diǎn)通過添加斷言來完成。
1.
右鍵點(diǎn)擊我們的“登錄”頁面---->添加---->斷言---->響應(yīng)斷言

來設(shè)置一下斷言頁面,我們想斷言什么呢?調(diào)用的用戶名和密碼是不是我們test.dat文件里的用戶名和密碼,怎樣來進(jìn)行呢。
3.
這里我們需要分別準(zhǔn)備兩個文件,一個放用戶名,一個放密碼。

下面編寫函數(shù)來調(diào)用這兩個文件,如何編寫先看我上一篇文章。
在響應(yīng)斷言頁面添加兩個“模式”

(第三步還有一種方法,直接調(diào)用原來test.dat的數(shù)據(jù)進(jìn)行檢查,我試了半天一直失敗,不知道原因在哪兒?)
4.
添加一個斷言結(jié)果
右鍵點(diǎn)擊我們的“登錄”頁面---->添加---->監(jiān)聽器---->斷言結(jié)果
還可以再添加一個“查看結(jié)果樹” 右鍵點(diǎn)擊我們的“登錄”頁面---->添加---->監(jiān)聽器---->查看結(jié)果樹

在線程組中設(shè)置5個用戶,點(diǎn)擊運(yùn)行運(yùn)行。
查看斷言結(jié)果:

查看結(jié)果做:

好了,檢查點(diǎn)添加成功!
集合點(diǎn):簡單來理解一下,雖然我們的“性能測試”理解為“多用戶并發(fā)測試”,但真正的并發(fā)是不存在的,為了更真實的實現(xiàn)并發(fā)這感念,我們可以在需要壓力的地方設(shè)置集合點(diǎn),
還拿那個用戶和密碼的地方,每到輸入用戶名和密碼登錄的地方,所有的虛擬用戶都相互之間等一等,然后,一起訪問。(紅軍排長說:等一等!大家一起沖啊!這樣給敵人的壓力是很大的。嘻嘻!)
1.
接著之前創(chuàng)建的腳本,右鍵點(diǎn)擊 step1---->定時器---->Synchronizing Timer

這樣子就添加了一個“集合點(diǎn)”,下面來設(shè)置一下集合點(diǎn)。

2.
我們添加完之后的列表是這個樣子的,

發(fā)現(xiàn)了沒,我們集合點(diǎn)的位置不對,應(yīng)該在登錄的前面才對。怎么弄呢?
點(diǎn)擊“synchronizing Timer”拖動到“登錄”面前的位置,不要松鼠標(biāo)的左鍵,再點(diǎn)擊鼠標(biāo)的右鍵,選擇在“之前插入”---有點(diǎn)難噢,慢慢來!

OK!!