使用異步方式提高測(cè)試腳本運(yùn)行效率
優(yōu)化測(cè)試腳本中,提高效率是主要目的之一,但是往往效率提升是最難的,因?yàn)闊o(wú)從下手。但其實(shí)我們平時(shí)的測(cè)試腳本中有一部分是很容易優(yōu)化提升效率的,那就是I/O部分。我們常規(guī)的做法是在腳本運(yùn)行前使用JUnit的@Before或者@BeforeClass來(lái)進(jìn)行各種I/O操作,例如讀寫(xiě)數(shù)據(jù)庫(kù)、讀寫(xiě)磁盤(pán)文件等,很多時(shí)候是為了準(zhǔn)備測(cè)試數(shù)據(jù),這些預(yù)置條件花費(fèi)的時(shí)間常常比整個(gè)腳本的運(yùn)行時(shí)間都要長(zhǎng),如果能縮短這部分操作的時(shí)間,那么效率很得到很大的提升。
優(yōu)化的方法很簡(jiǎn)單,就是將這部分操作異步處理。以數(shù)據(jù)準(zhǔn)備為例,我們最常見(jiàn)的做法是將數(shù)據(jù)保存在excel中,然后讀取excel后再插入數(shù)據(jù)庫(kù),這里就涉及一次磁盤(pán)I/O和一次網(wǎng)絡(luò)I/O,但是準(zhǔn)備出來(lái)的數(shù)據(jù)一般并不是在測(cè)試腳本的第一步就會(huì)被用到,所以可以把預(yù)置條件異步執(zhí)行,與測(cè)試腳本并行執(zhí)行,再需要預(yù)置條件處理結(jié)果的時(shí)候再去獲取。
下面我用一個(gè)頁(yè)面自動(dòng)化腳本為例來(lái)介紹如何提高這部分操作的效率,這段代碼用來(lái)校驗(yàn)淘寶交易過(guò)程中的付款環(huán)節(jié),既然是校驗(yàn)付款,那么在預(yù)置條件中應(yīng)該要準(zhǔn)備一個(gè)未付款狀態(tài)的訂單數(shù)據(jù)。
優(yōu)化前我們的腳本如下:
Java代碼
1.import java.util.concurrent.ExecutionException; 2.import java.util.concurrent.TimeoutException; 3. 4.import org.junit.Before; 5.import org.junit.Test; 6. 7. 8.public class AsyncSample { 9. 10. private long orderId; 11. 12. @Before 13. public void createOrder() { 14. //準(zhǔn)備訂單數(shù)據(jù) 15. orderId = 0L; //賦值準(zhǔn)備好的訂單號(hào) 16. } 17. 18. @Test 19. public void test() throws InterruptedException, ExecutionException, TimeoutException { 20. //步驟一:登錄頁(yè)面 21. //步驟二:打開(kāi)已買(mǎi)到訂單頁(yè)面 22. //步驟三:根據(jù)訂單號(hào)定位頁(yè)面元素位置 23. //步驟四:付款 24. //斷言:驗(yàn)證付款結(jié)果 25. } 26. 27.} |
上面的腳本中,最耗時(shí)的應(yīng)該在@Before的createOrder方法中,下面來(lái)優(yōu)化這個(gè)方法。
Java代碼
1.import java.util.concurrent.Callable; 2.import java.util.concurrent.ExecutionException; 3.import java.util.concurrent.ExecutorService; 4.import java.util.concurrent.Executors; 5.import java.util.concurrent.Future; 6.import java.util.concurrent.TimeUnit; 7.import java.util.concurrent.TimeoutException; 8. 9.import org.junit.AfterClass; 10.import org.junit.Before; 11.import org.junit.Test; 12. 13. 14.public class AsyncSample { 15. 16. private static final ExecutorService single = Executors.newSingleThreadExecutor(); 17. 18. private Future<Long> future; 19. 20. @Before 21. public void createOrder() { 22. future = single.submit(new Callable<Long>() { 23. 24. @Override 25. public Long call() throws Exception { 26. long orderId = 0L; 27. //準(zhǔn)備訂單數(shù)據(jù) 28. return orderId; //返回訂單ID 29. } 30. }); 31. } 32. 33. @AfterClass 34. public static void shutdown() { 35. single.shutdownNow(); 36. } 37. 38. @Test 39. public void test() throws InterruptedException, ExecutionException, TimeoutException { 40. //步驟一:登錄頁(yè)面 41. //步驟二:打開(kāi)已買(mǎi)到訂單頁(yè)面 42. long orderId = future.get(10, TimeUnit.SECONDS); //步驟三:從異步任務(wù)中獲取訂單號(hào) 43. //步驟四:根據(jù)訂單號(hào)定位頁(yè)面元素位置 44. //步驟五:付款 45. //斷言:驗(yàn)證付款結(jié)果 46. } 47. 48.} |
為了清楚的說(shuō)明方法,并沒(méi)有寫(xiě)太多的代碼,都以注釋說(shuō)明取代。可以看到在步驟三時(shí)才需要預(yù)置條件中準(zhǔn)備的測(cè)試數(shù)據(jù),但是正常情況下,在登錄和打開(kāi)已買(mǎi)到頁(yè)面的過(guò)程中,訂單數(shù)據(jù)已經(jīng)準(zhǔn)備好了,步驟三可以直接拿到訂單號(hào)然后繼續(xù)后面的步驟。
相比原來(lái)的腳本,我們充分利用了登錄和打開(kāi)頁(yè)面這段時(shí)間完成了數(shù)據(jù)準(zhǔn)備的工作,所以整個(gè)數(shù)據(jù)準(zhǔn)備的時(shí)間完全沒(méi)有了,腳本效率提升是非常明顯的。
當(dāng)然,也可以將異步的方法作一些封裝使其更簡(jiǎn)潔和易用。另外,對(duì)于異步方法的使用需要把握好度,避免大量使用降低代碼的可讀性和可維護(hù)性。
posted on 2013-06-05 10:31 順其自然EVO 閱讀(327) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): selenium and watir webdrivers 自動(dòng)化測(cè)試學(xué)習(xí)