一個新聞 app 應該會有以下這些 activity。
語言選擇 - 當使用者第一次打開軟體, 他必須至少選擇一種語言。選擇後,選項儲存在共享偏好中,使用者跳轉到新聞清單 activity。
新聞清單 - 當使用者來到新聞清單 activity,将發送一個包含語言參數的請求到伺服器,并将伺服器傳回的内容顯示在 recycler view 上(包含有新聞清單的 id, news_list)。 如果共享偏好中未存語言參數,或者伺服器沒有傳回一個成功消息, 就會彈出一個錯誤對話框并且 recycler view 将不可見。如果使用者隻選擇了一種語言,新聞清單 activity 有個 “change your language” 的按鈕,或者如果使用者選擇多種語言,則按鈕為 “change your languages” 。 (我對天發誓這是一個虛構的 app 軟體)
新聞細節 - 如同名字所述, 當使用者點選新聞清單項時将啟動這個 activity。
這個 app 功能已經足夠,,讓我們深入研究下為新聞清單 activity 編寫的測試用例。 這是我第一次寫的代碼。
<code>/*</code>
<code>click on the first news item.</code>
<code>it should open newsdetailactivity</code>
<code>*/</code>
<code>@test</code>
<code>public void testclickonanynewsitem() {</code>
<code>onview(allof(withid(r.id.news_list), isdisplayed())).perform(recyclerviewactions</code>
<code>.actiononitematposition(1, click()));</code>
<code>intended(hascomponent(newsdetailsactivity.class.getname()));</code>
<code>}</code>
<code></code>
<code>/**</code>
<code>* to test the correct text on the button</code>
<code>public void testchangelanguagefeature() {</code>
<code>int count = userpreferenceutil.getselectedlanguagescount();</code>
<code>if (count == 1) {</code>
<code>onview(withtext("choose your language")).check(matches(isdisplayed()));</code>
<code>} else if (count > 1) {</code>
<code>onview(withtext("choose your languages")).check(matches(isdisplayed()));</code>
<code>?}</code>
<a target="_blank"></a>
在第一個測試用例 <code>testclickonanynewsitem()</code>, 如果伺服器沒有傳回成功資訊,測試用例将會傳回失敗,因為 recycler view 是不可見的。但是這個測試用例的目的并非如此。不管該用例為 pass 還是 fail,它的最低要求是 recycler view 總是可見的, 如果因某種原因,recycler view 不可見,那麼測試用例不應視為 failed。正确的測試代碼應該像下面這個樣子。
<code>click on any news item.</code>
<code>try {</code>
<code>/*to test this case, we need to have recyclerview present. if we don't have the</code>
<code>recyclerview present either due to the presence of error_screen, then we should consider</code>
<code>this test case successful. the test case should be unsuccesful only when we click on a</code>
<code>news item and it doesn't open newsdetail activity</code>
<code>viewinteraction viewinteraction = onview(withid(r.id.news_list));</code>
<code>viewinteraction.check(matches(isdisplayed()));</code>
<code>} catch (nomatchingviewexception e) {</code>
<code>return;</code>
<code>} catch (assertionfailederror e) {</code>
<code>&nbsp; &nbsp;//在這裡我們确信,news_list的 recyclerview 對使用者是可見的。</code>
<code>&nbsp; &nbsp;onview(allof(withid(r.id.news_list), isdisplayed())).perform(recyclerviewactions</code>
當我開始測試, 我通常按如下順序測試 activity:
語言選擇
新聞清單
新聞細節
因為我首先測試語言選擇 activity,在測試 newslist activity 之前,總有一種語言已經是選擇好了的。但是當我先測試新聞清單 activity 時,測試用例開始傳回錯誤資訊。原因很簡單 - 沒有選擇語言,recycler view 不會顯示。注意, 測試用例的執行順序不能影響測試結果。 是以在運作測試用例之前, 語言選項必須是儲存在共享偏好中的。在本例中,測試用例獨立于語言選擇 activity 的測試。
<code>@rule</code>
<code>public activitytestrule activitytestrule =</code>
<code>new activitytestrule(topicsactivity.class, false, false);</code>
<code>userpreferenceutil.saveuserprimarylanguage("english");</code>
<code>intent intent = new intent();</code>
<code>activitytestrule.launchactivity(intent);</code>
現在在第二個測試用例 <code>testchangelanguagefeature()</code> 中,我們擷取到使用者選擇語言的個數,基于這個數目,我們寫了 if-else 條件來進行測試。 但是 if-else 條件應該寫在你的代碼當中,而不是測試代碼裡。每一個條件應該單獨測試。 是以,在本例中,不是隻寫一條測試用例,而是要寫如下兩個測試用例。
<code>* to test the correct text on the button when only one language is selected.</code>
<code>public void testchangelanguagefeatureforsingelanguage() {</code>
<code>//other initializations</code>
<code>userpreferenceutil.saveselectedlanguagescount(1);</code>
<code>* to test the correct text on the button when more than one language is selected.</code>
<code>public void testchangelanguagefeatureformultiplelanguages() {</code>
<code>userpreferenceutil.saveselectedlanguagescount(5); //write anything greater than 1.</code>
在大多數應用中,我們與外部網絡或者資料庫進行互動。一個測試用例運作時可以向伺服器發送一個請求,并擷取成功或失敗的傳回資訊。但是不能因從伺服器擷取到失敗資訊,就認為測試用例沒有通過。這樣想這個問題 - 如果測試用例失敗,然後我們修改用戶端代碼,以便測試用例通過。 但是在本例中, 我們要在用戶端進行任何更改嗎?- no。
但是你應該也無法完全避免要測試網絡請求和響應。由于伺服器是一個外部代理,我們可以設想一個場景,發送一些可能導緻程式崩潰的錯誤響應。是以,你寫的測試用例應該覆寫所有可能來自伺服器的響應,甚至包括伺服器決不會發出的響應。這樣可以覆寫所有代碼,并能保證應用可以處理所有響應,而不會崩潰。
正确的編寫測試用例與編寫這些測試代碼同等重要。
原文釋出時間為:2017-02-12
本文來自雲栖社群合作夥伴“linux中國”