小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

創(chuàng)建可維護(hù)的自動(dòng)化驗(yàn)收測試

 gyb98 2012-03-22

作者 / Dale. H.Emery   譯者 / 張小明,Holly

測試即開發(fā)

這里的測試指的是自動(dòng)化測試,從軟件的本質(zhì)上看,測試的自動(dòng)化乃是測試方面的軟件開發(fā),萬變不離其宗,這也就意味著那些凡是屬于軟件開發(fā)的定律或者原則也同樣適用于測試自動(dòng)化。對于沒有寫過代碼或者代碼經(jīng)驗(yàn)較少的人來說,或許這其中的道理不能一眼就瞧得出來。

通常情況下軟件開發(fā)的很大一部分開銷是維護(hù)——修修補(bǔ)補(bǔ),更新不斷。軟件的可維護(hù)性強(qiáng),則開發(fā)成本低,同理,測試的自動(dòng)化開發(fā)成功與否也很大程度上體現(xiàn)在它的可維護(hù)性成本大小上。我接觸過的很多試圖嘗試引進(jìn)自動(dòng)化測試的機(jī)構(gòu)沒幾個(gè)月就決定放棄自動(dòng)化測試,問之棄因,你會(huì)發(fā)現(xiàn)大多是因?yàn)樽詣?dòng)化腳本過于不穩(wěn)定以及隨之衍生的難維護(hù)性。舉個(gè)例子,界面上重命名一個(gè)按鈕會(huì)導(dǎo)致大批的測試用例失敗,而與此同時(shí)花費(fèi)在調(diào)通和更新這些用例身上的時(shí)間成本又太高。

有些團(tuán)隊(duì)或機(jī)構(gòu)在自動(dòng)化測試上取得了成功,難道他們的自動(dòng)化就可以避免掉這樣的維護(hù)費(fèi)用問題?當(dāng)然不可能。而成功與失敗的團(tuán)隊(duì)之間一個(gè)重要的區(qū)別就是:在對待測試開發(fā)的維護(hù)問題上,失敗者往往是被昂貴的維護(hù)費(fèi)用嚇住而放棄自動(dòng)化計(jì)劃,而成功者則是從一開始就做足了應(yīng)對措施。那些在自動(dòng)化取得成功的團(tuán)隊(duì)懂得測試即開發(fā)這一道理,明白測試開發(fā)一旦開始,維護(hù)在所難免,所以他們會(huì)深思熟慮,想方設(shè)法降低維護(hù)成本。

軟件需求的變更和系統(tǒng)實(shí)現(xiàn)的變更會(huì)影響測試,需要測試做出相應(yīng)的調(diào)整,這二者任意一種變更都可能導(dǎo)致一系列的自動(dòng)化測試失敗。如果一些自動(dòng)化測試不能同步新的軟件變更和產(chǎn)品新特性,那么它們將會(huì)被淘汰,其測試結(jié)果也不會(huì)得到運(yùn)用。而要使其回歸正常,我們必須不斷調(diào)整測試以配合需求和系統(tǒng)實(shí)現(xiàn)的變更。維護(hù)的成本開始顯山露水。

因此如果需求和實(shí)現(xiàn)的變化是必然的,那么降低自動(dòng)化測試維護(hù)成本的方法只有一個(gè),即編寫適應(yīng)性強(qiáng)的測試腳本。

暴露太多無關(guān)緊要的細(xì)節(jié)或者重復(fù)這兩大關(guān)鍵因素使得修改代碼的困難大大增加,無數(shù)慘痛的經(jīng)驗(yàn)教訓(xùn)讓軟件開發(fā)人員對此深有體會(huì),對于那些正在從事和將要從事的自動(dòng)化測試開發(fā)者們,也肯定不想重蹈覆轍。

驗(yàn)收測試和系統(tǒng)的任務(wù)

驗(yàn)收測試用來檢測一個(gè)系統(tǒng)是否正確履行了某一特定任務(wù)。也就意味著,驗(yàn)收測試的核心是關(guān)注它所要驗(yàn)證的功能點(diǎn)是否正確,而不考慮用了何種技術(shù)、何種方法去測試。

現(xiàn)在假定我們要測某個(gè)系統(tǒng)的創(chuàng)建賬號這個(gè)特性,系統(tǒng)通過傳遞給Create命令用戶名和密碼來創(chuàng)建新賬號。創(chuàng)建賬號特性的功能之一是驗(yàn)證密碼的有效性。一個(gè)合法的密碼長度必須介于6~16字符之間且至少包含一個(gè)字母、一個(gè)數(shù)字以及一個(gè)標(biāo)點(diǎn)符號。如果用戶提交的密碼合法,Create命令創(chuàng)建成功并報(bào)告Account Created;反之,Create命令不會(huì)執(zhí)行創(chuàng)建過程,同時(shí)報(bào)告Invalid Password。這就是功能職責(zé)的本質(zhì)。無論軟件系統(tǒng)以何種技術(shù)實(shí)現(xiàn),Web應(yīng)用也好,GUI桌面應(yīng)用也罷或者是命令行執(zhí)行的程序,也不管會(huì)不會(huì)有人像德州電鋸殺人狂里的休維特一樣,揮舞瘋狂的電鋸恐嚇要鋸斷那些輸錯(cuò)密碼童鞋的指頭,總之,系統(tǒng)需執(zhí)行此項(xiàng)職責(zé)(密碼檢查是系統(tǒng)必須實(shí)現(xiàn)的職責(zé))。

無關(guān)緊要的細(xì)節(jié)

表1 不良自動(dòng)化測試用例腳本
表1 不良自動(dòng)化測試用例腳本

列表1展示的是一段不良自動(dòng)化測試用例腳本,該測試用例用來檢測Create命令的密碼有效性檢查這一職責(zé)。

這段測試腳本問題很多,一眼望去,最明顯的是可讀性很差,我們看到第二行The create command validates passwords,這是測試的標(biāo)題,表明該測試的測試點(diǎn)和職責(zé),但往下讀時(shí),我們會(huì)發(fā)現(xiàn),里面充斥了太多累贅的單詞和煩人的諸如“{$@^”這樣的符號,讓人不知其所言。

仔細(xì)看一下,我們可以挑出來幾個(gè)密碼,比如1234!@$^!緊接著再加把勁,啊哈,我們會(huì)發(fā)現(xiàn)一些密碼會(huì)導(dǎo)致status值為Invalid Password,而另一些會(huì)使得status值為Account Created。從另一方面看,我們可能也會(huì)注意不到上述內(nèi)容因?yàn)樵摐y試腳本在密碼和狀態(tài)status之間夾雜了太多的實(shí)現(xiàn)細(xì)節(jié),或曰:測試噪聲。試想,這些特殊的符號$、@、^以及單詞Run、Ruby、fred究竟和密碼及其有效性有什么關(guān)系!對于自動(dòng)化測試的腳本來說,從用例的可讀性和可維護(hù)性角度看這些都是無關(guān)緊要的過程實(shí)現(xiàn)細(xì)節(jié)。

過多無關(guān)緊要的細(xì)節(jié)是怎樣毀掉可維護(hù)性的?假設(shè)我們的系統(tǒng)安全分析師指出六位長度的密碼本身不安全。于是為了增強(qiáng)安全性,我們將密碼長度下限由六改成十,這是一個(gè)典型的需求變更,請思考,這時(shí)候列表1的測試腳本哪里需要修改?怎樣改?答案恐怕沒那么簡單。

讓我們再來考慮一個(gè)更有挑戰(zhàn)性的需求變更。假如我們想讓系統(tǒng)管理員能夠?yàn)槿我环N情況設(shè)定具體的密碼長度最長與最短值。這時(shí)候該怎么修改剛才的測試腳本?答案還是無法一眼看出??峙聸]那么簡單。

這其中的原因“恐怕”在于測試腳本沒有清晰表達(dá)它所要測試的功能職責(zé)。當(dāng)看不出一段測試用例腳本的本質(zhì) ,通常意味著需求變更之時(shí)測試人員會(huì)需要花數(shù)倍的代價(jià)來修改原測試腳本。

因此,為方便識別本質(zhì)就要隱藏非必要細(xì)節(jié)的,以使自動(dòng)化腳本用戶更容易看到測試的本質(zhì),在上面創(chuàng)建用戶的例子中,大多數(shù)非必要的細(xì)節(jié)是如何調(diào)用Create命令。該系統(tǒng)是基于Ruby的命令行程序,現(xiàn)在讓我們再次返回列表1的測式腳本里解讀一番,黑色字體加深的第一行告訴自動(dòng)化測試框架Robot啟動(dòng)Ruby解釋器,加載被測程序文件app/cli.rb,并調(diào)用Create命令,參數(shù)值為用戶名fred以及密碼1234!@$^,最后命令返回的結(jié)果存在變量${status}中,呵,數(shù)數(shù)不必要的實(shí)現(xiàn),細(xì)節(jié)至少有5~6個(gè)之多!

再來看字體加深的第二行,實(shí)現(xiàn)命令返回值和期望值Invalid Password的比較,雖然看起來比剛才那一行較容易理解 ,但措辭笨重,并且過分的語法細(xì)節(jié)容易分散人們的注意力。

通過Robot自動(dòng)化框架我們可以把實(shí)現(xiàn)細(xì)節(jié)提煉成關(guān)鍵字(Keyword),使之以類似子函數(shù)的形式為測試用例腳本調(diào)用,一個(gè)完整的自動(dòng)化測試用例便可由數(shù)個(gè)關(guān)鍵字組合而成。

現(xiàn)在我們演示如何使用關(guān)鍵字來隱藏不必要的實(shí)現(xiàn)細(xì)節(jié)。一個(gè)可行的方法就是問自己這樣一個(gè)問題:假設(shè)自己對被測系統(tǒng)實(shí)現(xiàn)一無所知,該如何寫出自動(dòng)化測試腳本的第一步?是的,即使對實(shí)現(xiàn)一無所知也無大礙,我們只需 知道我們要測試創(chuàng)建用戶這個(gè)產(chǎn)品特性——被測系統(tǒng)顯然要提供的功能。繼而我們知道創(chuàng)建用戶即是被測系統(tǒng)的必要職責(zé),而且從系統(tǒng)需求分析可知?jiǎng)?chuàng)建用戶需要提供用戶名和密碼。

基于以上所述,可能這樣修改測試:

Create Account fred 1234@!$^

當(dāng)然修改后的腳本可能還有其他一些問題,我會(huì)在稍后部分接著討論。

再看看加深的第二行,驗(yàn)證創(chuàng)建用戶命令返回的結(jié)果是否為Invalid Password,順著上面修改的思路則可以變成:Status Should Be Invalid Password。

兩行合并,看一看整體效果:

Create Account fred 1234@!$^

Status Should Be Invalid Password

原來的一步經(jīng)過一次提煉現(xiàn)在看起來簡潔多了,可讀性也變強(qiáng)了,我們很容易發(fā)現(xiàn)這兩行的邏輯上的聯(lián)系:系統(tǒng)必須告知輸入的這一密碼是無效的。

現(xiàn)在還無法運(yùn)行新的腳本,因?yàn)闇y試框架Robot找不到關(guān)鍵字Create Account和Status Should Be的定義,兩個(gè)關(guān)鍵字的Ruby實(shí)現(xiàn)代碼如表2。

表2 兩個(gè)關(guān)鍵字的Ruby實(shí)現(xiàn)代碼
表2 兩個(gè)關(guān)鍵字的Ruby實(shí)現(xiàn)代碼

字體加深的代碼行創(chuàng)建了一個(gè)名為Create Account的關(guān)鍵字,需要兩個(gè)參數(shù)user_name和password。關(guān)鍵字函數(shù)的主體只有兩行代碼,第一行加載被測程序并調(diào)用Create命令,第二行保存返回值,對比之前的原測試腳本,我們發(fā)現(xiàn)主體第一行代碼和表1的加深第一行實(shí)現(xiàn)了同樣的功能,非必要細(xì)節(jié)即隱藏于此。

你或許已經(jīng)發(fā)現(xiàn)了關(guān)鍵字的實(shí)現(xiàn)代碼里引入了更多的語法和特殊字符。這不用多慮,通過把細(xì)節(jié)抽象成關(guān)鍵字, 我們的測試腳本看起來整潔多了,可讀性大大增強(qiáng),現(xiàn)在我把更新過的測試腳本貼上如表3所示,更直觀展示了修改后的效果。

表3 更新過的測試腳本
表3 更新過的測試腳本

雖然某些程度上增加了關(guān)鍵字這一部分的代碼,但獲得了整個(gè)測試用例腳本的干凈清爽,這一做法是值得嘗試的。

重復(fù)

上面我們已經(jīng)學(xué)會(huì)通過提煉可復(fù)用的關(guān)鍵字改進(jìn)了測試腳本,但還存在其他問題。一個(gè)問題是我們之前提到的,即每隔一個(gè)測試步驟就包含用戶名fred。另一個(gè)更大的問題是重復(fù),從表3修改過的測試來看,每一對關(guān)鍵字(Create Account和Status Should Be)組成一步驗(yàn)證測試,每一步都要提交一個(gè)不同的密碼并與比較系統(tǒng)返回的狀態(tài)值和期望值,我們看到,除了輸入的密碼和期望狀態(tài)值不同之外,其他部分基本都是一樣的。

重復(fù)的代碼將毀掉可維護(hù)性。現(xiàn)在假設(shè)我們的用戶交互分析師指出產(chǎn)品系統(tǒng)的其他部分并不要求用戶創(chuàng)建賬號(Create)而是要求他們注冊(Register),這就在同一個(gè)系統(tǒng)里出現(xiàn)了用戶交互接口和使用術(shù)語的不一致,而用戶交互分析師堅(jiān)持整個(gè)系統(tǒng)應(yīng)該杜絕這種不一致性,于是我們決定把Create命令變成Register。

這樣一來,對測試會(huì)產(chǎn)生的影響有多大?我們封裝了關(guān)鍵字Create Account來創(chuàng)建用戶,現(xiàn)在看樣子只需要把關(guān)鍵字的實(shí)現(xiàn)部分中調(diào)用Create命令的地方改成Register就可以了,但這樣一來的又一個(gè)問題就在于我們的測試的關(guān)鍵字和被測的功能也出現(xiàn)了不一致的叫法,這會(huì)使人困惑。或許以后我們每次驗(yàn)收測試跑完之后,都需要向這些測試報(bào)告的經(jīng)理或者市場人員解釋這些關(guān)鍵詞。

為了保持術(shù)語一致性,最好的做法是修改我們的測試用例。上面的測試用例中,至少有八個(gè)用到Create Account關(guān)鍵字的地方可能都要改成Register。還有兩個(gè)關(guān)鍵字也都用到了Create Account。而現(xiàn)實(shí)會(huì)更殘酷,可能有成千上萬的測試步驟都調(diào)用了那個(gè)關(guān)鍵字。由此,我們得出結(jié)論:重復(fù)絕對會(huì)增加維護(hù)成本。

重復(fù)往往預(yù)示了潛藏在測試中的某一重要概念。當(dāng)這樣的重復(fù)不是發(fā)生在個(gè)別測試步驟而是一系列的步驟的時(shí)候,情況更是這樣。

思考一下表3中的測試腳本,看看前面兩行究竟說明什么。沒錯(cuò),它們核實(shí)創(chuàng)建用戶命令是否拒絕1234!@$^這一密碼。那再來看看第9~10兩行。這兩行來證實(shí)創(chuàng)建用戶命令接受!C2456這一密碼,再進(jìn)行一次抽象概括,我們驚奇地發(fā)現(xiàn),原來這兩行測試的本質(zhì)便是接受(Accept)和拒絕(Reject)。但遺憾的是在表3的測試中,這一本質(zhì)卻被埋沒了。接下來我們利用兩個(gè)新的關(guān)鍵字來使概念明朗化,如表4所示:

表4 用兩個(gè)新的關(guān)鍵字來使概念明朗化
表4 用兩個(gè)新的關(guān)鍵字來使概念明朗化

這兩個(gè)新的關(guān)鍵字不僅將重寫我們的測試腳本,同時(shí)也給接受密碼和拒絕密碼下了定義:接受密碼即調(diào)用被測系統(tǒng)的Create命令,系統(tǒng)報(bào)告用戶創(chuàng)建成功;拒絕密碼即調(diào)用Create命令,系統(tǒng)報(bào)告密碼無效。

如此一來再次經(jīng)過修改的測試腳本如表5所示,減少了重復(fù)并且更能體現(xiàn)被測功能的職責(zé),即密碼的接受或拒絕。

表5 減少了重復(fù)的重寫測試
表5 減少了重復(fù)的重寫測試

讓我們捋一捋剛才的思路,總結(jié)一下該部分。首先我們經(jīng)過分析測試代碼的重復(fù)部分,發(fā)現(xiàn)被測功能的兩個(gè)最基本概念——接受正確的密碼和拒絕錯(cuò)誤的密碼。通過定義兩個(gè)關(guān)鍵字,我們抽象并命名了這兩個(gè)基本概念。最后我們在測試用例中使用新的關(guān)鍵字,從而提升了測試的可讀性以及可維護(hù)性。

給本質(zhì)一個(gè)有意義的名字

經(jīng)過一番“折騰”,現(xiàn)在表5給出測試已經(jīng)能夠比較清晰地表達(dá)測試的基本概念。而與此同時(shí),最后一點(diǎn)不夠清晰的地方已經(jīng)開始明朗起來??纯礈y試中的幾個(gè)密碼,我們不能馬上弄清到底給出的密碼無效在什么地方?那正確的密碼是符合了什么樣的規(guī)則嗎?或許花些時(shí)間你就可以找到問題的答案。這里涉及一個(gè)重點(diǎn):任何花在思考測試的意義即其本質(zhì)的時(shí)間都算作維護(hù)成本 。這個(gè)成本看起來微不足道,但是如果系統(tǒng)需求更改導(dǎo)致大面積關(guān)聯(lián)的測試用例都要修改,這時(shí)累加起來的成本是巨大的。我的一些客戶已經(jīng)發(fā)現(xiàn)這個(gè)問題的嚴(yán)重性,道理很明白,千里之堤,潰于蟻穴。

在上述的測試?yán)又校宜x取的每一個(gè)密碼 都有特定的目的,也就說每一密碼的本質(zhì)都是和被測系統(tǒng)功能的某一個(gè)需求有關(guān)。比如1234!@$^這個(gè)密碼,它不含字母, 因而這個(gè)密碼的本質(zhì)就可以這么描述:一個(gè)不包含字母的密碼。

我習(xí)慣給每一個(gè)本質(zhì)賦予具有意義的名稱,在測試代碼中給本質(zhì)命名的是變量。有時(shí)候我也創(chuàng)建變量,給它命名一個(gè)富有表現(xiàn)力的名字,再給它規(guī)定一種能體現(xiàn)其名的價(jià)值。如下,我定義了一個(gè)變量用來儲(chǔ)存沒有字母的
密碼。

表6 在測試腳本中使用變量,節(jié)省空間
表6 在測試腳本中使用變量,節(jié)省空間

然后在測試腳本中使用變量,節(jié)省空間,這里略去了其它變量的定義過程,如表6所示,每一個(gè)密碼都以變量的形式表達(dá)其代表的本質(zhì)意義。至此,離我們開始設(shè)定的目標(biāo)已經(jīng)很近了,但依然有可以再優(yōu)化的地方,我將進(jìn)一步把原來一個(gè)測試按照密碼不同屬性拆分成多個(gè)測試用例,如表7。

表7 把原來一個(gè)測試按照密碼不同屬性拆分成多個(gè)測試用例
表7 把原來一個(gè)測試按照密碼不同屬性拆分成多個(gè)測試用例

現(xiàn)在,只需看一眼便可知每一個(gè)測試用例或者每一步的意義何在。這里,重要的需求概念被清晰精煉地表述了出來。

現(xiàn)在假定新需求改變了密碼極限長度,由于每一個(gè)需求和被測功能都由測試用例清晰地顯示出來,我能夠很快定位哪一個(gè)測試用例需要修改。并且由于每一個(gè)測試數(shù)據(jù)也即密碼都以有意義的變量的形式儲(chǔ)存,我們能夠很快的找到需要修改的變量進(jìn)行重新賦值。先前對測試代碼所做的重構(gòu)帶來的好處顯而易見,這里再一次強(qiáng)調(diào)測試即開發(fā)的主旨。

讓測試經(jīng)得起測試:應(yīng)對系統(tǒng)主要實(shí)現(xiàn)架構(gòu)的改變

在前面部分我們努力讓測試能夠更靈活地自適應(yīng)需求變更,可如果是系統(tǒng)的主要實(shí)現(xiàn)架構(gòu)發(fā)生了變化呢?測試會(huì)受到什么影響?為了找出答案,我們通過改變一點(diǎn)實(shí)現(xiàn)的細(xì)節(jié)——通過Web頁面創(chuàng)建用戶的方式取代之前的命令行調(diào)用Create命令的方式?,F(xiàn)在創(chuàng)建用戶只需要打開創(chuàng)建用戶的Web頁面,輸入用戶名和密碼,然后點(diǎn)擊創(chuàng)建用戶按鈕,由頁面打印創(chuàng)建結(jié)果。嚴(yán)峻的問題來了,我們的測試該如何修改?

還記得我們之前封裝不必要細(xì)節(jié)并提煉了兩個(gè)關(guān)鍵字Create Account和Status Should Be。這兩個(gè)關(guān)鍵字封裝的細(xì)節(jié)就是如何調(diào)用命令行執(zhí)行Create命令以及獲得結(jié)果報(bào)告。很明顯,我們肯定要重寫這兩個(gè)地方,因?yàn)楝F(xiàn)在需要通過Web頁面操作才能實(shí)現(xiàn)。

表8 修改后的關(guān)鍵字實(shí)現(xiàn)
表8 修改后的關(guān)鍵字實(shí)現(xiàn)

表8是修改后的關(guān)鍵字實(shí)現(xiàn)。我們修改了與系統(tǒng)交互的實(shí)現(xiàn),即通過使用開源Web測試工具Selenium進(jìn)行頁面訪問和操作,那么現(xiàn)在的問題是對于那幾個(gè)具體的自動(dòng)化測試用例,我們還需要修改什么?答案是什么都不需要,此次修改工作已完畢。通過改變幾行代碼,使我們的自動(dòng)化測試輕松運(yùn)行在變化了的實(shí)現(xiàn)架構(gòu)的系統(tǒng)上,這往往就是成功和失敗的自動(dòng)化測試之間的區(qū)別。

與此同時(shí),回到現(xiàn)實(shí)世界

在真實(shí)的測試中,你可能要做更多的工作以應(yīng)對系統(tǒng)實(shí)現(xiàn)架構(gòu)的變化,你可能不止需要修改兩個(gè)關(guān)鍵字。但只要你創(chuàng)建了級別較低的關(guān)鍵字,將其他代碼和與系統(tǒng)交互的細(xì)節(jié)分開, 那么你所需要做的就只是修改這些關(guān)鍵字而該測試用例照常運(yùn)行不需要改動(dòng)【譯者注:如果你看到Martin Flower的《重構(gòu)》一書,就應(yīng)該明白這樣一條重構(gòu)原則,保持接口不變,改變底層實(shí)現(xiàn)】。

真實(shí)的項(xiàng)目里很多實(shí)現(xiàn)架構(gòu)上的變動(dòng)將會(huì)對測試開發(fā)工具提出更嚴(yán)酷更顛覆的問題。 但 即使是最壞情況,你依然可以使用先進(jìn)的開源測試工具,用以解決很多重復(fù)的問題,幫助你撰寫能夠清晰表達(dá)測試本質(zhì)的用例和腳本。

再次強(qiáng)調(diào),一定要記住其中的本質(zhì)內(nèi)容:只有消滅重復(fù)的無關(guān)緊要細(xì)節(jié),讓測試清晰表達(dá)被測系統(tǒng)功能職責(zé),才能在發(fā)生系統(tǒng)需求和實(shí)現(xiàn)變更的情況下輕松應(yīng)對以便降低自動(dòng)化測試維護(hù)的成本。這也正是我們衡量自動(dòng)化測試開發(fā)成功的標(biāo)志。


    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多