首先由于我自己也是個新手,也是在學(xué)習(xí)各種框架然后給公司項目選定相應(yīng)自動化框架,研究移動自動化測試框架也就近段時間而已,所以我只能從我自己今天為止的認(rèn)知角度給各個框架抒發(fā)我自己的拙見,你看是否能從中接納一二吧(對于我自己的話還需要再花一段時間去學(xué)習(xí)各個框架才能確定哪個/些是適合我們項目的了,也許到時我會寫個正式的總結(jié))。
成都創(chuàng)新互聯(lián)公司服務(wù)項目包括包頭網(wǎng)站建設(shè)、包頭網(wǎng)站制作、包頭網(wǎng)頁制作以及包頭網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,包頭網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到包頭省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
根據(jù)你的要求,應(yīng)該不會考慮MonkeyRunner和Robotium,但我還是想跟你說下其實Robotium還是挺不錯的,如果你沒有考慮跨進(jìn)程調(diào)用其他APP的話。至于MonkeyRunner我就不大推薦了,你可以看下我對金陽光老師的一個評論的回復(fù)《MonkenRunner通過HierarchyViewer定位控件的方法和建議》(文章最后我干脆也貼出來了)。至于Robotium,你對比下本人博客里面各個框架編寫的Note的測試示例就可以看出來Robotium相對其他框架會簡介很多,況且發(fā)展的比UIAutomator和Appium長久很多,所以也應(yīng)該會更成熟,和Eclipse集成調(diào)試起來也很方便。比起后兩者如果有不足的話我覺得就以下幾點吧:
1. 所有的操作抽象到一個Solo類里面,缺乏面向?qū)ο蟮木幊趟枷?,有時會讓人不適應(yīng)。如果你熟悉C語言等面向過程的語言思想的話應(yīng)該沒有問題。
2. 獲取控件的方法比較缺乏,大概就幾種:通過Text,ID, ClassName,Index。沒有后兩者的多種多樣
3. 跨進(jìn)程:因為底層使用Instrument框架,測試包和被測應(yīng)用包打包在一起作為一個進(jìn)程運行而線程間通過instrumentaiton進(jìn)行通信,導(dǎo)致了逃不出這個進(jìn)程設(shè)沙箱(sandbox)
4. 做不了模擬鍵盤的測試(但同時這個也是Robotium非常巨大的優(yōu)點,因為不像后兩者那樣需要調(diào)用鍵盤導(dǎo)致輸入的各種各樣的問題),因為Robotium輸入讀出其實是直接對控件的text屬性進(jìn)行操作沒有通過鍵盤驅(qū)動的,你如果做過UI編程應(yīng)該就明白我的意思了,因為記住你的測試代碼和目標(biāo)應(yīng)用是打包在同一個進(jìn)程中的,同一個進(jìn)程中想訪問另外一個線程的某個變量,運用相應(yīng)的IPC(Interprocess Communication)機(jī)制當(dāng)然是沒有問題的了。
然后到了你問的主題UIAutomator和Appium的對比,我個人是這樣看的:
1. UIAutomator是親爹(google)生的,所以可以保證后續(xù)的開發(fā)維護(hù)力量,除非google倒閉(這里我有點不懂的是為什么google對Monkeyrunner的態(tài)度這么讓人摸不著頭腦,具體請看以上我說的對MonkeyRunner的評論)
2. Appium雖然不是親爹生的,但是干爹實力雄厚把它武裝的無所不能(android,ios,firefox,browser通殺),單單以android來說,底層用得還是UIAutomator,所以只要它能及時跟上UIAutomator的更新,功能上面我不是很擔(dān)心。
3. 但是也這是Appium的這種架構(gòu):UIautomator/seledroid-Appium Server-Selenium/AppiumDriver-Test Case (《Appium架構(gòu)框架圖整理》),導(dǎo)致框架有點復(fù)雜,當(dāng)問題出現(xiàn)的時候調(diào)試起來比較難以定位,不知道哪個模塊出錯了。但是說道調(diào)試,總比UIAutomator好,起碼Appium可以直接集成到eclipse上面進(jìn)行debug,UiAutomator卻每次都要push到目標(biāo)機(jī)器然后再去執(zhí)行,怎么調(diào)試呢?到現(xiàn)在為止我知道的只能原始的print了。
4. 向下兼容問題:Appium可以通過底層UIAutomator/Selendroid(不記得是不是這名字了)通殺;UIAutomator只能在API Level
17(包含)以上使用
5.語言支持:appium基本通殺,UIAutomator用java足矣
6.跨平臺:如你所說的只是android兩者都沒有問題,如果往后需要擴(kuò)展到ios,那么建議appium
7.bug數(shù)量:UIAutomator有的問題Appium都會有,UIAutomator沒有的問題Appium也有可能有^_^(不過我還是很看好Appium的)
8. 輸入問題,都有bug,具體請查看我相應(yīng)blog,特別是中文輸入,這就是為什么我剛才特意提出Robotum的原因之一
9. WebView支持:UIAutomator據(jù)說今年年初已經(jīng)開始支持,個人沒有這方面要求所以沒研究;Appium的框架用的Selenium本身就是PC上最流行的開源Web測試框架,所以必然支持了。注意這你你要有點android編程知識了,WebView指的不僅是WebView控件還包含如用sencha+phonegap把webview封裝成一個跨平臺app的情況了,具體如果不清楚請google。
其他區(qū)別我現(xiàn)在就沒有想到了,希望能幫助到你,從我自己的角度來看,我覺得UIAutomator繼續(xù)往前發(fā)展是必然的了,但是它不可能最終支持ios。至于Appium我同樣有很大的信心它會繼續(xù)往好的方向發(fā)展,且考慮到它的跨平臺支持,基于node.js(現(xiàn)在非常流行哦),兼容性等,我如果是你的話我會考慮用Appium的(拋開Robotium不說,如果你又要考慮的話就需要你根據(jù)我之前說的再總結(jié)下了^_^)。
我覺得這個可以類比之前的微軟和Borland的關(guān)系,API是Windows,但是IDE是Borland的,各專所長了??上Вɑ蛘邞c幸)后來微軟發(fā)力一下把Borland打得滿地找牙一蹶不振,不過這是題外話了,略過......
對了,我有可能會對這封郵件整理下發(fā)到博客了,也希望其他網(wǎng)友能評點一二給你出主意。今晚本來想看下easy_monkey的知識了,給你寫這個email變成臨時性總結(jié)了。^_^
給金陽光老師評論的回復(fù)如下(關(guān)于MonkeyRunner的個人觀點)
-----------------------------------------------------------------------------------------------------------------
回復(fù)haorenmin2008:首先膜拜下,金老師大駕光臨蓬蓽生輝?。?/p>
對于后者,確實如此,UIAutomator需要API Level17(包含)以上。
對于前者,因為還沒有MonkeyRunner的項目經(jīng)驗,所以是否很強(qiáng)大我就不敢妄加評論了,但是在我近來的tryout過程中,鄙人有以下的一些不成熟的認(rèn)知:
1. 感覺功能不是很穩(wěn)定,之前嘗試一個MonkeyDevice的getProperty方法,竟然有時成功有時失敗。
2. 性能不好,特別是當(dāng)我們要用到hierarchyviewer的功能的時候很明顯。
3. 只能用MonkeyImage的sameAs做截屏的對比,雖然加上hierarchyviewer后可以用它的getText,但還是很有限。
4. 控件定位方面主要是坐標(biāo)點和HierarchyViewer提供的根據(jù)ID。前這兒在UI布局稍微有調(diào)整位置的話就需要跟著變動,沒有像其他控件類框架那樣做高層抽象除非換控件不然都不需要怎么變動;后者的話很多控件是沒有id或者是有多個控件id相同的。
5. 可調(diào)試性也不強(qiáng)(起碼我摸索了這幾天沒有發(fā)現(xiàn)一個很好的調(diào)試方法,比如IDE Ecilpse等的集成調(diào)試方法)
6. HierarchyViewer的穩(wěn)定性也讓我擔(dān)憂,碰到過幾次取控件信息的時候報exception的。
7. 資料稀缺,不僅百度,google也一樣
8. Google支持讓人覺得摸不著頭腦,sdk給出的API和官方提供的API竟然不一致,以MonkeyDevice為例子,而sdk多出來的API竟然還不能用,google出來的信息不超過10個page,還要很多都是重復(fù)的石沉大海的網(wǎng)友報的問題。
9. 再一個的我真心搞不懂為什么本身java寫的庫非要搞個jython來調(diào)用,首先我不說性能損耗(這點肯定是有的,native庫當(dāng)然用native語言調(diào)用效率最好嘛),我想在eclipse上對以下的"device."做自動補(bǔ)全是做不到的“device = MonkeyRunner.waitForConnection()\n device.",而只有直接調(diào)用個構(gòu)造函數(shù)實例化的device = MonkeyDevice(xxx)才能做到,這個我不相信是我配置的問題,換了個jython標(biāo)準(zhǔn)編譯器以調(diào)用標(biāo)準(zhǔn)庫問題同樣存在。
項目中經(jīng)常會進(jìn)行打包分發(fā), 但是常規(guī)的打包過程不免會非常的乏味無聊, 重復(fù)性的勞動, 實在沒啥意思, 今天就來介紹fastlane工具進(jìn)行android自動打包, 上傳蒲公英(也可以firim)并進(jìn)行釘釘群組通知相關(guān)人員。
Fastlane是一整套的客戶端CICD工具集合。Fastlane可以非??焖俸唵蔚拇罱ㄒ粋€自動化發(fā)布服務(wù),并且支持Android,iOS,MacOS。
Fastlane命令執(zhí)行的底層并不是自己實現(xiàn)的,而是調(diào)用其他的插件或者工具執(zhí)行的。比如說打包,F(xiàn)astlane中的gym工具只是xcodebuild工具的一個封裝,調(diào)用的其實還是xcodebuild中的打包命令。
Fastlane本身沒有一套特殊語法,使用的Ruby語言。
Fastlane的插件工具叫做action,每一個action都對應(yīng)一個具體的功能。
1、蘋果系統(tǒng)自帶有ruby
2、安裝今天的主角fastlane
通過修改用戶讀寫權(quán)限可以解決
3、安裝蒲公英的 Fastlane 插件
如果遇到這種情況:Could not find action, lane or variable 'pgyer'.
可能是你安裝pgyer插件的時候,不是在項目fastlane文件夾下安裝的,重新安裝一下就可以解決上面的錯誤。
4、安裝獲取應(yīng)用版本的 Fastlane 插件
如果出現(xiàn)類似pgyer的錯誤,同理在項目fastlane文件夾下重新安裝就可以避免找不到插件的命令錯誤。
在使用 Fastlane 之前,我們首先需要在項目中初始化 Fastlane。首先進(jìn)入 App 的開發(fā)目錄,執(zhí)行以下命令來初始化 Fastlane:
激動人心的時刻終于來了,開始打包。
啟動Jenkins
1、 安裝jdk
從略,建議1.6或以上版本,配置好環(huán)境變量。
2、 安裝tomcat
從略,安裝完調(diào)試下tomcat是否正常。
3、 安裝ant
下載zip包,解壓后配置好環(huán)境變量。
4、 安裝jenkins
下載war包,命名為Jenkins,拷貝到tomcat/webapps目錄下。
5、 安裝Android SDK
下載安裝,完成后配置好Android_SDK_HOME環(huán)境變量。此步驟主要用于進(jìn)行android自動化測試,若不進(jìn)行此項可略過。
安裝完成后啟動tomcat/bin/startup.bat文件(linux下是startup.sh),在瀏覽器輸入,8080為tomcat端口,即可訪問jenkins服務(wù)器。
配置Jenkins
1、 JDK配置
新增JDK,指定JDK名字和JAVA_HOME
2、 ANT配置
新增ANT,指定ANT名字和ANT_HOME
3、 Maven配置
從略,本文未使用到Maven,具體配置方法參考Google。
4、 Subversion
選擇1.6版本SVN,勾選Update default Subversion credentials cache after successful authentication
5、 郵件通知
填寫SMTP server、Default user E-mail suffix、System Admin E-mail Address、Jenkins URL、勾選Use SMTP Authentication,填寫User Name、Password、Use SSL、SMTP port、Chareset(UTF-8) 、Default Content Type(默認(rèn))、Default Recipients(默認(rèn)收件人),配置完成后可進(jìn)行測試郵件。
6、 Jenkins URL
配置該URL,用于別人訪問。
插件管理
1、 Hudson Subversion Plug-in,jenkins的svn插件。
2、 Android Emulator Plugin,android模擬器插件。
3、 JUnit Attachments Plugin,junit測試報告附件插件。
4、 Email-ext plugin,郵件擴(kuò)展插件。此處說明下,默認(rèn)Jenkins只會發(fā)送構(gòu)建失敗的郵件,我們需安裝此插件才能自定義不同場景。
5、 Deploy to container Plugin遠(yuǎn)程發(fā)布插件。
自動化測試
打包源工程
Android程序
本小節(jié)講訴如何打包一個Android工程,當(dāng)前使用的是ant進(jìn)行編譯源碼。
1、 首先構(gòu)建一個自由風(fēng)格的Job。
2、 添加源碼路徑,選擇所使用的版本控制器,輸入源碼路徑。
3、 構(gòu)建觸發(fā)器可根據(jù)需要選擇是否定時構(gòu)建。
4、 構(gòu)建環(huán)境,此處Jenkins安裝了Android Emulator Plugin插件,可以啟動已有模擬器或添加新的模擬器,本文案例中使用真機(jī)調(diào)試。
5、 構(gòu)建,卸載手機(jī)中原程序 adb –s uninstall com.XXXXXX
6、 生成bulid.xml文件,-p后面跟工程所在的本地jenkins下路徑
android update project -n *** c:\被測工程Job路徑\workspace
7、 Ant進(jìn)行編譯程序,并安裝到當(dāng)前手機(jī)中
ant debug install -f c:\被測工程Job路徑\workspace\build.xml
8、 構(gòu)建后操作,本案例中構(gòu)建完成后自動啟動構(gòu)建下一個測試Job
Bulid other projects,選擇測試工程的Job.
打包測試工程
Android程序
本小節(jié)講訴如何構(gòu)建一個Android測試工程,包括郵件發(fā)送和測試報告展示。
1、 構(gòu)建步驟1-7和Android程序章節(jié)一樣,從略。
2、 本文案例中測試程序是通過命令行啟動運行的,所以在此處增加一個批處理運行。P.S. adb shell am instrument -w -e class com.megafon.test.MegafonTest#testDeleteContact com.megafon.test/android.test.InstrumentationTestRunner ,此處是通過批處理來單獨運行一個個的測試用例。避免了Junit3的無序執(zhí)行的問題。
3、 刪除Workspace中原來存在的測試報告文件,一般不刪除也會覆蓋。
如何讓測試程序生成xml格式的測試報告,其他文章會重點介紹。
4、 從手機(jī)中拷貝測試報告,最終測試是在手機(jī)上運行,所以報告也生成在手機(jī)中,使用adb pull命令把測試報告全部拷貝到workspace下制定目錄。
5、 構(gòu)建后操作,發(fā)布測試報告,如果報告中包含附件,此處使用到JUnit Attachments Plugin插件。
6、 郵件通知,此處使用到Email-ext plugin插件,前面的默認(rèn),直接使用我們在系統(tǒng)管理里面設(shè)置的默認(rèn)值。
7、 點擊右下角高級按鈕,可選擇不同場景下發(fā)送郵件。
8、 測試結(jié)果展示,在本次構(gòu)建的控制臺可以顯示當(dāng)前所有的構(gòu)建日志。
9、測試報告點擊Test Result可以顯示所有測試記錄。
1、Monkey是Android SDK自帶的測試工具,在測試過程中會向系統(tǒng)發(fā)送偽隨機(jī)的用戶事件流,如按鍵輸入、觸摸屏輸入、手勢輸入等),實現(xiàn)對正在開發(fā)的應(yīng)用程序進(jìn)行壓力測試,也有日志輸出。實際上該工具只能做程序做一些壓力測試,由于測試事件和數(shù)據(jù)都是隨機(jī)的,不能自定義,所以有很大的局限性。
2、MonkeyRunner也是Android SDK提供的測試工具。嚴(yán)格意義上來說MonkeyRunner其實是一個Api工具包,比Monkey強(qiáng)大,可以編寫測試腳本來自定義數(shù)據(jù)、事件。缺點是腳本用Python來寫,對測試人員來說要求較高,有比較大的學(xué)習(xí)成本。
3、Instrumentation是早期Google提供的Android自動化測試工具類,雖然在那時候JUnit也可以對Android進(jìn)行測試,但是Instrumentation允許你對應(yīng)用程序做更為復(fù)雜的測試,甚至是框架層面的。通過Instrumentation你可以模擬按鍵按下、抬起、屏幕點擊、滾動等事件。Instrumentation是通過將主程序和測試程序運行在同一個進(jìn)程來實現(xiàn)這些功能,你可以把Instrumentation看成一個類似Activity或者Service并且不帶界面的組件,在程序運行期間監(jiān)控你的主程序。缺點是對測試人員來說編寫代碼能力要求較高,需要對Android相關(guān)知識有一定了解,還需要配置AndroidManifest.xml文件,不能跨多個App。
4、UiAutomator也是Android提
1、確定jdk安裝完畢,且檢查環(huán)境變量
2、確定android SDK安裝完畢,且檢查環(huán)境變量
3、確定你的appium和nodejs均安裝完畢,且環(huán)境變量設(shè)置完畢,可以通過cmd命令行:appium-doctor中確定
4、真機(jī)開啟了usb調(diào)試模式,通過命令行執(zhí)行:appium -a 127.0.0.1 -p 4723 -U N2F4C15A30001571 --no-reset ,其中-u后面的部分是手機(jī)的devices。來建立手機(jī)端和appium服務(wù)器的連接
5、在初始化程序設(shè)置一些運行時的狀態(tài),如appium版本,手機(jī)版本,型號,系統(tǒng)類型。設(shè)置待測試的app packagename和activityname
6、test類中寫入操作,進(jìn)行自動化測試
該腳本是我在獨立開發(fā)過程中,為了提升 Android 應(yīng)用打包和運營的效率而開發(fā)的腳本。項目地址是,
如項目中的語言構(gòu)成展示的,該腳本完全使用 Python 語言開發(fā)完成。
使用起來非常簡單,首先你要準(zhǔn)備如下的環(huán)境,
然后,通過編輯配置文件 config.yml 對腳本進(jìn)行配置。比如,
YAML 格式也不算新穎,早在幾年之前的 SpringBoot 里面就已經(jīng)采用了這種格式。相比于使用 json 或者 properties 等格式的配置文件,它更加簡潔。
1、使用 gradle 指令自動打包,區(qū)分 32 位和 64 位 :因為現(xiàn)在有些應(yīng)用市場明確要求區(qū)分 32 位和 64 位,所以,打包的時候要分開進(jìn)行打包。
2、打包完成之后將 APK 拷貝到指定的目錄 :主要用來做本地的 APK 文件備份,后面也會用這里拷貝的 APK 文件進(jìn)行自動化加固。
3、使用 diffuse 輸出相對于上一個版本的 APK 版本差異報告 :diffuse 是 JakeWharton 開發(fā)的 APK, AAB, AAR 和 JAR 的對比工具。這里我用它對比當(dāng)前版本和上一個版本的 APK 的信息,以實現(xiàn)對 APK 質(zhì)量的監(jiān)控。diffuse 項目的地址是
3、拷貝多語言資源到指定的目錄,并自動提交到 Github 倉庫以便于協(xié)助翻譯 :對做國際化的應(yīng)用的開發(fā)者而言,我們可以通過應(yīng)用內(nèi)的協(xié)助翻譯功能借助社區(qū)的力量實現(xiàn)應(yīng)用的多語言。這里我盡量將這個過程做得更加自動化。即在應(yīng)用打包完成之后將應(yīng)用內(nèi)的多語言資源按照版本信息拷貝到指定的目錄下。然后使用 Git 工具將其推送到 Github 等。具體的效果可以參考 .
4、自動打 tag 并提交到遠(yuǎn)程倉庫 :該功能用來在打包完成之后使用為當(dāng)前版本添加 Git tag,以便于后續(xù)根據(jù)版本回滾到指定的 Git 提交記錄。
5、根據(jù) Git 提交記錄自動生成更新日志 :上面做了為項目自動添加 Git tag 的功能之后,我們可以根據(jù)當(dāng)前版本到上一版本之間的 Git 提交記錄的 comment 信息自動生成版本更新日志。雖然,這個這樣生成的更新日志并不能直接用作發(fā)布時的更新記錄,但在至少可以讓我們直觀得看到這個版本修改了什么。
6、使用 360 加固 對上述 APK 進(jìn)行加固并輸出到指定的目錄 :加固操作其實非常簡單,只需要一個 command 指令就可以完成了,
不過在使用上述命令之前需要先通過 GUI 的形式修改你在 360 加固中的渠道和簽名信息(直接手動改文件也可以)。
7、上傳打包 APK 到藍(lán)奏云 :藍(lán)奏云是現(xiàn)在很多開發(fā)者用來分享軟件的一個云存儲平臺,100M 以下的文件可以免費存儲,類似于百度云。上傳藍(lán)奏云之前需要先修改配置文件,
這里需要填入的 ylogin 和 phpdisk_info 可以在登錄之后通過 Chrome 的開發(fā)工具查看 cookie 信息得到。目前能夠做到自動化的一個方案就是使用上述兩個信息。
8、通過 Telegram bot 將打包完成的渠道包和更新日志信息發(fā)送到 Telegram 群組 :對海外的用戶我們可以通過 Telegram 作為一個交流的渠道。Telegram 是一個非常好用的聊天軟件。它提供了 bot 功能,即一個可以推送消息的機(jī)器人。我們可以通過這個功能來在群組中推送消息、圖片和文件。Telegram 的 bot 有非常強(qiáng)大的自定義性。其實我們完全可以基于爬蟲和 bot 維護(hù)一個社區(qū),然后通過在社區(qū)內(nèi)推送廣告來獲得一些利益。這也不失為一個賺錢的渠道。使用 Telegram bot 之前需要在配置文件中填入如下信息,
這里的 token 是注冊 bot 的時候得到的信息。chat_id 可以通過如下方式獲取到:
即將 token 信息填入到上述 YourBOTToken 處。在返回的 json 結(jié)果中可以獲取到 chat id 信息。
向群組推送信息的方式非常簡單,一個 http 請求即可完成,
更多的協(xié)議可以參考這個文檔:
9、完成上述操作之后使用郵件通知打包結(jié)果 :最后就是在完成了最終的打包操作之后通過 Email 發(fā)送一封郵件,內(nèi)部包含了本次打包的 diff 信息等給指定的用戶。使用郵件功能需要在配置文件中填寫,
這里我們使用的是 QQ 郵箱來發(fā)送郵件。這里需要填寫的 user 和 password 字段分別是郵箱和開通 smtp 服務(wù)時系統(tǒng)提供的密碼信息。QQ 郵箱開通 SMTP 服務(wù)器其 官方文檔 即可。
上述是該打包腳本的主要功能。后續(xù)我會添加更多功能。因為時間有限,有些功能需要修改一下才能使用。不過,許多功能我都封裝成了獨立的 Python 腳本,如果需要的話可以自己做細(xì)微的修改。對于這個腳本,如果你有更好的建議和想法,可以跟我交流~
網(wǎng)站欄目:android自動化,Android自動化打包
文章網(wǎng)址:http://sd-ha.com/article46/dsspihg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、云服務(wù)器、全網(wǎng)營銷推廣、軟件開發(fā)、品牌網(wǎng)站制作、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)