日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java单元测试】如何进行单元测试、异常测试、参数化测试、超时测试、测试多线程

發布時間:2024/2/28 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java单元测试】如何进行单元测试、异常测试、参数化测试、超时测试、测试多线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Junit單元測試的步驟

(1)新建一個單元測試

(2)選擇位置

(3)選擇需要測試的方法

(4)是否將Junit 4添加到ClassPath中

(5)自動生成的測試類

(6) 然后就可以編寫單元測試了

單元測試的編寫

(1)Assert斷言

package cn.hanquan.junit;import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;class CalcTest {@Testvoid testAdd() {assertEquals(3, new Calc().add(1, 2));assertEquals(30, new Calc().add(10, 20));assertEquals(159, new Calc().add(150, 9));} }
(2)Junit Fixture:Junit4 @Before、@After的使用

初始化測試資源稱為Fixture

@Before:創建初始化對象,在執行所有每一個@Test之前都會執行一次。如is = new FileInputStream()
@After:銷毀@Before創建的測試對象,在執行所有每一個@Test之后都會執行一次。如is.close()
@BeforeClass:在其中初始化非常耗時的對象,如:數據庫的連接
@AfterClass:清理@BeforeClass創建的資源,比如:斷開數據庫連接

注意:在JUnit5中,@Before @After 注解不執行

官方文檔:https://junit.org/junit5/docs/current/user-guide/#migrating-from-junit4-tips


@Before 和@After 被 @BeforeEach 和@AfterEach給替代了。

還有一些其他的的注解也被替代了。

在JUnit5的環境下寫了@Before @After , 講道理 IDE應該提醒 該注解已經不存在, 然而Eclipse并沒有這樣的提示。


代碼示例

被測試的類Calc.java

package cn.hanquan.junit;public class Calc {public Calc() {}public int add(int a, int b) {System.out.println(a + "+" + b + "=" + (a + b));return a + b;} }

測試類CalcTest

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import org.junit.After; import org.junit.Before; import org.junit.Test;public class CalcTest {Calc c;@Beforepublic void initialize() {System.out.println(">>>>>>> initializing >>>>>>>");c = new Calc();}@Testpublic void testAdd1() {assertEquals(3, c.add(1, 2));assertEquals(30, c.add(10, 20));assertEquals(159, c.add(150, 9));}@Testpublic void testAdd2() {assertEquals(4, c.add(2, 2));assertEquals(36, c.add(13, 23));assertEquals(1000, c.add(-3000, 4000));}@Afterpublic void destroy() {System.out.println("<<<<<<<<< cleaning <<<<<<<<<\n");} }

測試結果

輸出

>>>>>>> initializing >>>>>>> 1+2=3 10+20=30 150+9=159 <<<<<<<<< cleaning <<<<<<<<<>>>>>>> initializing >>>>>>> 2+2=4 13+23=36 -3000+4000=1000 <<<<<<<<< cleaning <<<<<<<<<

(3)測試拋出的異常是否符合預期

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import org.junit.After; import org.junit.Before; import org.junit.Test;public class CalcTest {Calc c;@Beforepublic void initialize() {System.out.println(">>>>>>> initializing >>>>>>>");c = new Calc();}@Test // 測試輸出是否符合預期public void testAdd2() {assertEquals(20, c.divide(100, 5));}@Test(expected = ArithmeticException.class) // 針對異常進行的測試public void testAdd3() {c.divide(8, 0);}@Afterpublic void destroy() {System.out.println("<<<<<<<<< cleaning <<<<<<<<<\n");} }

(4)參數化測試:一次運行多個測試


JUnit參數化測試的五個步驟:

(1)為準備使用參數化測試的測試類指定特殊的運行器 org.junit.runners.Parameterized

(2)為測試類聲明幾個變量,分別用于存放期望值和測試所用數據

(3)為測試類聲明一個帶有參數的公共構造函數,并在其中為第二個環節中聲明的幾個變量賦值

(4)為測試類聲明一個使用注解 org.junit.runners.Parameterized.Parameters 修飾的,返回值為 java.util.Collection 的公共靜態方法,并在此方法中初始化所有需要測試的參數對

(5)編寫測試方法,使用定義的變量作為參數進行測試。

示例代碼

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays; import java.util.Collection;import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters;/*** 使用Junit進行參數化測試的步驟* * @author Buuug**/ //(1)測試類指定特殊的運行器org.junit.runners.Parameterized @RunWith(Parameterized.class) public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}// (2)為測試類聲明幾個變量,分別用于存放期望值和測試所用數據。此處我只放了測試所有數據,沒放期望值。private int n1;private int n2;private int result;// (3)為測試類聲明一個帶有參數的公共構造函數,并在其中為第二個環節中聲明的幾個變量賦值。public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}// (4)為測試類聲明一個使用注解 org.junit.runners.Parameterized.Parameters 修飾的,返回值為// java.util.Collection 的公共靜態方法,并在此方法中初始化所有需要測試的參數對。@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 1000000, 333333, 888888 }, { 56, 8, 7 }, { 55, 55, 1 },{ 12, 6, 2 }, { 21, 10, 2 }, { 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}// (5)步驟五:編寫測試方法,使用定義的變量作為參數進行測試。@Testpublic void testAdd() {assertEquals(result, c.divide(n1, n2));}@Afterpublic void aft() {System.out.println("After\n");} }

測試結果

第8個未通過,是故意寫錯的。

(5)超時測試:設定運行時間限制,測試是否運行時間過長

在50行加一個@Test(timeout = 1)就行了。

一開始想通過Thread.sleep(1000);這種形式拖延時間,但是拋出了ThreadInterrupted異常,(沒有具體去了解原因),然后我又在@Test的方法里加了一個Lambda表達式開啟的多線程,結果開啟之后,不管sleep多長也沒有影響了,都可以在限定時間內結束,我尋思著是不是要join一下才可以。(后來加了Join,確實如此。)

我在被測試的類上面加了一些無用的循環拖延時間,然后把時間限定設置為1ms。看看效果吧:

示例代碼1:沒有使用多線程,只是加了沒用的循環拖延時間

package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays; import java.util.Collection;import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters;/*** 使用Junit進行參數化測試的步驟* * @author Buuug**/ @RunWith(Parameterized.class) public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}private int n1;private int n2;private int result;public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 1000000, 333333, 888888 }, { 56, 8, 7 }, { 55, 55, 1 },{ 12, 6, 2 }, { 21, 10, 2 }, { 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}@Test(timeout = 1) // 設置超時時間public void testAdd() {assertEquals(result, c.divide(n1, n2));}@Afterpublic void aft() {System.out.println("After\n");} }

測試結果

示例代碼2:使用多線程sleep模擬運行耗時,記得join一下主線程,否則都來不及計算就完成了

  • CalcTest.java單元測試:時間限制為501ms。
package cn.hanquan.junit;import static org.junit.Assert.assertEquals;import java.util.Arrays; import java.util.Collection;import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters;/*** 使用Junit進行參數化測試的步驟* * @author Buuug**/ @RunWith(Parameterized.class) public class CalcTest {Calc c;@Beforepublic void bef() {System.out.println("Before");c = new Calc();}private int n1;private int n2;private int result;public CalcTest(int n1, int n2, int result) {super();this.n1 = n1;this.n2 = n2;this.result = result;}@Parameterspublic static Collection<Object[]> data() {return Arrays.asList(new Object[][] { { 4, 2, 2 }, { 9, 3, 3 }, { -100, 25, -4 }, { 88, 2, 44 }, { 25, 5, 5 },{ 72, 8, 9 }, { 42, 6, 7 }, { 1, 1, 1 }, { 56, 8, 7 }, { 55, 55, 1 }, { 12, 6, 2 }, { 21, 10, 2 },{ 70, 20, 3 }, { 45, 15, 3 }, { 46, 15, 3 }, { 47, 3, 15 }, { 2, 1, 2 } });}@Test(timeout = 1000) // 設置超時時間public void testAdd() {Thread t = new Thread(() -> { // ()表示的是函數的參數,這里無參assertEquals(result, c.divide(n1, n2));});t.start();try {t.join();// join} catch (InterruptedException e) {e.printStackTrace();}}@Afterpublic void aft() {System.out.println("After\n");} }
  • 被測試的類:Calc,里面Thread.sleep(500);。由于時間限制為501ms,因此僅空余出1ms給它做計算。
package cn.hanquan.junit;public class Calc {public Calc() {}public int divide(int a, int b) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(a + "/" + b + "=" + (a / b));return a / b;} }

運行結果:部分未通過

那個拋出java.lang.InterruptedException異常的,是因為沒有在限制時間內運行完畢,被打斷了吧?(待解決,暫時沒有深入研究)

總結

以上是生活随笔為你收集整理的【Java单元测试】如何进行单元测试、异常测试、参数化测试、超时测试、测试多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。