1. 程式人生 > >Java測試框架

Java測試框架

前言

在專案開發過程中必不可少的會用到測試框架來檢查自己的程式碼邏輯,可能大多數人和我一樣從來沒有怎麼重視過測試程式碼,認為測試程式碼存在與否的意義不大。但是,看過很多大牛的專案後,發現他們寫的專案中測試用例的程式碼遠多於實際程式碼。所以,為了向大牛們看齊,最近又重新學習了一波之前用到過的測試框架,在這裡做一個小結。

1. 常見測試框架

我在專案開發過程中使用的單元測試框架有Junit、TestNG以及Mockito,Junit和TestNG使用的比較多,Mockito最近才開始使用。對於Junit和TestNG的用法我就不多做介紹了,相信大家都會使TestNG和JUnit是針對Java語言的兩個比較常用的測試框架。JUnit出現的比較早,但是早期的JUnit 3對測試程式碼有非常多的限制,使用起來很不方便,後來的JUnit 4得到很大的改進。TestNG的出現介於JUnit 3和JUnit 4,但是TestNG在很多方面還要優於JUnit 4。下面從整體上對TestNG和JUnit 4進行比較全面的比較。

TestNG與JUnit的相同點
1. 使用annotation,且大部分annotation相同。
2. 都可以進行單元測試(Unit test)。
3. 都是針對Java測試的工具。

TestNG與JUnit的不同點:
1. JUnit只能進行單元測試,TestNG可以進行單元測試,功能測試,端到端測試,整合測試等。
2. TestNG需要一個額外的xml配置檔案,配置測試的class、method甚至package。
3. TestNG的執行方式更加靈活:命令列、ant和IDE,JUnit只能使用IDE。
4. TestNG的annotation更加豐富,比如@ExpectedExceptions、@DataProvider等。
5. 測試套件執行失敗,JUnit 4會重新執行整個測試套件。TestNG執行失敗時,會建立一個XML檔案說明失敗的測試,利用這個檔案執行程式,就不會重複執行已經成功的測試。

TestNG比JUnit 4靈活性的體現:
1. JUnit 4中必須把@BeforeClass修飾的方法宣告為public static,這就限制了該方法中使用的變數必須是static。而TestNG中@BeforeClass修飾的方法可以跟普通函式完全一樣。
2. JUnit 4測試的依賴性非常強,測試用例間有嚴格的先後順序。前一個測試不成功,後續所有的依賴測試都會失敗。TestNG 利用@Test 的dependsOnMethods屬性來應對測試依賴性問題。某方法依賴的方法失敗,它將被跳過,而不是標記為失敗。
3. 對於n個不同引數組合的測試,JUnit 4要寫n個測試用例。每個測試用例完成的任務基本是相同的,只是受測方法的引數有所改變。TestNG的引數化測試只需要一個測試用例,然後把所需要的引數加到TestNG的xml配置檔案中。這樣的好處是引數與測試程式碼分離,非程式設計師也可以修改引數,同時修改無需重新編譯測試程式碼。
4. JUnit 4的測試結果通過Green/Red bar體現,TestNG的結果除了Green/Red bar,還有test-output資料夾,對測試結果的描述更加詳細,方便定位錯誤。

相比於Junit和TestNG,mockito的功能是解決units之間由於耦合而難於被單獨測試的問題,下面做下簡單介紹,具體的用法請參照http://site.mockito.org/

什麼是mock?
在軟體開發的世界之外, “mock”一詞是指模仿或者效仿。 因此可以將“mock”理解為一個替身,替代者. 在軟體開發中提及”mock”,通常理解為模擬物件或者Fake。

為什麼需要Mock?
Mock是為了解決units之間由於耦合而難於被測試的問題。所以mock object是unit test的一部分。

Mock的好處是什麼?
提前建立測試,TDD(測試驅動開發)這是個最大的好處吧。
如果你建立了一個Mock那麼你就可以在service介面建立之前寫Service Tests了,這樣你就能在開發過程中把測試新增到你的自動化測試環境中了。換句話說,模擬使你能夠使用測試驅動開發。

團隊可以並行工作
這類似於上面的那點;為不存在的程式碼建立測試。但前面講的是開發人員編寫測試程式,這裡說的是測試團隊來建立。當還沒有任何東西要測的時候測試團隊如何來建立測試呢?模擬並針對模擬測試!這意味著當service藉口需要測試時,實際上QA團隊已經有了一套完整的測試元件;沒有出現一個團隊等待另一個團隊完成的情況。這使得模擬的效益型尤為突出了。

你可以建立一個驗證或者演示程式
由於Mocks非常高效,Mocks可以用來建立一個概念證明,作為一個示意圖,或者作為一個你正考慮構建專案的演示程式。這為你決定專案接下來是否要進行提供了有力的基礎,但最重要的還是提供了實際的設計決策。

為無法訪問的資源編寫測試
這個好處不屬於實際效益的一種,而是作為一個必要時的“救生圈”。有沒有遇到這樣的情況?當你想要測試一個service介面,但service需要經過防火牆訪問,防火牆不能為你開啟或者你需要認證才能訪問。遇到這樣情況時,你可以在你能訪問的地方使用MockService替代,這就是一個“救生圈”功能。

Mock 可以交給使用者
在有些情況下,某種原因你需要允許一些外部來源訪問你的測試系統,像合作伙伴或者客戶。這些原因導致別人也可以訪問你的敏感資訊,而你或許只是想允許訪問部分測試環境。在這種情況下,如何向合作伙伴或者客戶提供一個測試系統來開發或者做測試呢?最簡單的就是提供一個mock,無論是來自於你的網路或者客戶的網路。

隔離系統
有時,你希望在沒有系統其他部分的影響下測試系統單獨的一部分。由於其他系統部分會給測試資料造成干擾,影響根據資料收集得到的測試結論。使用mock你可以移除掉除了需要測試部分的系統依賴的模擬。當隔離這些mocks後,mocks就變得非常簡單可靠,快速可預見。這為你提供了一個移除了隨機行為,有重複模式並且可以監控特殊系統的測試環境。

其實上面的特點總結成一句話:Mock可以解決測試物件的依賴問題,讓測試能夠只針對測試物件本身的邏輯,保證測試不受依賴的影響。

下面有個例子可以清晰的體現這一點,直接上程式碼:

public class OrderService {
    private PriceService priceService=new PriceService();

    private ProductService productService=new ProductService();

    /**
     * 該方法是返回訂單資訊
     * 依賴價格服務、商品服務
     * @param orderCode
     * @return
     */
    public OrderInfo getOrderInfoByOrderCode(String orderCode){
        PriceInfo priceInfo=priceService.getPriceInfoByProductCode("L3001");
        ProductInfo productInfo=productService.getProductInfoByProductCode("L3001");
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.optionText=productInfo.optionText;
        orderInfo.productCode=productInfo.productCode;
        orderInfo.productName=productInfo.productName;
        orderInfo.price=priceInfo.price;
        return orderInfo;
    }
}

對於上面這個方法,在不使用Mockito來進行測試時,需要價格服務的getPriceInfoByProductCode和商品服務的getProductInfoByProductCode方法開發完成才能進行測試,下面是不使用Mockito的測試程式碼

public class OrderServiceTestWithJunit {
    private OrderService orderService;
    private ProductService productService;
    private PriceService priceService;
    @Before
    public void setUp() throws Exception {
        orderService=new OrderService();
        productService=new ProductService();
        priceService=new PriceService();
        ReflectionTestUtils.setField(orderService,"productService",productService);
        ReflectionTestUtils.setField(orderService,"priceService",priceService);
    }

    @Test
    public void getOrderInfoByOrderCode() throws Exception {
        OrderInfo orderInfo=orderService.getOrderInfoByOrderCode("testCode");
        Assert.assertNotNull(orderInfo);
    }

}

這樣的確可以完成對訂單服務的測試,但是前提是產品服務和價格服務已經完成且保證正確性,如果依賴的服務存在異常,這時異常將會從訂單服務丟擲,那麼定位異常將會非常麻煩。因此,對於這種有很多依賴的測試單元,只使用Junit或者TestNG,想要對測試單元本身的邏輯進行測試,幾乎是不可能的。

下面介紹用Mockito的做法

public class OrderServiceTestWithMock {
    @Mock
    private ProductService productService;
    @Mock
    private PriceService priceService;
    @InjectMocks
    private OrderService orderService;
    @BeforeClass
    public void setUp(){
        MockitoAnnotations.initMocks(this);
        setMockData();
    }

    private void setMockData() {
        when(priceService.getPriceInfoByProductCode(anyString())).thenAnswer(invoke->{
                PriceInfo priceInfo=new PriceInfo();
                priceInfo.price= BigDecimal.valueOf(100);
                return priceInfo;
        }
        );

        when(productService.getProductInfoByProductCode(anyString())).thenAnswer(invocation -> {
            ProductInfo productInfo=new ProductInfo();
            productInfo.optionText="10支裝";
            productInfo.productCode="L3001";
            productInfo.productName="mock商品";
            return productInfo;
        });
    }

    @Test
    public void testGetOrderInfoByOrderCode() throws Exception {
       OrderInfo orderInfo=orderService.getOrderInfoByOrderCode("Test");
       Assert.assertNotNull(orderInfo.optionText);
    }

}

2. 在專案中如何選擇測試框架?

JUnit 4 和 TestNG 在表面上是相似的,然而設計 JUnit 的目的是為了分析程式碼單元,而 TestNG 的預期用途則針對高階測試。對於大型測試套件,我們不希望在某一項測試失敗時就得重新執行數千項測試,TestNG 的靈活性在這裡尤為有用。這兩個框架都有自己的優勢,需要按照測試要求來選擇,不過對於開發來說其實選擇那一個沒有什麼太大的區別,因為用到的測試框架的功能不多,都是些基本的用法,對於微服務或者多人協作完成一個功能的情況下,Mockito是必須接入。

3.總結

其實開發寫測試用例是一個不斷梳理自己程式碼邏輯的過程,可能在寫的過程中你就發現了邏輯上的漏洞。

相關推薦

java測試框架如何執行groovy指令碼檔案

本人在寫基於httpclient的測試框架時,用到了groovy指令碼作為測試用例的指令碼語言,自然就需要java執行上傳的測試指令碼,在看過例項之後,自己進行了封裝,總體來說跟java反射執行java方法類似。但又有一些不相容的情況,部分已經寫了部落格做記錄了,以後會陸續更

Java測試框架

前言 在專案開發過程中必不可少的會用到測試框架來檢查自己的程式碼邏輯,可能大多數人和我一樣從來沒有怎麼重視過測試程式碼,認為測試程式碼存在與否的意義不大。但是,看過很多大牛的專案後,發現他們寫的專案中測試用例的程式碼遠多於實際程式碼。所以,為了向大牛們看齊,最

怎樣選擇Java測試框架 JUnit還是TestNG?

Martin Fowler曾說過,軟體開發領域中此前從沒有過這樣的事情:很少幾行程式碼對大量的程式碼起了如此重要的作用。JUnit過去直到如今依然是單元測試的一個標準,是最流行的開源工具。當然現在我們有許多有別於JUnit的其他的開源工具。我自己,除了使用JUnit外,還

怎樣選擇Java測試框架 JUnit還是TestNG

自動測試成為你Java專案中的一部分了嗎?你最愛的測試框架是什麼哪?使用的又是哪一種標準?   本文的4名開發者將和你一起分享他們在自動測試領域中的觀點和經驗。當你的專案面臨測試階段的時候,希望這些觀點能對你有所幫助。如果你也想要分享自己的觀點,請回帖參與討論。我們真摯的希望

Java+Maven+selenium+testing+reportNG自動化測試框架

都是 tlist image pub tro snapshot htm sea cells 最近公司新出了一個產品,需要搭建自動化測試框架,這是一個學以至用的好機會,跟上級申請後,決定搭建一個java自動化測試框架。 Java自動化測試對我來講可以說不難不易,因為java是

java 性能測試框架工具-junitperf

mas lang 1.7 ogr art 技術分享 hello 圖片 success 性能測試工具 對於 Java 開發者來說,要去學習性能測試工具未免很麻煩。 但有時候會有性能測試的需求。 junitperf junitperf 就是一款為 Java 開發者設計的性能測試

Java&Selenium Web自動化測試框架理念

一、自動化測試含義 在自動化測試領域內流傳著一個說法:單元測試才是自動化測試的核心,在自動化測試裡,無論框架何等完美都不可能脫離單元測試,單元測試將會是自動化測試裡最小的單位,把它看作單位一,若干個單位一組成了一個整體,它就成了自動化測試; 諸如Python的單元測試框架Unittest、Pytest;J

java:集合框架(Collection集合的帶All功能測試)

        boolean addAll(Collection c)         boolean removeAll(Collection c)         boolean contains

JAVA SSM框架中解決ajax及swagger測試請求跨域問題

1.在config問價夾下建立一個類CrossDomainConfig.java: package com.game.config; import org.springframework.context.annotation.Configuration; import org.springfr

JAVA 程式設計師需要用到 10 個測試框架和庫

想要提高你的自動化測試技術?以下是 10 個優秀的測試框架和庫,以及它們常見用法的概述。 最近我寫了一些文章,關於 Java 程式設計師今年應該學習什麼,例如程式語言,庫和框架等,如果只能學習或提高其中一項,那必然是自動化測試技能。 測試是專業程式設計師區別於業餘程式設計師的一項指標,作為專業程式設計師,並

JAVA+Maven+TestNG搭建介面測試框架及例項

1、配置JDK 2、安裝Eclipse以及TestNG Eclipse下載地址:http://beust.com/eclipse TestNG安裝過程: 線上安裝 輸入網址:http://beust.com/eclipse 線上安裝會比較慢,有的人可能還會連結不上這個地址,所以下面介紹一個離線下載的方

TestNg JAVA 自動化單元測試框架Demo

環境準備 既然是java 的自動化單元測試框架,就必須要有java的環境了,這裡使用的編輯器是Eclipse,已經安裝過TestNg 外掛,如果環境準備好就可以開始了 程式碼例項 程式碼結構

java+selenium+Firefox自動化測試框架

此篇沒有太多參考的價值,不夠詳細.有時間補充FireFox下載28-32版本的,我下載的是,較高版本不支援FireBug和FirePath新增元件搜尋安裝FireBug安裝FirePath外掛下載一下紅框內的包其中selenium-server-3.1.0包內包含的檔案將第三

java版本-API介面測試框架搭建

基本概念:testng ,http, json, mysql, jenkins, spring 陸陸續續搭建起來的介面測試框架,使用起來並不是特別的理想,所以走上了一條迭代優化的不歸路。 所謂的框架是指,用例的組織,批量執行,測試報告,引數化配置。 測試框架應該

Java微基準測試框架JMH

本文轉自:https://www.xncoding.com/2018/01/07/java/jmh.html  作者:XiongNeng JMH,即Java Microbenchmark Harness,這是專門用於進行程式碼的微基準測試的一套工具API。 JM

web自動化測試框架搭建( Java+Cucumber+Gradle) _Mac_3

1. 建立一個Gradle projectfile-->new-->Other-->Gradle Project2. 修改build.gradle// plugin  apply pl

selenium+java+testNG+pageObject深入理解自動化測試框架

關於selenium+java+testNg的環境配置文章,本文主要講述測試框架的架構實現。 我們知道,搭建一個合理的測試框架能夠將自動化測試做大做大,一個合適的自動化測試框架能夠極大的降低程式碼的數量,便於後續的維護。文章先從測試框架的模型,思想講起,然後將各個部分做實現

groovy如何使用java介面測試框架傳送http請求

本人在使用java寫框架做http介面測試的過程中,經過大神指點思路,發現用例還是要用指令碼語言來做會更加有利於後期的用例執行和用例管理。最近在研究大神推薦的groovy指令碼語言,略有一些小成績。下面分享一下如何在groovy裡面使用自己寫的基於java的介面測試框架來發送

Java JUnit 單元測試框架

JUnit是一個Java語言的單元測試框架。 Junit 測試也是程式設計師測試,即所謂的白盒測試 如使用eclipse 開發,不用新增jar包,eclipse內部已經集成了,我們只需要引入即可使用。 1.新增方法,【專案】上右擊,選擇Build Path ,進入 2 .

Java+Selenium3框架設計篇5-如何實現郵件傳送測試報告

       本篇繼續回答網友的問題,這個主題是如何通過郵件傳送測試報告。通過郵件傳送測試報告,這個很重要,也很有必要。不管你使用什麼自動化測試框架,都建議添加發送測試報告的功能。先來設計我們的傳送郵件的場景:假如我們測試報告是固定的名稱,放在固定的路徑下。 1.下載jav