《软件工程》实验报告——软件测试
一、實驗目的
掌握結構化分析與設計方法
掌握JUnit的用法;
掌握白盒測試中路徑覆蓋的測試用例設計;
掌握黑盒測試中等價類方法;
二、實驗內容
1. 某證券公司為了方便提供證券交易服務,欲開發一證券交易平臺。該平臺接收客戶命令信息,可執行以下主要功能:
(1)登錄。輸入用戶名、密碼及校驗碼信息,登錄證券交易平臺。
(2)開戶。如果是新客戶,需先提交開戶信息,進行開戶,并將客戶信息存入客戶記錄中,賬戶信息(余額等)存入賬戶記錄中;
(3)存款。客戶可以向其賬戶中存款,根據存款金額修改賬戶余額;
(4)取款。客戶可以從其賬戶中取款,根據取款金額修改賬戶余額;
(5)證券交易。客戶進行證券交易,將交易信息存入交易記錄中;
(6)查詢交易。平臺從交易記錄中讀取交易信息,將交易明細返回給客戶。。
該平臺采用結構化分析方法,畫出第1層的數據流圖如下圖所示(有簡化):
判斷該信息流屬于變換流還是事務流,并將該數據流圖映射為程序結構,畫出程序結構圖。
事務流
2. 進行測試驅動的開發
測試驅動開發,英文全稱Test-Driven Development,簡稱TDD,是一種不同于傳統軟件開發流程的新型的開發方法。它要求在編寫某個功能的代碼之前先編寫測試代碼,然后只編寫使測試通過的功能代碼,通過測試來推動整個開發的進行。這有助于編寫簡潔可用和高質量的代碼,并加速開發過程。
測試驅動開發過程可分為:1)分析需求;2)設計測試用例;3)開發測試代碼;4)開發功能代碼;5)運行測試,據此修改代碼,直到全部通過。
本實驗要求按照測試驅動的開發的過程進行一個類的開發。已提供一個類Point2d的源代碼。要求編寫另一個類Rect,通過左上角點和寬度、高度定義一個長方形(認為它的邊分別平行于x和y軸)。要求該類具備:
1)無參構造方法,默認左上角點在(0,0),寬度、高度均為1。
2)單參數構造方法,接收Point2d參數作為左上角點。寬度、高度默認為1。
3)三參數構造方法,接收Point2d參數及兩個double值,分別設置其左上角點與寬度、高度。
4)能夠計算長方形面積。
5)能夠判斷某個點是位于長方形內(含在邊上)、或其外。
為此,可按照以下步驟進行開發:
1)建立一個空的Rect類;
2)右鍵點擊Rect類,選擇NewàJunit Test Case,在對話模式選擇:
建立一個測試用例RectCreationTest,用于測試Rect的構造方法。
3)第一個測試可寫成:??????
@Testpublic void test() {Rect r = new Rect();assertNotEquals(p, null);Point2d p = r.getTopleft();assertEquals(r.getWidth(), 1.0, 1.0e-6);assertEquals(r.getHeight(), 1.0, 1.0e-6);}即用于測試無參構造方法所得對象,默認左上角點在(0,0),寬度、高度均為1。
4)運行測試,Run AsàJunit Test,不通過。
5)開發功能代碼,即寫上無參構造方法。
6)再次運行測試,直至通過。至此可保證無參構造方法已編寫完畢。
?????? 按照上述過程,將上面要求的其余5項功能按照測試驅動開發的方式編寫完成。
Point2d類
package io.shentuzhigang.demo.design.tdo;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:40*/public class Point2d {private double x;private double y;public Point2d(){this(0, 0);}public Point2d(double x, double y){this.x = x;this.y = y;}public double getX() {return x;}public void setX(double x) {this.x = x;}public double getY() {return y;}public void setY(double y) {this.y = y;}}Rect類
package io.shentuzhigang.demo.design.tdo;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:41*/ public class Rect {private Point2d topLeftPoint;private int width;private int height;public Rect() {this(new Point2d(0,0),1,1);}public Rect(Point2d topLeftPoint) {this(topLeftPoint,1,1);}public Rect(Point2d topLeftPoint, int weight, int height) {this.topLeftPoint = topLeftPoint;this.width = weight;this.height = height;}public double area(){return width * height;}public boolean contain(Point2d point){return topLeftPoint.getX()<=point.getX() && point.getX()<=topLeftPoint.getX()+ width&& topLeftPoint.getY()<=point.getY() && point.getY()<=topLeftPoint.getY()+height;}public Point2d getTopLeftPoint() {return topLeftPoint;}public void setTopLeftPoint(Point2d topLeftPoint) {this.topLeftPoint = topLeftPoint;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;} }RectCreationTest類?
package io.shentuzhigang.demo.design.tdo;import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:51*/ public class RectCreationTest {@Testpublic void test() {Rect r = new Rect();assertNotEquals(r, null);Point2d p = r.getTopLeftPoint();assertEquals(r.getWidth(), 1.0, 1.0e-6);assertEquals(r.getHeight(), 1.0, 1.0e-6);}}?3. 有以下程序(其中的操作并沒有什么具體意義,僅用于演示)
基于JUnit,針對以下程序設計測試用例,滿足路徑覆蓋標準。
import java.awt.Point; public class Path {public static Point Coverage(int a, int b, int c){Point p = new Point();int x = 5;int y = 7;if(a>b && b>c){a += 1;x += 6;if(a==10 || b>20){b += 1;x = y+4; }if(a<10 || c==20){b += 2;y = 4;}a = a + b + 1;y = x + y;}if(a>5 || c<10){b = c + 5;x += 1;}p.x = x;p.y = y;return p;} }自行畫出程序流圖,如教材P329。計算獨立路徑數量,進而設計基本路徑測試所需的測試用例:
| 序號 | 測試用例描述 | 輸入參數 | 期望輸出 | ||
| a | b | c | |||
| 1 | 基本路徑測試1 | ? | ? | ? | ? |
| 2 | 基本路徑測試2 | ? | ? | ? | ? |
| 3 | 基本路徑測試3 | ? | ? | ? | ? |
| 4 | ? | ? | ? | ? | ? |
| 5 | ? | ? | ? | ? | ? |
| ? | ? | ? | ? | ? | ? |
?
分析:9個區域,8個謂詞節點,路徑條數為9。
| 序號 | 測試用例描述 | 輸入參數 | 期望輸出 | ||
| a | b | c | |||
| 1 | 基本路徑測試1 | 9 | 8 | 7 | (12,18) |
| 2 | 基本路徑測試2 | 9 | 7 | 8 | (6,7) |
| 3 | 基本路徑測試3 | 10 | 5 | 5 | (6,7) |
| 4 | 基本路徑測試4 | 4 | 3 | 20 | (5,7) |
| 5 | 基本路徑測試5 | 23 | 21 | 20 | (12,15) |
| 6 | 基本路徑測試6 | 10 | 9 | 8 | (12,18) |
| 7 | 基本路徑測試7 | 6 | 8 | 10 | (6,7) |
| 8 | 基本路徑測試8 | 1 | 5 | 9 | (6,7) |
| 9 | 基本路徑測試9 | 1 | 5 | 10 | (5,7) |
4. 設計一個靜態方法,接收一個字符串,判斷該字符串是否為一個格式正確的電話號碼。所謂正確格式,有以下規則:
1)如果含3位數值,首位需為1;(110等)
2)如果含8位數值,首位不為0;(本地座機號碼)
3)如果含11位數值,首位需為1(手機號碼)或0(北京等地座機號碼);
4)如果含12位數值,首位需為0;(杭州等地座機號碼,第5位不檢測)
(國外號碼等情況不考慮)
請結合等價類方法給出該方法的測試用例,并基于JUnit,寫出測試類。
方法:
1)等價類分為:
-
有效等價類:是指對于程序的規格說明來說,是合理的,有意義的輸入數據構成的集合。
-
無效等價類:是指對于程序的規格說明來說,是不合理的,無意義的輸入數據構成的集合。
2)確立等價類劃分原則
原則1:若規定了取值范圍,或輸入值的個數,則可以確立一個有效等價類和兩個無效等價類。
例:程序對輸入條件的要求是:…輸入數是從1到999…
則? 有效等價類是:1≦輸入數≦999;
兩個無效等價類是:輸入數〈1 或 輸入數>999
原則2:如果規定了輸入數據的一組值,而且程序要對每種輸入數據分別處理,則可為每種輸入值確立一個有效等價類,此外針對這組值確立一個無效等價類,它是所有不允許的輸入值的集合。
例:教師上崗方案中規定對教授、副教授、講師和助教分別計算分數,做相應的處理。因此可以確定4個有效等價類為教授、副教授、講師和助教,一個無效等價類,它是所有不符合以上身分的人員的輸入值的集合。
原則3:若規定了輸入值的集合,或者是規定了“必須如何”的條件,則可確立一個有效等價類和一個無效等價類。
例:某種語言對變量標識符規定必須“以字母打頭”,則所有以字母打頭的構成有效等價類,而不以字母打頭的歸于無效等價類。
原則4:如果規定輸入數據為整型,則可劃分出正整數、零和負整數三個有效類,其他數據為無效類。
原則5:如果程序處理對象是表格,則應使用空表、含一項和多項的表。
3)在確立了等價類之后,建立等價類表,列出所有劃分出的等價類。
例如:
4)設計測試用例,覆蓋所有的有效等價類組合,和所有的無效等價類組合。
| 序號 | 測試用例描述 | 輸入參數 | 期望輸出 | 覆蓋范圍 | ||
| 位數 | 首位 | 用例 | ||||
| 1 | 有效等價類 | 3 | 1 | 110 | true | 1,5,8 |
| 2 | 無效等價類 | 3 | 2 | 222 | false | 2 |
| ? | …… | ? | ? | ? | ? | 3 |
5)Junit測試類:
靜態方法
package io.shentuzhigang.demo.design;import java.util.regex.Pattern;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 16:24*/ public class PhoneNumber {public static boolean check(String s){Pattern pattern = Pattern.compile("^[\\d]*$");if(pattern.matcher(s).matches()){if(s.length()==3){return s.startsWith("1");}else if(s.length()==8){return s.startsWith("0");}else if(s.length()==11){return s.startsWith("1") || s.startsWith("0");}else if(s.length()==12){return s.startsWith("0");}}return false;} }等價類表
| 輸入等價類 | 合理等價類 | 不合理等價類 |
| 電話號碼 | ①首位為1的3位數字字符 ②首位為0的8位數字字符 ③首位為1或0的11位數字字符 ④首位為0的12位數字字符 | ⑤有非數字字符 ⑥位數不合法 ⑦首位不合法 |
測試用例
| 序號 | 測試用例描述 | 輸入參數 | 期望輸出 | 覆蓋范圍 | ||
| 位數 | 首位 | 用例 | ||||
| 1 | 有效等價類 | 3 | 1 | 110 | true | 1,5,7 |
| 2 | 無效等價類 | 3 | 2 | 222 | false | 1,7 |
| 3 | 有效等價類 | 8 | 0 | 01111111 | true | 2 |
| 4 | 無效等價類 | 8 | 1 | 11111111 | false | 2 |
| 5 | 有效等價類 | 11 | 1 | 11111111111 | true | 3 |
| 6 | 有效等價類 | 11 | 0 | 01111111111 | true | 3 |
| 7 | 無效等價類 | 11 | 1 | 1111111a110 | false | 3,5 |
| 8 | 無效等價類 | 11 | 0 | 01111111-110 | false | 3,5 |
| 9 | 有效等價類 | 12 | 0 | 011111111111 | true | 4 |
| 10 | 無效等價類 | 12 | 1 | 111111111111 | false | 4 |
| 11 | 無效等價類 | 1 | 1 | 1 | false | 6 |
| 12 | 無效等價類 | 7 | 1 | 1111111 | false | 6 |
| 13 | 無效等價類 | 8 | 1 | 101011a0 | false | 2,5 |
Junit測試類
package io.shentuzhigang.demo.design;import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.platform.commons.annotation.Testable;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 17:06*/ @Testable public class PhoneNumberTest{@Testpublic void testCheckPhoneNumber1(){Assertions.assertTrue(PhoneNumber.check("110"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber2(){Assertions.assertFalse(PhoneNumber.check("222"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber3(){Assertions.assertTrue(PhoneNumber.check("01111111"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber4(){Assertions.assertFalse(PhoneNumber.check("11111111"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber5(){Assertions.assertTrue(PhoneNumber.check("11111111111"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber6(){Assertions.assertTrue(PhoneNumber.check("01111111111"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber7(){Assertions.assertFalse(PhoneNumber.check("1111111a110"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber8(){Assertions.assertFalse(PhoneNumber.check("01111111-110"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber9(){Assertions.assertTrue(PhoneNumber.check("011111111111"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber10(){Assertions.assertTrue(PhoneNumber.check("011111111111"), "電話號碼合法");}@Testpublic void testCheckPhoneNumber11(){Assertions.assertFalse(PhoneNumber.check("1"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber12(){Assertions.assertFalse(PhoneNumber.check("1111111"), "電話號碼不合法");}@Testpublic void testCheckPhoneNumber13(){Assertions.assertFalse(PhoneNumber.check("101011a0"), "電話號碼不合法");} }測試結果
參考文章
Junit4單元測試的基本用法
Junit3 單元測試 用等價類測試電話號碼
總結
以上是生活随笔為你收集整理的《软件工程》实验报告——软件测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《操作系统》实验报告——主存空间的分配与
- 下一篇: 数据库——关系数据库——交通违规处罚通知