2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩41頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p><b>  畢業(yè)論文(設(shè)計(jì))</b></p><p>  面向android系統(tǒng)的測(cè)試工具</p><p>  學(xué) 生 姓 名: </p><p>  指導(dǎo)教師: 講師 </p><p>  專業(yè)名稱:

2、 電子信息工程 </p><p>  所在學(xué)院: 信息工程學(xué)院 </p><p><b>  2012年06月</b></p><p><b>  目錄</b></p><p><b>  摘要I</b></p>

3、<p>  AbstractII</p><p><b>  第1章 緒論1</b></p><p>  1.1. 課題背景1</p><p>  1.2. 課題說(shuō)明1</p><p>  第2章 Android開(kāi)發(fā)系統(tǒng)綜述3</p><p>  2.1. android系

4、統(tǒng)介紹3</p><p>  2.2. 開(kāi)發(fā)環(huán)境介紹5</p><p>  2.3. 開(kāi)發(fā)語(yǔ)言介紹7</p><p>  第3章 測(cè)試工具介紹9</p><p>  3.1. 測(cè)試工具結(jié)構(gòu)介紹9</p><p>  3.2. 測(cè)試工具中Service介紹12</p><p>  第4

5、章 總體設(shè)計(jì)22</p><p>  4.1. 概述22</p><p>  4.2. 構(gòu)成23</p><p>  第5章 設(shè)計(jì)思想24 </p><p>  5.1. 設(shè)計(jì)思想概述24</p><p>  5.2. 設(shè)計(jì)原則25</p><p>  第6章 結(jié)論.35</

6、p><p><b>  致謝36</b></p><p><b>  參考文獻(xiàn)37</b></p><p>  附錄........................................................................................................

7、.............38</p><p><b>  摘要</b></p><p>  基于 Android 的自動(dòng)化測(cè)試的設(shè)計(jì)與實(shí)現(xiàn)以Android 客戶端的測(cè)試為研究?jī)?nèi)容,分析了 Android 自動(dòng)化測(cè)試框架及其層次關(guān)系,嘗試在現(xiàn)有測(cè)試方法的 基 礎(chǔ) 上 進(jìn) 行 測(cè) 試 手 段 的 優(yōu) 化 和 創(chuàng) 新 。 研 究 了 基 于 JUnit 和 instrum

8、entaion 的 Android 自 動(dòng) 化 框 架 的 實(shí) 現(xiàn) 技 術(shù) ,并 利 用 Hudson 進(jìn)行集成,實(shí)現(xiàn) Android 的自動(dòng)化測(cè)試。產(chǎn)品的開(kāi)發(fā)實(shí)踐表明, 這種自動(dòng)化測(cè)試方法效率高、用戶體驗(yàn)好, 對(duì)于 Android 的自動(dòng)化測(cè)試研究具有一定參考價(jià)值。Android應(yīng)用程序使用Java做為開(kāi)發(fā)語(yǔ)言,把編譯后的Java代碼連同其它應(yīng)用程序需要的數(shù)據(jù)和資源文件一起打包到一個(gè)Android包文件中,這個(gè)文件使用.apk做為

9、擴(kuò)展名,它是分發(fā)應(yīng)用程序并安裝到移動(dòng)設(shè)備的媒介,用戶只需下載并安裝此文件到他們的設(shè)備。單一.apk文件中的所有代碼被認(rèn)為是一個(gè)應(yīng)用程序。</p><p>  關(guān)鍵詞: 關(guān)鍵詞:測(cè)試自動(dòng)化;Android;設(shè)計(jì) </p><p><b>  Abstract</b></p><p>  This paper focuses on test

10、ing of Android clients. The authors analyze the Android automated testing framework and its hierarchy. The implementation is based on two automated testing framework of Android platform: JUnit a

11、nd instrumentation. The purpose of this article is to propose an optimized test method. Making use of the continuous integration features of Hudson, the real sense of automated testing can be

12、 achieved. It shows that t</p><p>  Key words:automated testing;Android;mobile phone;design</p><p><b>  緒論</b></p><p><b>  課題背景</b></p><p>

13、  作為20世紀(jì)最偉大的發(fā)明之一,計(jì)算機(jī)也進(jìn)入了后PC時(shí)代。不知不覺(jué)中,形形色色的數(shù)字產(chǎn)品成為主要的信息處理工具、并且逐步形成一個(gè)充滿商機(jī)的巨大產(chǎn)業(yè)。</p><p>  隨著后PC時(shí)代的到來(lái),人們開(kāi)始接觸全新的計(jì)算機(jī)軟件,計(jì)算及操作系統(tǒng)。Android系統(tǒng)的開(kāi)源,為計(jì)算機(jī)產(chǎn)品的生產(chǎn)商們又一次創(chuàng)造了商機(jī),越來(lái)越多的人開(kāi)始知道Android,認(rèn)識(shí)Android,開(kāi)始使用Android,這樣也就使得Android產(chǎn)品

14、走進(jìn)了一個(gè)美好的時(shí)代,而Android產(chǎn)品程序的測(cè)試也被生產(chǎn)商們開(kāi)始慢慢的拿到了日程上,這關(guān)系到他們生產(chǎn)過(guò)程中能否更多的節(jié)約時(shí)間金錢。</p><p>  此次設(shè)計(jì)通過(guò)對(duì)Android系統(tǒng)測(cè)試工具的開(kāi)發(fā),可以掌握Android系統(tǒng)軟件開(kāi)發(fā)的基本技術(shù)、例如Android的用戶界面設(shè)計(jì),Android進(jìn)程間的通信,以及我們采用的Java語(yǔ)言等。既可以用于國(guó)內(nèi)的軟件開(kāi)發(fā)、又可在將來(lái)的實(shí)際工作中的對(duì)日產(chǎn)品開(kāi)發(fā)中有所助益。

15、</p><p><b>  課題說(shuō)明</b></p><p><b>  設(shè)計(jì)要求</b></p><p>  Android模擬器,Java語(yǔ)言,Eclipse開(kāi)發(fā)環(huán)境。能理解、掌握Android軟件開(kāi)發(fā)的基本知識(shí)。</p><p><b>  設(shè)計(jì)內(nèi)容</b></p

16、><p>  評(píng)價(jià)邏輯的手動(dòng)設(shè)定,而后會(huì)自動(dòng)執(zhí)行,Sevice部分解決,實(shí)現(xiàn)AP與測(cè)試工具的種種通信與聯(lián)系,自動(dòng)評(píng)價(jià)用Adapter層。</p><p><b>  實(shí)現(xiàn)方法</b></p><p> ?、旁赑C機(jī)上,利用Eclipse的開(kāi)發(fā)軟件,編寫(xiě)程序代碼,并進(jìn)行編譯代碼以及對(duì)代碼進(jìn)行調(diào)試,編譯調(diào)試成功后,再利用Android模擬器來(lái)初步的模擬

17、運(yùn)行。測(cè)試工具要實(shí)現(xiàn)的部分除了測(cè)試相關(guān)代碼外,還有與AP進(jìn)行調(diào)用的部分,主要是需要給AP提供相關(guān)的接口。</p><p>  (2)以下是測(cè)試工具的結(jié)構(gòu)圖,其中藍(lán)色字體為需要改動(dòng)或是添加的部分。</p><p>  Android系統(tǒng)開(kāi)發(fā)綜述</p><p>  Android系統(tǒng)介紹</p><p>  Android是一個(gè)智能手機(jī)及便攜設(shè)

18、備操作系統(tǒng),中文名安卓、安致。由Google在2007年推出,并迅速成為智能手機(jī)的主流操作系統(tǒng)。</p><p>  下圖為Android創(chuàng)始開(kāi)發(fā)者合影:</p><p>  Android是一個(gè)冉冉升起的新系統(tǒng),僅用2年時(shí)間就從零到市場(chǎng)巨擘。而nokia用了12年,apple用了5年.截止到2010年第四季度,在全球智能手機(jī)市場(chǎng)安卓已經(jīng)完成對(duì)于nokia及apple的超越,同時(shí)增長(zhǎng)速度也

19、是遠(yuǎn)遠(yuǎn)超過(guò)其他對(duì)手。</p><p>  以下兩個(gè)表是Android發(fā)展的相關(guān)數(shù)據(jù)調(diào)查:</p><p><b>  系統(tǒng)開(kāi)放性</b></p><p>  在優(yōu)勢(shì)方面,Android平臺(tái)首先就是其開(kāi)放性,開(kāi)放的平臺(tái)允 android系統(tǒng)標(biāo)志。</p><p>  許任何移動(dòng)終端廠商加入到Android聯(lián)盟中來(lái)。顯著的開(kāi)

20、放性可以使其擁有更多的開(kāi)發(fā)者,隨著用戶和應(yīng)用的日益豐富,一個(gè)嶄新的平臺(tái)也將很快走向成熟。開(kāi)發(fā)性對(duì)于Android的發(fā)展而言,有利于積累人氣,這里的人氣包括消費(fèi)者和廠商,而對(duì)于消費(fèi)者來(lái)講,最大的受益正是豐富的軟件資源。開(kāi)放的平臺(tái)也會(huì)帶來(lái)更大競(jìng)爭(zhēng),如此一來(lái),消費(fèi)者將可以用更低的價(jià)位購(gòu)得心儀的手機(jī)</p><p><b>  掙脫運(yùn)行商的束縛</b></p><p>  在

21、過(guò)去很長(zhǎng)的一段時(shí)間,特別是在歐美地區(qū),手機(jī)應(yīng)用往往受到運(yùn)營(yíng)商制約,使用什么功能接入什么網(wǎng)絡(luò),幾乎都受到運(yùn)營(yíng)商的控制。自從iPhone上市,用戶可以更加方便地連接網(wǎng)絡(luò),運(yùn)營(yíng)商的制約減少。隨著EDGE、HSDPA這些2G至3G移動(dòng)網(wǎng)絡(luò)的逐步過(guò)渡和提升,手機(jī)隨意接入網(wǎng)絡(luò)已不是運(yùn)營(yíng)商口中的笑談。</p><p>  2.1.3豐富的硬件選擇</p><p>  這一點(diǎn)還是與Android平臺(tái)的開(kāi)放

22、性相關(guān),由于Android的開(kāi)放性,眾多的廠商會(huì)推出千奇百怪,功能特色各具的多種產(chǎn)品。功能上的差異和特色,卻不會(huì)影響到數(shù)據(jù)同步、甚至軟件的兼容。好比你從諾基亞Symbian風(fēng)格手機(jī)一下改用蘋(píng)果iPhone,同時(shí)還可將Symbian中優(yōu)秀的軟件帶到iPhone上使用、聯(lián)系人等資料更是可以方便地轉(zhuǎn)移。</p><p>  2.1.4不受任何限制的開(kāi)發(fā)商</p><p>  Android平臺(tái)提

23、供給第三方開(kāi)發(fā)商一個(gè)十分寬泛、自由的環(huán)境。因此不會(huì)受到各種條條框框的阻擾,可想而知,會(huì)有多少新穎別致的軟件會(huì)誕生。為未來(lái)的軟件行業(yè)做出非凡的成就。但也有其兩面性,血腥、暴力、情色方面的程序和游戲如何控制正是留給Android難題之一。也是留給軟件行業(yè)的,社會(huì)的難題。</p><p><b>  開(kāi)發(fā)環(huán)境介紹</b></p><p>  Eclipse是著名的跨平臺(tái)的自

24、由集成開(kāi)發(fā)環(huán)境(IDE)。最初主要用來(lái)Java語(yǔ)言開(kāi)發(fā)。</p><p>  Eclipse的本身只是一個(gè)框架平臺(tái),但是眾多插件的支持使得Eclipse擁有其他功能相對(duì)固定的IDE軟件很難具有的靈活性。許多軟件開(kāi)發(fā)商以Eclipse為框架開(kāi)發(fā)自己的IDE。</p><p>  Eclipse最初是由IBM公司開(kāi)發(fā)的替代商業(yè)軟件Visual Age for Java的下一代IDE開(kāi)發(fā)環(huán)境,2

25、001年11月貢獻(xiàn)給開(kāi)源社區(qū),現(xiàn)在它由非營(yíng)利軟件供應(yīng)商聯(lián)盟Eclipse基金會(huì)(Eclipse Foundation)管理。 2003年,Eclipse 3.0選擇OSGi服務(wù)平臺(tái)規(guī)范為運(yùn)行時(shí)架構(gòu)。 2007年6月,穩(wěn)定版3.3發(fā)布。2008年6月發(fā)布代號(hào)為Ganymede的3.4版。</p><p>  Eclipse的基礎(chǔ)是富客戶機(jī)平臺(tái)(Rich Client Platform, 即RCP)。RCP包括下列組

26、件:</p><p>  核心平臺(tái)(啟動(dòng)Eclipse,運(yùn)行插件)</p><p>  OSGi(標(biāo)準(zhǔn)集束框架)</p><p>  SWT(可移植構(gòu)件工具包)</p><p>  JFace(文件緩沖,文本處理,文本編輯器)</p><p>  Eclipse工作臺(tái)(即Workbench ,包含視圖(views)、編

27、輯器(editors)、視角(perspectives)、和向?qū)В╳izards))</p><p>  Eclipse采用的技術(shù)是IBM公司開(kāi)發(fā)的(SWT),這是一種基于Java的窗口組件,類似Java本身提供的AWT和Swing窗口組件;不過(guò)IBM聲稱SWT比其他Java窗口組件更有效率。Eclipse的用戶界面還使用了GUI中間層JFace,從而簡(jiǎn)化了基于SWT的應(yīng)用程序的構(gòu)建。</p>&l

28、t;p>  Eclipse的插件機(jī)制是輕型軟件組件化架構(gòu)。在富客戶機(jī)平臺(tái)上,Eclipse使用插件來(lái)提供所有的附加功能,例如支持Java以外的其他語(yǔ) 言。 已有的分離的插件已經(jīng)能夠支持C/C++(CDT)、Perl、Ruby,Python、telnet和數(shù)據(jù)庫(kù)開(kāi)發(fā)。插件架構(gòu)能夠支持將任意的擴(kuò)展加入到 現(xiàn)有環(huán)境中,例如配置管理,而決不僅僅限于支持各種編程語(yǔ)言。</p><p>  Eclipse的設(shè)計(jì)思想是:

29、一切皆插件。Eclipse核心很小,其它所有功能都以插件的形式附加于Eclipse核心之上。Eclipse基本內(nèi)核包括:圖形API (SWT/Jface), Java開(kāi)發(fā)環(huán)境插件(JDT ),插件開(kāi)發(fā)環(huán)境(PDE)等。</p><p>  Eclipse由各種不同的計(jì)劃組成。以下列出了部分計(jì)劃。</p><p>  Eclipse計(jì)劃:本身包括Eclipse平臺(tái),Eclipse富客戶端平臺(tái)

30、(RCP)和Java開(kāi)發(fā)工具(JDT)。</p><p>  Eclipse測(cè)試和性能工具平臺(tái)(TPTP):提供一個(gè)允許軟件開(kāi)發(fā)者構(gòu)建諸如測(cè)試調(diào)試、概況分析、基準(zhǔn)評(píng)測(cè)等測(cè)試和性能工具的平臺(tái)。</p><p>  Eclipse Web工具平臺(tái)計(jì)劃 (WTP):用Java企業(yè)版Web應(yīng)用程序開(kāi)發(fā)工具來(lái)擴(kuò)展Eclipse平臺(tái)。它由以下部分組成:HTML、JavaScript、CSS、JSP、S

31、QL、XML、DTD、XSD和WSDL的 源代碼編輯器;XSD和WSDL的圖形界面編輯器;Java企業(yè)版的“項(xiàng)目性質(zhì)”(project nature)、建構(gòu)器(builder)和模型(model),與一個(gè)Java企業(yè)版的導(dǎo)航(navigator);一個(gè)Web服務(wù)(Web service)向?qū)Ш蜑g覽器,還有一個(gè)WS-I測(cè)試工具;最后是數(shù)據(jù)庫(kù)訪問(wèn)查詢的工具與模型。</p><p>  Eclipse商業(yè)智能和報(bào)表工具

32、計(jì)劃(BIRT):提供Web應(yīng)用程序(特別是基于Java企業(yè)版的)的報(bào)表開(kāi)發(fā)工具。</p><p>  Eclipse可視化界面編輯器計(jì)劃(VEP):一個(gè)Eclipse下創(chuàng)建圖形用戶界面代碼生成器的框架。</p><p>  Eclipse建模框架(EMF):依據(jù)使用XMI描述的建模規(guī)格,生成結(jié)構(gòu)化數(shù)據(jù)模型的工</p><p>  具和其他應(yīng)用程序的代碼。</

33、p><p>  圖形化編輯器框架(GEF):能讓開(kāi)發(fā)者采用一個(gè)現(xiàn)成的應(yīng)用程序模型來(lái)輕松地創(chuàng)建。</p><p>  UML2:Eclipse平臺(tái)下的一個(gè)UML 2.0元模型的實(shí)現(xiàn),用以支持建模工具的開(kāi)發(fā)。</p><p>  AspectJ:一種針對(duì)Java的面向側(cè)面語(yǔ)言擴(kuò)展。</p><p>  Eclipse通訊框架(ECF):專注于在Ecl

34、ipse平臺(tái)上創(chuàng)建通訊應(yīng)用程序的工作。</p><p>  Eclipse數(shù)據(jù)工具平臺(tái)計(jì)劃(DTP)</p><p>  Eclipse設(shè)備驅(qū)動(dòng)軟件開(kāi)發(fā)計(jì)劃(DSDP)</p><p>  C/C++開(kāi)發(fā)工具計(jì)劃(CDT):努力為Eclipse平臺(tái)提供一個(gè)全功能集成開(kāi)發(fā)器。</p><p>  Eclipse平臺(tái)COBOL集成開(kāi)發(fā)環(huán)境子計(jì)劃(

35、COBOL):將構(gòu)建一個(gè)Eclipse平臺(tái)上的全功能COBOL集成開(kāi)發(fā)環(huán)境。</p><p>  并行工具平臺(tái)(PTP):將開(kāi)發(fā)一個(gè)對(duì)并行計(jì)算機(jī)架構(gòu)下的一組工具進(jìn)行集成工具。 </p><p>  嵌入式富客戶端平臺(tái)(eRCP):計(jì)劃將Eclipse富客戶端平臺(tái)擴(kuò)展到嵌入式設(shè)備上。這個(gè)平臺(tái)主要是一個(gè)富客戶端平臺(tái)(RCP)組件子集的集合。它能讓桌面環(huán)境下的應(yīng)用程序模型能夠

36、大致同樣地能運(yùn)用在嵌入式設(shè)備上</p><p><b>  開(kāi)發(fā)語(yǔ)言介紹</b></p><p>  Java最初被命名為Oak,目標(biāo)設(shè)定在家用電器等小型系統(tǒng)的編程語(yǔ)言,來(lái)解決諸如電視機(jī)、電話、鬧鐘、烤面包機(jī)等家用電器的控制和通訊問(wèn)題。由于這些智能化家電的市場(chǎng)需求沒(méi)有預(yù)期的高,Sun放棄了該項(xiàng)計(jì)劃。就在Oak幾近失敗之時(shí),隨著互聯(lián)網(wǎng)的發(fā)展,Sun看到了Oak在計(jì)算機(jī)網(wǎng)

37、絡(luò)上的廣闊應(yīng)用前景,于是改造了Oak,以“Java”的名稱正式發(fā)布。 </p><p>  Java 編程語(yǔ)言的風(fēng)格十分接近C、C++語(yǔ)言。Java是一個(gè)純的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言,它繼承了 C++ 語(yǔ)言面向?qū)ο蠹夹g(shù)的核心,Java舍棄了C ++語(yǔ)言中容易引起錯(cuò)誤的指針(以引用取代)、運(yùn)算符重載(operator overloading)、多重繼承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的對(duì)象

38、所占據(jù)的內(nèi)存空間,使得程序員不用再為內(nèi)存管理而擔(dān)憂。在 Java SE 1.5 版本中,Java 又引入了泛型編程(Generic Programming)、類型安全的枚舉、不定長(zhǎng)參數(shù)和自動(dòng)裝/拆箱等語(yǔ)言特性。 Java 不同于一般的編譯執(zhí)行計(jì)算機(jī)語(yǔ)言和解釋執(zhí)行計(jì)算機(jī)語(yǔ)言。它首先將源代碼編譯成二進(jìn)制字節(jié)碼(bytecode),然后依賴各種不同平臺(tái)上的虛擬機(jī)來(lái)解釋執(zhí)行字節(jié)碼,從而實(shí)現(xiàn)了“一次編譯、到處執(zhí)行”的跨平臺(tái)特性。不過(guò),每次的編譯執(zhí)

39、行需要消耗一定的時(shí)間,這同時(shí)也在一定程度上降低了 Java 程序的運(yùn)行效率。但在 J2SE 1.4.2 發(fā)布后,Java 的執(zhí)行速度有了大幅提升。 與傳統(tǒng)程序不同,Sun 公司在推出 Java 之際就將其作為一種開(kāi)放的技術(shù)。全球數(shù)以萬(wàn)計(jì)</p><p><b>  測(cè)試工具介紹</b></p><p><b>  測(cè)試工具結(jié)構(gòu)介紹</b><

40、/p><p>  Android自動(dòng)化測(cè)試目前可借鑒的經(jīng)驗(yàn)不多,現(xiàn)在采取的方式就是通過(guò)java代碼對(duì)Activity和View進(jìn)行操作,目前已知的入口是Instrumentation類。 </p><p>  Instrumentation與Activity均位于android.app包下,這個(gè)包內(nèi)還有諸如ActivityManagerNative這種不對(duì)App層開(kāi)放的類,通過(guò)查看Androi

41、d源碼發(fā)現(xiàn)Activity類中諸如startActivity(Intent intent)這樣重要的方法都是通過(guò)Instrumentation實(shí)現(xiàn),Instrumentation中也提供了一系列對(duì)Activity生命周期控制的方法。以Instrumentation為基礎(chǔ),Android SDK在Junit基礎(chǔ)上進(jìn)行了擴(kuò)展,提供了AndroidTestCase類及系列子類,其中最重要的一個(gè)類是ActivityInstrumentation

42、TestCase2</p><p>  基于Instrumentation的測(cè)試框架的工作原理SDK中的這張圖說(shuō)明的很清楚了:</p><p>  研究Android源碼發(fā)現(xiàn)框架層中有很多對(duì)測(cè)試有幫助的類、方法都被加上了注解或是聲明為private的,無(wú)法從app層訪問(wèn)。自然而然我們想到了java的反射機(jī)制,java反射允許我們?cè)L問(wèn)這樣的類和方法。 </p><p>

43、;  在上面的基礎(chǔ)上,國(guó)外有人開(kāi)發(fā)出了robot/" target="_blank" >Robotium工具,可以在有app源碼或apk的情況下進(jìn)行自動(dòng)化黑盒測(cè)試。 </p><p>  但是Robotium目前的缺點(diǎn)也很明顯,無(wú)法對(duì)WebView進(jìn)行操作,這對(duì)大量使用WebView的淘寶Android客戶端來(lái)說(shuō)無(wú)疑是很大的限制。 </p><p>  

44、而且Robotium提供的API是面向過(guò)程的,測(cè)試代碼的可擴(kuò)展性差。 </p><p>  我們需要一個(gè)面向?qū)ο蟮模蓪?duì)WebView進(jìn)行操作的自動(dòng)化測(cè)試框架,這就催生了TMTS(Taobao Mobile Test Studio)框架。 </p><p>  TMTS立項(xiàng)時(shí)還試圖著重解決另一個(gè)問(wèn)題,就是Instrumentation框架下testapp和app運(yùn)行在一個(gè)進(jìn)程中 ,app

45、crash會(huì)導(dǎo)致testapp一并crash。當(dāng)時(shí)和士敦一起研究了Instrumentation、Activity的啟動(dòng)流程,甚至想去研究一下dalvik是如何解析Manifest文件的,最后也沒(méi)有想到好的方法,收獲就是了解了android更底層一些的細(xì)節(jié),這個(gè)問(wèn)題現(xiàn)在先擱置了起來(lái)。 </p><p>  從測(cè)試代碼方面來(lái)看, Robotium中采用的是actionMethod(View, arg)的方式,TMT

46、S中采用getView(id).actionMethod(arg)的方式,更加符合java的編程習(xí)慣。TMTS測(cè)試代碼的編寫(xiě)也就是分三步,找到View,調(diào)用View的相應(yīng)的action方法,斷言。 </p><p>  TMTS框架主要思想就是通過(guò)反射機(jī)制調(diào)用Android框架層API拿到當(dāng)前Activity的所有View,在此基礎(chǔ)上返回需要獲得的View對(duì)象,對(duì)獲得的View通過(guò)Instrumentation封

47、裝一些此View常用的操作,最后返回,這就是TmtsView及其子類。 </p><p>  這種方式缺點(diǎn)也很明顯,對(duì)每個(gè)從android.View繼承來(lái)的子類,如果其中有特殊的操作,就需要封裝出一個(gè)對(duì)應(yīng)的TmtsView子類。 </p><p>  還有一個(gè)缺點(diǎn)就是目前是通過(guò)View在布局文件中聲明的id去尋找,這樣測(cè)試人員在編寫(xiě)代碼時(shí)需要對(duì)app的源碼非常熟悉,了解當(dāng)前操作的view的

48、id是多少,在傳遞id參數(shù)時(shí)還有可能寫(xiě)錯(cuò)。之后我們對(duì)這個(gè)方式進(jìn)行了一些改進(jìn),使用SDK自帶的hierarchyviewer工具獲得view的id;對(duì)每個(gè)布局文件進(jìn)行解析生成java類,這個(gè)類中會(huì)提供方法返回布局文件中的所有帶id的view,經(jīng)過(guò)討論,最后按view子類型來(lái)對(duì)一個(gè)布局中的view進(jìn)行歸類。 </p><p>  Bug的定位離不開(kāi)日志,因而日志系統(tǒng)也是一個(gè)測(cè)試框架重要的組成部分,Android的Lo

49、g類中提供了一系列的靜態(tài)方法可以在IDE中打印日志。在TMTS中,提供TmtsLog類,除日志打印外可將日志內(nèi)容實(shí)時(shí)保存至SD卡指定目錄,在框架代碼中的關(guān)鍵部位都加上了這樣的日志用來(lái)保存異常時(shí)的調(diào)用棧信息,用戶的測(cè)試代碼中也可以加上對(duì)TmtsLog的調(diào)用跟蹤測(cè)試代碼執(zhí)行進(jìn)度,TmtsLog將為每個(gè)測(cè)試類保存一份這樣的日志文件,同時(shí)包含用戶的過(guò)程日志和框架異常日志,文件名以精確到毫秒的日期加以區(qū)分。 </p><p&g

50、t;  項(xiàng)目做到這里遠(yuǎn)遠(yuǎn)沒(méi)有結(jié)束,套用屈原的一句話就是路漫漫其修遠(yuǎn)兮。 </p><p>  后面計(jì)劃解決的問(wèn)題有: </p><p>  1.跨進(jìn)程測(cè)試,讓testapp和app運(yùn)行在兩個(gè)不同的進(jìn)程中,這是一個(gè)大坑。 </p><p>  2.穩(wěn)定性問(wèn)題,目前框架中有很多地方硬編碼Thread.sleep()去等待一個(gè)View加載完成,避免對(duì)空的View進(jìn)行操作,

51、或者是對(duì)一個(gè)view進(jìn)行set操作后,也需要等待一段時(shí)</p><p>  間讓操作生效。希望能找到一種回調(diào)機(jī)制優(yōu)雅的解決。 </p><p>  而且Robotium提供的API是面向過(guò)程的,測(cè)試代碼的可擴(kuò)展性差。 </p><p>  我們需要一個(gè)面向?qū)ο蟮?,可?duì)WebView進(jìn)行操作的自動(dòng)化測(cè)試框架,這就催生了TMTS(Taobao Mobile Test S

52、tudio)框架。 </p><p>  TMTS立項(xiàng)時(shí)還試圖著重解決另一個(gè)問(wèn)題,就是Instrumentation框架下testapp和app運(yùn)行在一個(gè)進(jìn)程中 ,app crash會(huì)導(dǎo)致testapp一并crash。當(dāng)時(shí)和士敦一起研究了Instrumentation、Activity的啟動(dòng)流程,甚至想去研究一下dalvik是如何解析Manifest文件的,最后也沒(méi)有想到好的方法,收獲就是了解了android更底

53、層一些的細(xì)節(jié),這個(gè)問(wèn)題現(xiàn)在先擱置了起來(lái)。 </p><p>  從測(cè)試代碼方面來(lái)看, Robotium中采用的是actionMethod(View, arg)的方式,TMTS中采用getView(id).actionMethod(arg)的方式,更加符合java的編程習(xí)慣。TMTS測(cè)試代碼的編寫(xiě)也就是分三步,找到View,調(diào)用View的相應(yīng)的action方法,斷言。 </p><p>  

54、TMTS框架主要思想就是通過(guò)反射機(jī)制調(diào)用Android框架層API拿到當(dāng)前Activity的所有View,在此基礎(chǔ)上返回需要獲得的View對(duì)象,對(duì)獲得的View通過(guò)Instrumentation封裝一些此View常用的操作,最后返回,這就是TmtsView及其子類。 </p><p>  這種方式缺點(diǎn)也很明顯,對(duì)每個(gè)從android.View繼承來(lái)的子類,如果其中有特殊的操作,就需要封裝出一個(gè)對(duì)應(yīng)的TmtsVie

55、w子類。 </p><p>  項(xiàng)目做到這里遠(yuǎn)遠(yuǎn)沒(méi)有結(jié)束,套用屈原的一句話就是路漫漫其修遠(yuǎn)兮。后面計(jì)劃解決的問(wèn)題有: </p><p><b>  跨進(jìn)程測(cè)試</b></p><p>  讓testapp和app運(yùn)行在兩個(gè)不同的進(jìn)程中,這是一個(gè)大坑。 </p><p><b>  穩(wěn)定性問(wèn)題</b>

56、;</p><p>  目前框架中有很多地方硬編碼Thread.sleep()去等待一個(gè)View加載完成,避免對(duì)空的View進(jìn)行操作,或者是對(duì)一個(gè)view進(jìn)行set操作后,也需要等待一段時(shí)間讓操作生效。希望能找到一種回調(diào)機(jī)制優(yōu)雅的解決。 </p><p>  3.設(shè)法捕獲Toast消息 </p><p>  后面可能會(huì)研究的方向,是通過(guò)非java的方式來(lái)實(shí)現(xiàn)andr

57、oid自動(dòng)化測(cè)試。Android目前已經(jīng)通過(guò)ASE(Android Scripting Environment)支持了多種腳本語(yǔ)言,如phyton,lua,perl等,限于目前的人力還沒(méi)有時(shí)間來(lái)研究這一塊,相信ASE會(huì)給Android自動(dòng)化開(kāi)辟一片新天地。 </p><p>  最后談一點(diǎn)點(diǎn)感悟,老子曾經(jīng)曰過(guò):“持而盈之,不如其已;揣而銳之,不可長(zhǎng)保。金玉滿堂,莫之能守;富貴而驕,自遺其咎?!焙汀爸貫檩p根,靜為

58、躁君?!钡谝痪湓捳f(shuō)有缺陷才是真正的完美,沒(méi)有一個(gè)方案是真正完美的。第二句話說(shuō)有時(shí)候看起來(lái)完美的方案,過(guò)段時(shí)間之后又不適用了,而且不適用的地方很可能就是當(dāng)初覺(jué)得完美的地方,對(duì)于軟件項(xiàng)</p><p>  目解決方案也是如此。 </p><p>  測(cè)試工具中Service介紹</p><p><b>  Service概述</b></p&

59、gt;<p>  由于手機(jī)屏幕的限制,通常情況下在同一時(shí)刻僅有一個(gè)應(yīng)用程序牌激活狀態(tài),并能夠顯示在手機(jī)屏幕上,因此,應(yīng)用程序需要一種機(jī)制,在沒(méi)有用戶界面的情況下,合其能夠長(zhǎng)時(shí)間在后臺(tái)運(yùn)行,實(shí)現(xiàn)應(yīng)用程序的特定功能,并能夠處理事件或更新數(shù)據(jù),Android系統(tǒng)提供了(Service)服務(wù)組件,它不直接與用戶進(jìn)行交互,卻能夠長(zhǎng)期在后臺(tái)運(yùn)行。有很多情況需要使用Service,典型的例子就是:MP3播放器。</p>&

60、lt;p>  Service非常適用于無(wú)需用戶干預(yù),且需要長(zhǎng)期運(yùn)行的后臺(tái)功能。Service沒(méi)有用戶界面,有利于降低系統(tǒng)資源。而且Service比Activity具有更高的優(yōu)先級(jí),因此在系統(tǒng)資源緊張的時(shí)候,Service不會(huì)輕易被Android系統(tǒng)終止。即使Service被系統(tǒng)終止了,在系統(tǒng)資源恢復(fù)后Service也將自動(dòng)恢復(fù)運(yùn)行狀態(tài),因此可以認(rèn)為Service是在系統(tǒng)中永久運(yùn)行的組件。Service除了實(shí)現(xiàn)后臺(tái)服務(wù)功能,還可以用

61、于進(jìn)程間通信,解決兩個(gè)不同Activity應(yīng)用程序進(jìn)程之間的調(diào)用和通信問(wèn)題。</p><p>  Service概覽:</p><p><b>  類結(jié)構(gòu)圖:</b></p><p>  Service生命周期:</p><p><b>  三個(gè)生命周期函數(shù):</b></p><

62、p>  onCreate()</p><p><b>  onStart()</b></p><p><b>  onDestory</b></p><p><b>  生命周期圖:</b></p><p><b>  Service啟動(dòng)</b>&l

63、t;/p><p>  啟動(dòng)Service的兩種方式:startService 和bindService</p><p>  一、startService啟動(dòng)Service</p><p><b>  示例:</b></p><p>  1、 先創(chuàng)建一個(gè)類繼承于Service然后重寫(xiě)onBind()[且這個(gè)方法必須實(shí)現(xiàn)],on

64、Create()、onStart()、onDestory()方法</p><p>  2、 在AndroidMainfest.xml中注冊(cè)剛才寫(xiě)的這個(gè)Service</p><p>  view plainprint?</p><p>  <service android:name=".MyService" ></p>

65、<p>  <intent-filter ></p><p>  <action android:name="com.jiahui.myservice" /></p><p>  </intent-filter></p><p>  </service></p><p&

66、gt;  3、 通過(guò)在Activty中啟動(dòng)Service</p><p>  startServiceDemo:</p><p>  MyService繼承于Service類</p><p>  view plainprint?</p><p>  package com.jiahui.serviceDemo;</p><

67、p>  import android.app.Service;</p><p>  import android.content.Intent;</p><p>  import android.os.IBinder;</p><p>  public class MyService extends Service {</p><p>

68、<b>  @Override</b></p><p>  public IBinder onBind(Intent arg0) {</p><p>  // TODO Auto-generated method stub</p><p>  return null;</p><p><b>  }</b

69、></p><p><b>  @Override</b></p><p>  public void onCreate() {</p><p>  System.out.println("----onCreate-----");</p><p>  super.onCreate();</

70、p><p><b>  }</b></p><p><b>  @Override</b></p><p>  public void onDestroy() {</p><p>  System.out.println("----onDestory-----");</p>

71、;<p>  super.onDestroy();</p><p><b>  }</b></p><p><b>  @Override</b></p><p>  public void onStart(Intent intent, int startId) {</p><p> 

72、 System.out.println("----onStart-----");</p><p>  super.onStart(intent, startId);</p><p><b>  }</b></p><p><b>  }</b></p><p>  MainAct

73、ivty:</p><p>  view plainprint?</p><p>  package com.jiahui.serviceDemo;</p><p>  import android.app.Activity;</p><p>  import android.content.Intent;</p><p&

74、gt;  import android.os.Bundle;</p><p>  import android.view.View;</p><p>  import android.widget.Button;</p><p>  public class MainActivity extends Activity {</p><p>  

75、public void onCreate(Bundle savedInstanceState) {</p><p>  super.onCreate(savedInstanceState);</p><p>  setContentView(R.layout.main);</p><p>  Button btnStart = (Button) findViewBy

76、Id(R.id.btnStart);</p><p>  Button btnStop = (Button) findViewById(R.id.btnStop);</p><p>  final Intent service = new Intent();</p><p>  service.setAction("com.jiahui.myservice

77、");</p><p>  btnStart.setOnClickListener(new View.OnClickListener() {</p><p><b>  @Override</b></p><p>  public void onClick(View v) {</p><p>  // 啟動(dòng)Se

78、rvice</p><p>  MainActivity.this.startService(service);</p><p><b>  }</b></p><p><b>  });</b></p><p>  btnStop.setOnClickListener(new View.OnCli

79、ckListener() {</p><p><b>  @Override</b></p><p>  public void onClick(View v) {</p><p>  // 停止Service</p><p>  MainActivity.this.stopService(service);</p

80、><p><b>  }</b></p><p><b>  });</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  Service已創(chuàng)建則只會(huì)調(diào)用onStart()方法,st

81、opService將調(diào)用onDestory()方法</p><p>  除了通過(guò)startService來(lái)啟動(dòng)Service外我們還可以通過(guò)bindService()方法啟動(dòng)Service,也正好我們可以來(lái)好好比較這兩種方式的區(qū)別。</p><p>  bindService方法啟動(dòng)Service</p><p>  先看bindSerivce(Intent ser

82、vice,ServiceConnection conn,int flags)函數(shù)</p><p><b>  參數(shù)說(shuō)明:</b></p><p>  service:通過(guò)該參數(shù)也就是Intent我們可以啟動(dòng)指定的Service</p><p>  conn:該參數(shù)是一個(gè)ServiceConnection對(duì)象,這個(gè)對(duì)角用于監(jiān)聽(tīng)訪問(wèn)者(也可以說(shuō)成是

83、客戶端)與Service之間的連接情況,當(dāng)訪問(wèn)者與Service連接成功時(shí)將回調(diào)ServiceConnection對(duì)象的onServiceConnected(ComponentName name,Ibinder service)方法;如果斷開(kāi)將回調(diào)onServiceDisConnected(CompontName name)方法</p><p>  flags:指定綁定時(shí)是否自動(dòng)創(chuàng)建Service。</p&

84、gt;<p><b>  步驟:</b></p><p>  1、 新建一個(gè)類繼承于Service類,重寫(xiě)onBind()、onCreate()、onUnBind()、onDestory()方法。再在這個(gè)類里聲明一個(gè)Ibinder的子類對(duì)象用于提供于客戶端,同時(shí)可以定義一些成員變量,客戶端可以獲取到這個(gè)成員變量屬性</p><p>  2、 在Andro

85、idMainfest.xml文件中注冊(cè)這個(gè)Service</p><p>  3、 在Activity里通過(guò)bindService綁定Service</p><p><b>  示例代碼:</b></p><p>  package com.jiahui.serviceDemo;</p><p>  import and

86、roid.app.Service;</p><p>  import android.content.Intent;</p><p>  import android.os.Binder;</p><p>  import android.os.IBinder;</p><p>  public class MyService extends

87、 Service {</p><p>  private int count;</p><p>  private boolean quit;</p><p>  private MyBinder binder = new MyBinder();</p><p>  // 新建一個(gè)Binder對(duì)象用于提供給客戶端</p><

88、;p>  public class MyBinder extends Binder {</p><p>  public int getCount() {</p><p>  return count;</p><p><b>  }</b></p><p><b>  }</b></p

89、><p><b>  @Override</b></p><p>  public IBinder onBind(Intent intent) {</p><p>  System.out.println("----onBind-----");</p><p>  // 返回給客戶端一個(gè)Binder對(duì)象&

90、lt;/p><p>  return binder;</p><p><b>  }</b></p><p><b>  @Override</b></p><p>  public void onCreate() {</p><p>  System.out.println(&

91、quot;----onCreate-----");</p><p>  // 啟動(dòng)一條線程修改成員變量屬性</p><p>  new Thread() {</p><p><b>  @Override</b></p><p>  public void run() {</p><p>

92、;  while (!quit) {</p><p><b>  try {</b></p><p>  Thread.sleep(1000);</p><p>  } catch (Exception e) {</p><p><b>  }</b></p><p><

93、;b>  count++;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  }.start();</p><p><b>  }</b></p><p><b>  

94、@Override</b></p><p>  public void onDestroy() {</p><p>  this.quit = true;</p><p>  System.out.println("----onDestory-----");</p><p>  super.onDestroy(

95、);</p><p><b>  }</b></p><p><b>  @Override</b></p><p>  public boolean onUnbind(Intent intent) {</p><p>  System.out.println("----onUnbind-

96、----");</p><p>  return super.onUnbind(intent);</p><p><b>  }</b></p><p><b>  }</b></p><p>  MainActivty</p><p>  package com.

97、jiahui.serviceDemo;</p><p>  import android.app.Activity;</p><p>  import android.content.ComponentName;</p><p>  import android.content.Intent;</p><p>  import android

98、.content.ServiceConnection;</p><p>  import android.os.Bundle;</p><p>  import android.os.IBinder;</p><p>  import android.view.View;</p><p>  import android.widget.But

99、ton;</p><p>  import android.widget.Toast;</p><p>  public class MainActivity extends Activity {</p><p>  private Button btnBind;</p><p>  private Button btnUnBind;<

100、/p><p>  private Button btnGetData;</p><p>  MyService.MyBinder binder;</p><p>  // 定義一個(gè)ServiceConnection對(duì)象</p><p>  private ServiceConnection conn = new ServiceConnection

101、() {</p><p>  // 當(dāng)客戶端與Service斷開(kāi)連接時(shí)</p><p><b>  @Override</b></p><p>  public void onServiceDisconnected(ComponentName name) {</p><p>  System.out.println(&q

102、uot;---onServiceDisconnected----");</p><p><b>  }</b></p><p>  // 當(dāng)客戶端與Service建立連接時(shí)</p><p><b>  @Override</b></p><p>  public void onServic

103、eConnected(ComponentName name, IBinder service) {</p><p>  System.out.println("---onServiceConnected----");</p><p>  binder = (MyService.MyBinder) service;</p><p><b>

104、;  }</b></p><p><b>  };</b></p><p>  public void onCreate(Bundle savedInstanceState) {</p><p>  super.onCreate(savedInstanceState);</p><p>  setConten

105、tView(R.layout.main);</p><p>  btnBind = (Button) findViewById(R.id.btnBind);</p><p>  btnUnBind = (Button) findViewById(R.id.btnUnBind);</p><p>  btnGetData = (Button) findViewById

106、(R.id.btnGetData);</p><p>  final Intent intent = new Intent();</p><p>  intent.setAction("com.jiahui.myservice");</p><p>  btnBind.setOnClickListener(new View.OnClickList

107、ener() {</p><p><b>  @Override</b></p><p>  public void onClick(View v) {</p><p>  // 綁定Service</p><p>  bindService(intent, conn, BIND_AUTO_CREATE);</p&

108、gt;<p><b>  }</b></p><p><b>  });</b></p><p>  btnUnBind.setOnClickListener(new View.OnClickListener() {</p><p><b>  @Override</b></p&g

109、t;<p>  public void onClick(View v) {</p><p><b>  // 解除綁定</b></p><p>  unbindService(conn);</p><p><b>  }</b></p><p><b>  });</b

110、></p><p><b>  //獲取數(shù)據(jù)</b></p><p>  btnGetData.setOnClickListener(new View.OnClickListener() {</p><p><b>  @Override</b></p><p>  public void o

111、nClick(View v) {</p><p><b>  // 獲取數(shù)據(jù)</b></p><p>  Toast.makeText(MainActivity.this,</p><p>  "Service的count值為" + binder.getCount(),</p><p>  Toast

112、.LENGTH_LONG).show();</p><p><b>  }</b></p><p><b>  });</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  點(diǎn)擊

113、” 獲取Service里的數(shù)據(jù)”按鈕</p><p>  點(diǎn)擊“unBindService”按鈕</p><p>  所以也可以通過(guò)上圖知道bindService的生命周期</p><p>  bindService會(huì)經(jīng)歷onCreate()-->onBind()-->onUnbind()-->onDestory</p><p&

114、gt;  如何去理解這種通信方式?</p><p>  我的理解是bindService這一方我們可以看作是客戶端,然后客戶端調(diào)用bindService()方法去綁定一個(gè)Service,Service給我們返回一個(gè)Binder對(duì)象用于客戶端與Serivce通信,而這個(gè)Binder對(duì)象我們可以在客戶端的ServiceConnection對(duì)象里的一個(gè)onServiceConnected()方法取到這個(gè)Binder對(duì)象

115、,這樣我們就也能取到Service里的數(shù)據(jù)了</p><p><b>  所以總結(jié):</b></p><p>  bindService與startService 的區(qū)別:</p><p>  1. 生命周期 :startService() 方式啟動(dòng) ,Service 是通過(guò)接受Intent 并且會(huì)經(jīng)歷</p><p>

116、  onCreate()和onStart() .當(dāng)用戶在發(fā)出意圖使之銷毀時(shí)會(huì)經(jīng)歷onDestroy () ,而bindService () 方</p><p>  式啟動(dòng) ,與Activity 綁定的時(shí)候 ,會(huì)經(jīng)歷onCreate() 和onBind () ,而當(dāng)Activity 被銷毀的時(shí)候,Service 會(huì)先調(diào)用onUnbind () 然后是onDestroy () 。</p><p&g

117、t;  2. 控制方式 :前者的控制方式需要使用固定的方法,對(duì)Service 進(jìn)行單一的操作。而后者由于與Activity 綁定 ,不用考慮其生命周期問(wèn)題 ,并且從發(fā)送Intent 的被動(dòng)操作 ,變?yōu)榭梢灾鲃?dòng)對(duì)Service 對(duì)象進(jìn)行操作,我們甚至可以建立一個(gè)Handler 類,對(duì)Service 進(jìn)行相關(guān)的操作。大大加強(qiáng)了Service 的靈活性、可操作性。</p><p>  總結(jié) : 對(duì)于簡(jiǎn)單的應(yīng)用start

118、Service() 啟動(dòng)方式能帶來(lái)更少的代碼 , 簡(jiǎn)單的操作 。 對(duì)于復(fù)雜的應(yīng)用bindService () 方式,雖然帶來(lái)的更多的編碼,但同時(shí)也帶來(lái)了更好的可操作性,使其使用起來(lái)更方便。</p><p><b>  總體設(shè)計(jì)</b></p><p><b>  概述</b></p><p><b>  程序說(shuō)明

119、</b></p><p>  本項(xiàng)目主要通過(guò)Android自動(dòng)化測(cè)試工具對(duì)AP進(jìn)行手動(dòng)設(shè)定,自動(dòng)執(zhí)行的測(cè)試工作。</p><p>  PC機(jī)上運(yùn)用Eclipse編輯程序代碼以及對(duì)程序代碼進(jìn)行調(diào)試,利用Android模擬器進(jìn)行程序的測(cè)試。</p><p>  編譯成功后即可在Android模擬器上運(yùn)行程序,進(jìn)行TestCase的壓入,手動(dòng)設(shè)定,進(jìn)而執(zhí)行程序

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論