自動(dòng)化單元測(cè)試可以做許多的事,并幫你節(jié)省時(shí)間。它也可以被用作快速檢驗(yàn)新建工程或進(jìn)行冒煙測(cè)試。始終,單元測(cè)試是作為一種有效的、系統(tǒng)的檢驗(yàn)應(yīng)用程序各功能執(zhí)行的方式。Android SDK支持JUnit的自動(dòng)化單元測(cè)試。本教程假設(shè)你已熟悉Android和JUnit在Eclipse的使用。
創(chuàng)建一個(gè)Android的JUnit項(xiàng)目
如果你的Eclipse中已經(jīng)有Android項(xiàng)目,就不用再創(chuàng)建了。如果你的Eclipse中沒有Android項(xiàng)目,你可以創(chuàng)建一個(gè)JUnit項(xiàng)目,在創(chuàng)建JUnit項(xiàng)目的同時(shí)也會(huì)為你創(chuàng)建Android項(xiàng)目。
對(duì)現(xiàn)有的Android項(xiàng)目,在Eclipse中右鍵單擊,選擇“Android Tools”,然后“New Test Project…”,如下圖:
如果是新建Android項(xiàng)目,在“New Android Project”對(duì)話框中,按“Next”按鈕,如下圖:
無論按照上面哪種方式,你都會(huì)在這個(gè)時(shí)候創(chuàng)建Android項(xiàng)目的新測(cè)試項(xiàng)目。創(chuàng)建測(cè)試項(xiàng)目的對(duì)話框,如下圖所示,通常會(huì)自動(dòng)填寫上一些標(biāo)準(zhǔn)的命名約定等細(xì)節(jié)。如果沒有,請(qǐng)自己填寫,并創(chuàng)造該項(xiàng)目。
在Android中創(chuàng)建一個(gè)JUnit測(cè)試用例
Android應(yīng)用程序通常是由一些Activity類組成的。事實(shí)上,每一個(gè)ACtivity都可以是一個(gè)獨(dú)立實(shí)體,進(jìn)行測(cè)試。Android SDK中包含了幾個(gè)類來測(cè)試ACtivity類?,F(xiàn)在我們將使用一個(gè)。
右鍵單擊你的測(cè)試項(xiàng)目。選擇“New”,然后“JUnit Test Case”:
在新建JUnit測(cè)試用例對(duì)話框上填寫,使用超類是android.test.ActivityInstrumentTestCase2,其中T是我們要測(cè)試的Activity,如下圖:
點(diǎn)擊“完成”按鈕,這個(gè)類就創(chuàng)建成功了。注意:由向?qū)?chuàng)建的默認(rèn)構(gòu)造函數(shù)是不正確的。我們需要修改它,讓它不帶任何參數(shù),調(diào)用不同的super()的方法,代碼如下:
1 public ScreenValidation() { 2 super("com.mamlambo.testingproject.TestingProjectActivity", 3 TestingProjectActivity.class); 4 }
1 TextView helloText; 2 protected void setUp() throws Exception { 3 super.setUp(); 4 helloText = (TextView) getActivity(). 5 findViewById(R.id.hello_textview); 6 }
在Android中添加單元測(cè)試
01 public void testHelloTextVisibility() { 02 View container = getActivity().findViewById(R.id.container_layout); 03 int boundaryWidth = container.getWidth(); 04 int boundaryHeight = container.getHeight(); 05 06 int[] location = new int[2]; 07 container.getLocationOnScreen(location); 08 09 int[] helloTextLocation = new int[2]; 10 helloText.getLocationOnScreen(helloTextLocation); 11 12 Rect textRect = new Rect(); 13 helloText.getDrawingRect(textRect); 14 15 boolean widerThanBoundary = (textRect.width() > boundaryWidth); 16 boolean tallerThanBoundary = (textRect.height() > boundaryHeight); 17 boolean extendsOffRight = location[0] + boundaryWidth 18 > helloTextLocation[0] + textRect.width(); 19 assertTrue("Text wider than boundary", widerThanBoundary); 20 assertTrue("Text taller than boundary", tallerThanBoundary); 21 assertTrue("Text goes off right side", extendsOffRight); 22 23 // ... and so on 24 }
所有的測(cè)試方法必須用“test”做前綴。上面,我們已經(jīng)創(chuàng)建了一個(gè)測(cè)試名為“HelloTextVisibility”的方法。如果測(cè)試通過或失敗,assertFalse()都會(huì)被調(diào)用。(assertTrue()方法只有是true時(shí)調(diào)用。)
運(yùn)行JUnit測(cè)試用例
運(yùn)行測(cè)試和測(cè)試用例,點(diǎn)擊Eclipse的Debug,選擇Android JUnit測(cè)試。如果你喜歡,你還可以創(chuàng)建一個(gè)Android JUnit測(cè)試配置,自定義這些設(shè)置。
如下圖,我們的小應(yīng)用程序在橫屏模式下,“Hello Text Visibility”測(cè)試通過:
但在豎屏模式下,未能通過測(cè)試:
很顯然,我們的布局設(shè)計(jì)在豎屏模式下顯示不正確。(注:這可能是設(shè)置的寬度像素超過了手機(jī)的,而沒有使用合適的單位,如DP或是match_parent。)
Android應(yīng)用程序的質(zhì)量在于單元測(cè)試
創(chuàng)建單元測(cè)試時(shí),必須小心謹(jǐn)慎。如果測(cè)試用例不正確,測(cè)試的東西通過了,也沒有價(jià)值。這是非常糟糕的,因?yàn)樗赡苎谏w了一些問題。所以測(cè)試用例與代碼本身一樣重要。測(cè)試測(cè)試用例的主要方式是通過做代碼審查,并確保它們確實(shí)在測(cè)試。
當(dāng)然,測(cè)試Android框架的功能對(duì)于你的app來說,沒有起到特別大的作用。比如,測(cè)試設(shè)置文本字段的值,然后讀取它,看它是否相同。測(cè)試常規(guī)的TextView,并不是特別有意義的(除非你的SDK在一個(gè)新的設(shè)備上使用)。然而,如果是測(cè)試你自己實(shí)現(xiàn)的TextView,那就有必要了。
這并不是說任何代碼框架都是那樣的完美無缺,但測(cè)試的事情是值得花許多心思的去寫測(cè)試開始的。如果失敗了,比起的你的應(yīng)用程序,你將有更大的問題。還有是對(duì)SDK之間的細(xì)微差別的測(cè)試,在上面的例子中,我們沒有這么做,是因?yàn)槲覀兪褂昧苏_的SDK。
因此,如果你是自動(dòng)化單元測(cè)試的新手,我們建議你做一些這方面的課題研究。一個(gè)不錯(cuò)的地方是JUnit.org。
結(jié)論
在本教程中,你已經(jīng)學(xué)會(huì)如何快速添加一個(gè)新的測(cè)試項(xiàng)目,并在Eclipse的Android項(xiàng)目中使用JUnit對(duì)你的app執(zhí)行自動(dòng)化測(cè)試。單元測(cè)試可以為邏輯測(cè)試,功能測(cè)試和用戶界面測(cè)試等,不再是專門手動(dòng)測(cè)試移動(dòng)應(yīng)用。然而,使用一個(gè)包含自動(dòng)化單元測(cè)試的套件,有幾大好處:它可以節(jié)省時(shí)間,金錢和資源,以及提供一套可靠的,重復(fù)性的測(cè)試,并且可以運(yùn)行在許多不同的設(shè)備配置中。