Appium簡介和環(huán)境搭建

Appium簡介和環(huán)境搭建
espresso 是白盒測試框架, 通常是給開發(fā)人員用的,
monkey 是任意的在應(yīng)用界面亂點(diǎn)亂劃,適合壓力測試
monkeyrunner 有點(diǎn)類似UIAutomator,但是 通常是固定的根據(jù)坐標(biāo)點(diǎn)擊特點(diǎn)

特點(diǎn)
appium 是一個(gè)自動(dòng)化測試開源工具,支持 iOS 平臺(tái)和 Android 平臺(tái)上的原生應(yīng)用,web應(yīng)用和混合應(yīng)用。

  • “移動(dòng)原生應(yīng)用”是指那些用iOS或者 Android SDK 寫的應(yīng)用(Application簡稱app)。
  • “移動(dòng)web應(yīng)用”是指使用移動(dòng)瀏覽器訪問的應(yīng)用(appium支持iOS上的Safari和Android上的 Chrome)。
  • “混合應(yīng)用”是指原生代碼封裝網(wǎng)頁視圖——原生代碼和 web 內(nèi)容交互。比如,像 Phonegap,可以幫助開發(fā)者使用網(wǎng)頁技術(shù)開發(fā)應(yīng)用,然后用原生代碼封裝,這些就是混合應(yīng)用。

重要的是,appium是一個(gè)跨平臺(tái)的工具:它允許測試人員在不同的平臺(tái)(iOS,Android)使用同一套API來寫自動(dòng)化測試腳本,這樣大大增加了iOS和Android測試套件間代碼的復(fù)用性。

appium與Selenium
appium類庫封裝了標(biāo)準(zhǔn)Selenium客戶端類庫,為用戶提供所有常見的JSON格式selenium命令以及額外的移動(dòng)設(shè)備控制相關(guān)的命令,如多點(diǎn)觸控手勢和屏幕朝向。

appium客戶端類庫實(shí)現(xiàn)了Mobile JSON Wire Protocol(一個(gè)標(biāo)準(zhǔn)協(xié)議的官方擴(kuò)展草稿)和W3C WebDriver spec(一個(gè)傳輸不可預(yù)知的自動(dòng)化協(xié)議,該協(xié)議定義了MultiAction 接口)的元素。

appium服務(wù)端定義了官方協(xié)議的擴(kuò)展,為appium 用戶提供了方便的接口來執(zhí)行各種設(shè)備動(dòng)作,例如在測試過程中安裝/卸載App。這就是為什么我們需要appium特定的客戶端,而不是通用的Selenium 客戶端。當(dāng)然,appium 客戶端類庫只是增加了一些功能,而實(shí)際上這些功能就是簡單的擴(kuò)展了Selenium 客戶端,所以他們?nèi)匀豢梢杂脕磉\(yùn)行通用的Selenium會(huì)話。

appium是什么?有什么用

我們學(xué)習(xí)的移動(dòng)應(yīng)用自動(dòng)化,是基于appium這樣的一個(gè)自動(dòng)化框架的
Appium是一個(gè)開源、跨平臺(tái)(測試程序跨平臺(tái)、支持多平臺(tái)上的app測試)
多語言支持的(開發(fā)語言)移動(dòng)應(yīng)用 自動(dòng)化工具

測試移動(dòng)app 類型:
【原生app】是專門針對某一類移動(dòng)設(shè)備(比如蘋果、安卓)而開發(fā)的,所有界面和代碼都是專門為平臺(tái)設(shè)計(jì)的。比如:計(jì)算器【架構(gòu)c/s】
【混合(Hybrid)app(H5)】主要是指 它的一部分是原生界面和代碼,而另一部分是內(nèi)嵌web app 。 這個(gè)大家應(yīng)該有體會(huì),可以打開網(wǎng)頁瀏覽的app都是 混合app,比如微信、支付寶、美團(tuán)、移動(dòng)營業(yè)廳、開發(fā)者頭條等。
比如微信的sms界面是原生,原生代碼實(shí)現(xiàn)的。 【架構(gòu)c/s】
而打開某個(gè)朋友圈,或者別人發(fā)來的的鏈接部分則是 web部分,內(nèi)嵌了一個(gè)瀏覽器內(nèi)核,由瀏覽器內(nèi)核實(shí)現(xiàn)的。
現(xiàn)在混合型app很多,稍微功能全一些的都需要具備網(wǎng)頁瀏覽的功能。
【移動(dòng)web app】完全是用手機(jī)瀏覽器里打開的一個(gè)網(wǎng)址,web app 只能運(yùn)行在瀏覽器里,靠瀏覽器解釋執(zhí)行。資源一般都在網(wǎng)絡(luò)上。它其實(shí)就是一個(gè)觸屏版的網(wǎng)站。【架構(gòu)b/s】
Appium對這3種類型的app的測試都支持。

其他相關(guān)概念
C/S 架構(gòu)
Client/Server,即客戶端/服務(wù)器端架構(gòu),一種典型的兩層架構(gòu)。客戶端包含一個(gè)或多個(gè)在用戶的電腦上運(yùn)行的程序。服務(wù)器端有兩種,一種是數(shù)據(jù)庫服務(wù)器端,客戶端通過數(shù)據(jù)庫連接訪問服務(wù)器端的數(shù)據(jù);另一種是Socket服務(wù)器端,服務(wù)器端的程序通過Socket與客戶端的程序通信。

B/S 結(jié)構(gòu)
B/S是Browser/Server,即瀏覽器/服務(wù)器架構(gòu)。Browser指的是Web瀏覽器,極少數(shù)事務(wù)邏輯在前端實(shí)現(xiàn),主要事務(wù)邏輯在服務(wù)器端實(shí)現(xiàn),Browser客戶端,WebApp服務(wù)器端和DB端構(gòu)成所謂的三層架構(gòu)。B/S架構(gòu)的系統(tǒng)無須特別安裝,只有Web瀏覽器即可。Appium就是這種架構(gòu)。

被測試App運(yùn)行平臺(tái):
iOS (就是蘋果手機(jī)、平板、甚至iWatch等移動(dòng)設(shè)備上運(yùn)行的app)
Android(就是安卓手機(jī)、平板、等移動(dòng)設(shè)備上運(yùn)行的app)
Windows (就是Widnows手機(jī)、平板等移動(dòng)設(shè)備上運(yùn)行的app,但是這種平臺(tái)使用人數(shù)目前太少,少到基本可以忽略不計(jì)了,)
FirefoxOS (更少,更加可以忽略不計(jì)了)
【如果運(yùn)行iOS應(yīng)用則需要appium server運(yùn)行在Mac系統(tǒng)上,也就是說Mac系統(tǒng)才能做iOS應(yīng)用自動(dòng)化】

測試App運(yùn)行環(huán)境:
【真實(shí)設(shè)備】 就是蘋果安卓的手機(jī)、平板等移動(dòng)設(shè)備
【模擬器】 則是通過在PC或者M(jìn)ac電腦上的軟件虛擬的 蘋果安卓的手機(jī)、平板等移動(dòng)設(shè)備。 主要是方便我們測試用的。

測試程序語言:
appium支持多種程序語言開發(fā)測試程序,基本上Selenium支持的開發(fā)語言,appium都支持。
Python、java、Ruby、js、php、c#

appium原理
appium的架構(gòu)原理如圖所示,由客戶端和服務(wù)端組成,客戶端與服務(wù)端通過JSON進(jìn)行通信;


image.png

各部分的含義:
(1)Appium服務(wù)器。它是一個(gè)基于node.js的HTTP服務(wù)器。主要功能是接受從Appium客戶端發(fā)起的鏈接,監(jiān)聽客戶端發(fā)送來 命令,將命令發(fā)送到bootstrap.jar(IOS為bootstrap.js)執(zhí)行,并將命令的結(jié)果通過HTTP應(yīng)答反饋給Appium客戶端。
(2)Bootstrap.jar。Bootstrap.jar是在Android手機(jī)上運(yùn)行的一個(gè)應(yīng)用程序,它在手機(jī)上扮演TCP服務(wù)器的角色,當(dāng)appium服務(wù)器需要運(yùn)行命令時(shí),Appium服務(wù)器與Bootstrap.jar建立TCP通訊,并把命令發(fā)送給Bootstrap.jar;Bootstrap.jar負(fù)責(zé)運(yùn)行測試命令。
(3)Appium客戶端。主要是指實(shí)現(xiàn)了Appium功能的webdriver協(xié)議的客戶端Library,他負(fù)責(zé)與Appium服務(wù)器建立連接,并將測試腳本的指令發(fā)送給服務(wù)端。包括:python、Java、Ruby等。
(4)Seesion。Appium的客戶端和服務(wù)端之間進(jìn)行通信必須在一個(gè)session的上下文中進(jìn)行。客戶端發(fā)起通信的時(shí)候會(huì)首先發(fā)送一個(gè)叫做“Desired Capabilities”的JSON對象給服務(wù)端。服務(wù)端接收到該數(shù)據(jù)后,會(huì)創(chuàng)建一個(gè)session并將session的ID返回給客戶端,之后客戶端會(huì)用該session的ID發(fā)送后續(xù)的命令。
(5)Desired Capalities。Desired Capalities是一組設(shè)置的鍵值對,用于通知Appium服務(wù)端建立需要的session,其中一些設(shè)置可以改變Appium的運(yùn)行行為。

Appium在Android上基于UIAutomator實(shí)現(xiàn)了測試的代理程序(Bootstrap.jar),在iOS上基于UIAutomation實(shí)現(xiàn)了測試的代理程 序(Bootstrap.js)。當(dāng)測試腳本運(yùn)行時(shí),每行WebDriver的腳本都將轉(zhuǎn)換成Appium的指令發(fā)送給Appium服務(wù)器,而Appium服務(wù)器將 測試指令交給代理程序,將由代理程序負(fù)責(zé)執(zhí)行測試。比如腳本上的一個(gè)點(diǎn)擊操作,在Appium服務(wù)器上都是touch指令,當(dāng)指令 發(fā)送到Android系統(tǒng)上時(shí),Android系統(tǒng)上的Bootstrap.jar將調(diào)用UIAutomator的方法實(shí)現(xiàn)點(diǎn)擊操作;而當(dāng)指令發(fā)送到iOS系統(tǒng)上 時(shí),iOS的Bootstrap.js將調(diào)用UIAutomation的方法實(shí)現(xiàn)點(diǎn)擊操作。由于Appium有了這樣的能力,同樣的測試腳本可以實(shí)現(xiàn)跨平臺(tái)運(yùn) 行。

appium工作原理架構(gòu)圖
在Android端,appium基于WebDriver協(xié)議,利用Bootstrap.jar,最后通過調(diào)?用UiAutomator的命令,實(shí)現(xiàn)App的自動(dòng)化測試


image.png

【如果appium環(huán)境搭建沒有問題,執(zhí)行腳本會(huì)自動(dòng)安裝驅(qū)動(dòng)程序】
1.客戶端是我們寫的webdriver測試腳本。
2.中間是Appium的服務(wù),Appium在服務(wù)端啟動(dòng)一個(gè)Server(4723端口),跟selenium Webdriver測試框架類似, Appium?持標(biāo)準(zhǔn)的WebDriver JSONWireProtocol。在這里提供它提供了一套R(shí)EST的接口,Appium Server接收web driver client標(biāo)準(zhǔn)rest請求,解析請求內(nèi)容,調(diào)?用對應(yīng)的框架響應(yīng)操作。
3.appium server會(huì)把請求轉(zhuǎn)發(fā)給中間件Bootstrap.jar ,它是用java寫的,安裝在手機(jī)上.Bootstrap監(jiān)聽4724端口并接收appium 的命令,最終通過調(diào)?用UiAutomator的命令來實(shí)現(xiàn)。
4.最后Bootstrap將執(zhí)行的結(jié)果返回給appium server。
5.appium server再將結(jié)果返回給 appium client

appium-iOS工作流
在iOS端,appium同樣使?WebDriver的一套協(xié)議。與Android端測試框架不同的是appium ios封裝了apple的 Instruments框架,主要用了Instrument的UIAutomation(Apple的自動(dòng)化測試框架),然后在設(shè)備中注入bootstrap.js進(jìn)行監(jiān)聽。

image.png

1.客戶端是我們寫的webdriver測試腳本。
2.中間是Appium的服務(wù),Appium在服務(wù)端啟動(dòng)一個(gè)Server(4723端口),跟selenium Webdriver測試框架類似, Appium?持標(biāo)準(zhǔn)的WebDriver JSONWireProtocol。在這里提供它提供了一套R(shí)EST的接口,Appium Server接收web driver client標(biāo)準(zhǔn)rest請求,解析請求內(nèi)容,調(diào)?用對應(yīng)的框架響應(yīng)操作。
3.appium server調(diào)用instruments.js 啟動(dòng)?一個(gè)socket server,同時(shí)分出一個(gè)?子進(jìn)程運(yùn)?instruments.app,將bootstrap.js(UIAutomation腳本)注?入到device?于和外界進(jìn)行交互。
4.最后Bootstrap.js將執(zhí)行的結(jié)果返回給appium server。
5.appium server再將結(jié)果返回給 appium client。

Appium的加載流程

1)調(diào)用Andorid adb完成基本的系統(tǒng)操作
2)向Andriod上部署bootstrap.jar包并啟動(dòng)
3)Forward Android 的端口到PC的機(jī)器上
4)PC上監(jiān)聽端口接受請求,使用webdriver協(xié)議
5)分析命令并轉(zhuǎn)通過forward的端口發(fā)給bootstrap.jar包
6)bootstrap接受請求并把命令發(fā)給UiAutomator或插樁體系


image.png

手機(jī)端驅(qū)動(dòng)程序介紹
蘋果
i0S 9.3 and above: Apple' s XCUITest
i0S 9.3 and lower: Apple' s UIAutomation

安卓
Android 4. 2+: Google' s
UiAutomator(android系統(tǒng)自帶)/UiAutomator2(appium優(yōu)化版本)
Windows
Microsoft‘s WinAppDriver
環(huán)境安裝-windows+Android

硬件準(zhǔn)備

Android手機(jī)(最低系統(tǒng)4.2+,推薦系統(tǒng)6.0+)一臺(tái)(真機(jī)演示)
計(jì)算機(jī)配置(windows):
系統(tǒng):Win10
內(nèi)存:最小4G,推薦8G
硬盤可用空間:4G以上
分辨率:1280*800以上

安裝

Appium客戶端

安裝Appium Python Clien包
pip install Appium-Python-Clien
要確保安裝匹配版版的selenium和appium:pip install selenium -U # 更新selenium版本

Appium服務(wù)端

安裝Appium Desktop(windows版本)--包含node.js 和 元素定位工具
下載地址 http://appium.io (推薦下載版本:1.13 或 1.17)
1.雙擊打開壓縮包Appium

image.png

2.雙擊進(jìn)行安裝。
img

img

3.點(diǎn)擊完成即可
img

電腦端環(huán)境

安裝jdk1.8版本


image.png

解壓后默認(rèn)安裝。

配置環(huán)境變量

1.在系統(tǒng)變量新建:JAVA_HOME,對應(yīng)變量值為:E:\Program Files\Java\jdk1.8.0_172(jdk安裝路徑)


image.png

image.png

2.系統(tǒng)變量Path在安裝系統(tǒng)之后就有了,我們只需為它增加新的值。
選中 Path 單擊 “編輯” 按鈕,單擊 “新建”,添加下面的值。
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin


image.png

3.系統(tǒng)變量中建立CLASSPATH,變量值輸入:
.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar (要加.表示當(dāng)前路徑)


image.png

輸入 java -version,看到JDK版本 java version “1.8.0_60” 那么恭喜你安裝成功了


image.png

下載sdk:https://www.androiddevtools.cn

使用sdkmanager相關(guān)命令安裝build-tools, platforms, platform-tools

sdkmanager使用相關(guān)文檔:
https://developer.android.com/studio/command-line/sdkmanager
進(jìn)入路徑下的tool/bin/目錄下,首先運(yùn)行:sdkmanager –list

image.png

如何使用sdkmanager升級(jí)sdk呢,查看https://blog.csdn.net/kai_1215/article/details/80731099
安裝build-tools的25.0.2版本
sdkmanager "build-tools;25.0.2"
安裝platform-tools,platforms的android-26版本
sdkmanager "platform-tools," "platforms;android-26"
image.png

配置環(huán)境變量
配置ANDROID_HOME
新建一個(gè)系統(tǒng)環(huán)境變量,變量名為ANDROID_HOME
image.png

系統(tǒng)的Path變量,%ANDROID_HOME%\platform-tools;% ANDROID_HOME%\tools
image.png

最后,測試一下是否成功:開始-運(yùn)行-輸入cmd-在終端輸入
再輸入命令:adb
顯示以下視圖則說明配置成功;
image.png

安裝appium-server
image.png

image.png

打開appium,查看配置android_home和java_home是否與電腦配置一致,不一致 或 為空 手動(dòng)添加
image.png

手機(jī)端設(shè)置

電腦端的手機(jī)驅(qū)動(dòng),確保電腦能識(shí)別出手機(jī)(win10默認(rèn)不需要)

可以通過手機(jī)助手(驅(qū)動(dòng)安裝完成請卸載,否則會(huì)造成adb沖突)或者對應(yīng)品牌的官網(wǎng)去下載

手機(jī)端開啟USB設(shè)置(Android)

用usb線連接到電腦
進(jìn)入手機(jī)設(shè)置-》關(guān)于手機(jī),不但點(diǎn)擊版本號(hào)(7次以上),激活開發(fā)者模式,退出到上級(jí)菜單,在開發(fā)者模式中,啟動(dòng)usb調(diào)試,手機(jī)端彈出授權(quán)彈窗,點(diǎn)擊允許即可
手機(jī)端設(shè)置usb為文件傳輸(多媒體傳輸)模式

啟動(dòng)adb連接

打開終端,輸入:adb devices -l ,顯示device 表示連接成功
注意點(diǎn):
確保電腦上沒有其他的adb程序軟件,如殺毒軟件-安全管家- 手機(jī)助手---會(huì)占用手機(jī)端口號(hào)導(dǎo)致連接失敗
確保手機(jī)端開發(fā)者選項(xiàng)中對應(yīng)的adb權(quán)限全部打開(紅色標(biāo)注為 打開,藍(lán)色標(biāo)注為 關(guān)閉)

(可選)確保手機(jī)端appium相關(guān)的app對應(yīng)權(quán)限打開
? 設(shè)置》應(yīng)用管理》權(quán)限設(shè)置》找到對應(yīng)的app,查看權(quán)限

代碼驗(yàn)證環(huán)境是否搭建成功
執(zhí)行代碼
測試auto_boss.py

自動(dòng)化配置信息文檔:http://appium.io/docs/en/writing-running-appium/caps/#uiautomator2-only

導(dǎo)包

from appium import webdriver

準(zhǔn)備自動(dòng)化配置信息

desired_caps={
#移動(dòng)設(shè)備平臺(tái) 必填
'platformName':'Android',
#平臺(tái)OS版本號(hào),寫整數(shù)位即可 必填
'plathformVersion':'7',
#設(shè)備的名稱--值可以隨便寫,adb devices可以查看設(shè)備名稱 必填
'deviceName':'621QADQT256Y6',
#提供被測app的信息-包名,入口信息: 必填
#adb shell dumpsys activity recents | findstr intent={
'appPackage':'com.hpbr.bosszhipin',
'appActivity':'.module.launcher.WelcomeActivity',
#確保自動(dòng)化之后不重置app (不添加此項(xiàng),自動(dòng)化測試完之后會(huì)刪除用戶信息)
'noReset':True,
#設(shè)置session的超時(shí)時(shí)間,單位秒 默認(rèn)60s(代碼與服務(wù)端連接有延時(shí),如果不添加,時(shí)間超時(shí)就會(huì)導(dǎo)致代碼與服務(wù)端斷開連接)
'newCommandTimeout':6000,
#設(shè)置底層測試驅(qū)動(dòng)-1.15默認(rèn)使用的底層驅(qū)動(dòng)就是UiAutomator2
'automationName':'UiAutomator2',#或者UiAutomator1
# 'skipServerInstallation':True#跳過UI2的安裝,如果第一次運(yùn)行程序,不要添加該配置
}

初始化driver對象-用于控制手機(jī)-啟動(dòng)被測應(yīng)用

IP-appium-server所在機(jī)器的網(wǎng)絡(luò)ip,port-監(jiān)聽的端口號(hào),path固定/wd/hub

driver=webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
driver.implicitly_wait(10)#穩(wěn)定元素

點(diǎn)擊放大鏡

eles=driver.find_elements_by_id('com.hpbr.bosszhipin:id/img_icon')#先取所有符合條件的元素

找到第二個(gè)元素--放大鏡

btn=eles[1]
btn.click()

搜索框輸入職位信息

search_input=driver.find_element_by_id('com.hpbr.bosszhipin:id/et_search')
search_input.send_keys('軟件測試')#輸入?yún)?shù)

選擇符合條件的第一個(gè)搜索結(jié)果

driver.find_element_by_id('com.hpbr.bosszhipin:id/tv_filtered_name').click()

獲取當(dāng)前頁面所有職位信息元素

job_msg=driver.find_elements_by_id('com.hpbr.bosszhipin:id/view_job_card')
for job in job_msg:
#輸出崗位名稱
name=job.find_element_by_id('com.hpbr.bosszhipin:id/tv_position_name')
# print(name.text)
#輸出薪資
salray=job.find_element_by_id('com.hpbr.bosszhipin:id/tv_salary_statue')
# print(salray.text)
#輸出公司名稱
company=job.find_element_by_id('com.hpbr.bosszhipin:id/tv_company_name')
print('%s|%s|%s'%(name.text,salray.text,company.text))

input('......')

driver.quit()

發(fā)現(xiàn)appPackage fappActivity
未安裝被測應(yīng)用,使用SDK中的aapt進(jìn)行抓取
SDK中下載最新的build-tools,通過aapt dump badging xxx.apk命令來查appPackage與appActivity。
打開 windows 終端,輸入:
cd E:\androidsdk\build-tools\29.0.3
aapt dump badging xxx.apk (windows)
打開 Mac 終端,輸入:
cd /usr/local/androidsdk/build-tools/29.0.3
./aapt dump badging xxx.apk

已安裝被測應(yīng)用,先打開被測應(yīng)用,再在終端輸入以下命令:

adb shell dumpsys activity recentsl findstr intent={
adb shell dumpsys activity recentsl findstr "intent={" > d:\info.txt && d:\info.txt
斜杠之前為appPackage,斜杠之后為appActivity

首次運(yùn)行腳本會(huì)在手機(jī)上自動(dòng)新增兩個(gè)App
appium-settings--應(yīng)用會(huì)自動(dòng)安裝并啟用(無界面,打開后閃退,以服務(wù)形式存在)
UiAutomator2--appium優(yōu)化后的Android底層自動(dòng)化驅(qū)動(dòng)(桌面看不到此app,也打不開)
以上兩個(gè)app確保可以自動(dòng)安裝,并開啟全部權(quán)限(以下兩個(gè)應(yīng)用沒有啟動(dòng),從設(shè)置 -> 全部應(yīng)用-appium Settings/io.appium.uiautomantor2.serve -> 權(quán)限管理,開啟全部權(quán)限)

Adb無線連接
usb有線連接
Wi-Fi無線連接

無線連接的優(yōu)勢
減少usb連接干擾
提高連接穩(wěn)定性
脫離了有線的束縛(確保手機(jī)與電腦同一個(gè)局域網(wǎng))

連接步驟:

先以u(píng)sb有線連接的方式連接到計(jì)算機(jī)
激活手機(jī)adb的無線服務(wù)
? 終端命令行輸入:adb tcpip 5555
計(jì)算機(jī)以無線方式連接到手機(jī)
? 終端命令行輸入:adb connect <driverip>

如果手機(jī)重啟,需要重新激活連接--重復(fù)操作無線連接步驟即可】
1、斷開設(shè)備連接
adb kill-server #結(jié)束adb服務(wù)
adb start-server #啟動(dòng)adb服務(wù)
adb devices #獲取adb設(shè)備列表
2、創(chuàng)建設(shè)備連接
adb connect xxx #創(chuàng)建與xxx的設(shè)備連接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評(píng)論聯(lián)系作者。