qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          iOS集成測試框架—KIF 滾動屏幕時隱藏toolbar

           iOS集成測試框架——KIF
            KIF的全稱是“Keep It Functional”,是一款iOS集成測試框架,來自square。KIF使用了蘋果非公開的API,很多iOS測試框架都使用了非公開API,出于測試目的還是安全的,KIF并不使用非公開的API生成代碼,所以蘋果不會拒絕你的應用。
            注意: KIF 2.0并不兼容KIF 1.0,并且使用了不同的測試執行機制。
            功能:
            1.KIF用Objective C寫成,最大化集成代碼的同時還可以最小化層級數目。
            2.配置簡單。KIF可直接集成進你的Xcode項目中,無需運行額外的網絡服務器或者安裝任何額外的包。
            3.OS覆蓋范圍廣泛。KIF的測試套件可以運行iOS 5.1以上系統,甚至更低Testing Framework的版本也能運行。
            4.向用戶一樣進行測試。KIF可以模仿用戶的輸入,點擊事件等。
            5.可自動集成Xcode 5測試工具。
            IQDropDownTextField
            使用UIPickerView,支持下拉菜單的文本框。點擊文本框出現相關的選擇器。
            測試環境:Xcode 5.0,iOS 5.0以上
            KASlideShow--適用于iOS的幻燈篇展示(僅支持ARC)
            適用于iOS的幻燈篇展示(僅支持ARC)
            提供了淡入淡出和水平滑動兩種方式來展示幻燈片,支持手動展示。
            測試環境:Xcode 5.0,iOS 4.3以上版本
            XHShockHUD
            重用性好、使用簡單、可任意定制HUD樣式(用的人去定制),默認有四種定制好的方式。
            測試環境:Xcode 5.0,iOS 4.3以上
            SKSlideViewController
            SKSlideViewController是一個簡單易用的滑動導航菜單控件,可設置主要的和可選的視圖控制器,易于設置和調整。
            測試環境:Xcode 5.0,iOS 4.3以上
           CCHMapClusterController
            使用MapKit且適用于iOS和OS X平臺的高性能map聚集,僅需四行代碼。
            測試環境:Xcode 5.0,iOS 6.0以上
            滾動屏幕時隱藏toolbar--ABFullScrollViewController
            自定義ViewController,滾動屏幕時隱藏toolbar,類似Facebook、Safari以及Twitter等。
            測試環境:Xcode 5.0,iOS 7.0以上版本

          posted @ 2014-08-01 09:47 順其自然EVO 閱讀(281) | 評論 (0)編輯 收藏

          iOS開發之GCD使用總結

            GCD是iOS的一種底層多線程機制,今天總結一下GCD的常用API和概念,希望對大家的學習起到幫助作用。
            GCD隊列的概念
            在多線程開發當中,程序員只要將想做的事情定義好,并追加到DispatchQueue(派發隊列)當中就好了。
            派發隊列分為兩種,一種是串行隊列(SerialDispatchQueue),一種是并行隊列(ConcurrentDispatchQueue)。
            一個任務就是一個block,比如,將任務添加到隊列中的代碼是:
            1 dispatch_async(queue, block);
            當給queue添加多個任務時,如果queue是串行隊列,則它們按順序一個個執行,同時處理的任務只有一個。
            當queue是并行隊列時,不論第一個任務是否結束,都會立刻開始執行后面的任務,也就是可以同時執行多個任務。
            但是并行執行的任務數量取決于XNU內核,是不可控的。比如,如果同時執行10個任務,那么10個任務并不是開啟10個線程,線程會根據任務執行情況復用,由系統控制。
            獲取隊列
            系統提供了兩個隊列,一個是MainDispatchQueue,一個是GlobalDispatchQueue。
            前者會將任務插入主線程的RunLoop當中去執行,所以顯然是個串行隊列,我們可以使用它來更新UI。
            后者則是一個全局的并行隊列,有高、默認、低和后臺4個優先級。
            它們的獲取方式如下:
            1 dispatch_queue_t queue = dispatch_get_main_queue();
            2
            3 dispatch queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRORITY_DEFAULT, 0)
            執行異步任務
            1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            2     dispatch_async(queue, ^{
            3         //...
            4     });
            這個代碼片段直接在子線程里執行了一個任務塊。使用GCD方式任務是立即開始執行的
            它不像操作隊列那樣可以手動啟動,同樣,缺點也是它的不可控性。
            令任務只執行一次
            1 + (id)shareInstance {
            2     static dispatch_once_t onceToken;
            3     dispatch_once(&onceToken, ^{
            4         _shareInstance = [[self alloc] init];
            5     });
            6 }
            這種只執行一次且線程安全的方式經常出現在單例構造器當中。
            任務組
            有時候,我們希望多個任務同時(在多個線程里)執行,再他們都完成之后,再執行其他的任務,
            于是可以建立一個分組,讓多個任務形成一個組,下面的代碼在組中多個任務都執行完畢之后再執行后續的任務:
            1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            2     dispatch_group_t group = dispatch_group_create();
            3
            4     dispatch_group_async(group, queue, ^{ NSLog(@"1"); });
            5     dispatch_group_async(group, queue, ^{ NSLog(@"2"); });
            6     dispatch_group_async(group, queue, ^{ NSLog(@"3"); });
            7     dispatch_group_async(group, queue, ^{ NSLog(@"4"); });
            8     dispatch_group_async(group, queue, ^{ NSLog(@"5"); });
            9
            10     dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"done"); });延遲執行任務
            1     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            2         //...
            3     });
            這段代碼將會在10秒后將任務插入RunLoop當中。
            dispatch_asycn和dispatch_sync
            先前已經有過一個使用dispatch_async執行異步任務的一個例子,下面來看一段代碼:
            1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            2
            3     dispatch_async(queue, ^{
            4         NSLog(@"1");
            5     });
            6
            7     NSLog(@"2");
            這段代碼首先獲取了全局隊列,也就是說,dispatch_async當中的任務被丟到了另一個線程里去執行,async在這里的含義是,當當前線程給子線程分配了block當中的任務之后,當前線程會立即執行,并不會發生阻塞,也就是異步的。那么,輸出結果不是12就是21,因為我們沒法把控兩個線程RunLoop里到底是怎么執行的。
            類似的,還有一個“同步”方法dispatch_sync,代碼如下:
            1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            2
            3     dispatch_sync(queue, ^{
            4         NSLog(@"1");
            5     });
            6
            7     NSLog(@"2");
            這就意味著,當主線程將任務分給子線程后,主線程會等待子線程執行完畢,再繼續執行自身的內容,那么結果顯然就是12了。
            需要注意的一點是,這里用的是全局隊列,那如果把dispatch_sync的隊列換成主線程隊列會怎么樣呢:
            1     dispatch_queue_t queue = dispatch_get_main_queue();
            2     dispatch_sync(queue, ^{
            3         NSLog(@"1");
            4     });
            這段代碼會發生死鎖,因為:
            1.主線程通過dispatch_sync把block交給主隊列后,會等待block里的任務結束再往下走自身的任務,
            2.而隊列是先進先出的,block里的任務也在等待主隊列當中排在它之前的任務都執行完了再走自己。
            這種循環等待就形成了死鎖。所以在主線程當中使用dispatch_sync將任務加到主隊列是不可取的。
            創建隊列
            我們可以使用系統提供的函數獲取主串行隊列和全局并行隊列,當然也可以自己手動創建串行和并行隊列,代碼為:
            1     dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.Steak.GCD", DISPATCH_QUEUE_SERIAL);
            2     dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.Steak.GCD", DISPATCH_QUEUE_CONCURRENT);
            在MRC下,手動創建的隊列是需要釋放的
            1     dispatch_release(myConcurrentDispatchQueue);
            手動創建的隊列和默認優先級全局隊列優先級等同,如果需要修改隊列的優先級,需要:
            1     dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.Steak.GCD", DISPATCH_QUEUE_CONCURRENT);
            2     dispatch_queue_t targetQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
            3     dispatch_set_target_queue(myConcurrentDispatchQueue, targetQueue);
            上面的代碼修改隊列的優先級為后臺級別,即與默認的后臺優先級的全局隊列等同。
            串行、并行隊列與讀寫安全性
            在向串行隊列(SerialDispatchQueue)當中加入多個block任務后,一次只能同時執行一個block,如果生成了n個串行隊列,并且向每個隊列當中都添加了任務,那么系統就會啟動n個線程來同時執行這些任務。
            對于串行隊列,正確的使用時機,是在需要解決數據/文件競爭問題時使用它。比如,我們可以令多個任務同時訪問一塊數據,這樣會出現沖突,也可以把每個操作都加入到一個串行隊列當中,因為串行隊列一次只能執行一個線程的任務,所以不會出現沖突。
            但是考慮到串行隊列會因為上下文切換而拖慢系統性能,所以我們還是很期望采用并行隊列的,來看下面的示例代碼:
          1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
          2     dispatch_async(queue, ^{
          3         //數據讀取
          4     });
          5     dispatch_async(queue, ^{
          6         //數據讀取2
          7     });
          8     dispatch_async(queue, ^{
          9         //數據寫入
          10     });
          11     dispatch_async(queue, ^{
          12         //數據讀取3
          13     });
          14     dispatch_async(queue, ^{
          15         //數據讀取4
          16     });
            顯然,這5個操作的執行順序是我們無法預期的,我們希望在讀取1和讀取2執行結束后,再執行寫入,寫入完成后再執行讀取3和讀取4。
            為了實現這個效果,這里可以使用GCD的另一個API:
            1     dispatch_barrier_async(queue, ^{
            2         //數據寫入
            3     });
            這樣就保證的寫入操作的并發安全性。
            對于沒有數據競爭的并行操作,則可以使用并行隊列(CONCURRENT)來實現。
          JOIN行為
            CGD利用dispatch_group_wait來實現多個操作的join行為,代碼如下:
          1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
          2     dispatch_group_t group = dispatch_group_create();
          3
          4     dispatch_group_async(group, queue, ^{
          5         sleep(0.5);
          6         NSLog(@"1");
          7     });
          8     dispatch_group_async(group, queue, ^{
          9         sleep(1.5);
          10         NSLog(@"2");
          11     });
          12     dispatch_group_async(group, queue, ^{
          13         sleep(2.5);
          14         NSLog(@"3");
          15     });
          16
          17     NSLog(@"aaaaa");
          18
          19     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 2ull * NSEC_PER_SEC);
          20     if (dispatch_group_wait(group, time) == 0) {
          21         NSLog(@"已經全部執行完畢");
          22     }
          23     else {
          24         NSLog(@"沒有執行完畢");
          25     }
          26
          27     NSLog(@"bbbbb");
            這里起了3個異步線程放在一個組里,之后通過dispatch_time_t創建了一個超時時間(2秒),程序之后行,立即輸出了aaaaa,這是主線程輸出的,當遇到dispatch_group_wait時,主線程會被掛起,等待2秒,在等待的過程當中,子線程分別輸出了1和2,2秒時間達到后,主線程發現組里的任務并沒有全部結束,然后輸出了bbbbb。
            在這里,如果超時時間設置得比較長(比如5秒),那么會在2.5秒時第三個任務結束后,立即輸出bbbbb,也就是說,當組中的任務全部執行完畢時,主線程就不再被阻塞了。
            如果希望永久等待下去,時間可以設置為DISPATCH_TIME_FOREVER。
            并行循環
            類似于C#的PLINQ,OC也可以讓循環并行執行,在GCD當中有一個dispatch_apply函數:
            1     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            2     dispatch_apply(20, queue, ^(size_t i) {
            3         NSLog(@"%lu", i);
            4     });
            這段代碼讓i并行循環了20次,如果內部處理的是一個數組,就可以實現對數組的并行循環了,它的內部是dispatch_sync的同步操作,所以在執行這個循環的過程當中,當前線程會被阻塞。
            暫停和恢復
            使用dispatch_suspend(queue)可以暫停隊列中任務的執行,使用dispatch_result(queue)可以繼續執行被暫停的隊列。

          posted @ 2014-08-01 09:46 順其自然EVO 閱讀(24950) | 評論 (2)編輯 收藏

          攻城師的溝通修煉

            軟件開發做久了,都會有一些角色的轉變,從最初的直接leader分配具體工作來做,到后來需要和不同部門一起協作開發,溝通都是必備技能與工具,無論升級為TL(team leader)、PM(project manager),還是繼續做軟件工程師。最初做研發時,可能更多的只是關注技術性的專業知識上,覺得做好分配給自己的本職工作是唯一目標。當你技術能力提升到一定高度的時候,領導會分配更大的項目讓你負責,這時你發現,寫代碼不再是你8小時的全部內容,你需要和產品經理探討需求,需要和其他攻城師討論技術方案,需要和其他部門協調項目進度,需要和測試人員確認測試流程。。。。等等等等,你突然發現,溝通變得越來越重要,它已經成為你完成特定行動唯一真正有效的手段。
            這種轉型,對很多工程師來說是痛苦的,很多人當初選擇做研發是覺得程序開發只面對機器而不是人,正好符合自己不善言辭的木訥內向性格,當自己在這行業學到很多技術,自以為可以松一口氣的時候,突然發現自己的性格竟然不適合這個行業了,你是否在有了很多技術經驗后有過這樣的迷茫?
            你是否在和別人溝通需求時這個表情?
            你是否也像我曾經一樣,在別人說觀點時一直在尋找一次講話的機會?或者干脆馬上粗暴的打斷別人來表達自己的立場?在產品經理提了一個大的需求改動時馬上說這個做不了?在提出技術方案后意識到錯誤,但為了程序員的自尊以及覺得其他人都不懂技術而不去做道歉不做修改?在測試人員指出某個問題時覺得測試人員太過于較真,覺得這種情況一萬年也不會出現而懶得修改?
            最近讀了一本工程師修煉的書,里面講了最重要的一條就是溝通。
            無論你從程序員升級為TL,還是PM,還是架構師,或者是高級工程師,其實都是一種晉級。溝通技術知識對你往上升是非常關鍵的技能。這種技能通常意味著維護你的職位,明確特定項目的潛在風險和當前問題。在單位等級結構的這一層上,你應該阻止產生問題、尋找問題并且解決問題。你的上級都在盯著看你的每一步動作。壓力往往會非常大。對于靠技術吃飯的人來說,若想邁出跳至管理的第一步,階梯上的下個臺階的特性已經大大變化了。尤其是,首先要求的技能是溝通范圍、數量大大地拓寬了。
            一、溝通原則
            學習有效溝通是一個終身的過程——永遠都有改善的余地。要學習的溝通原則包括:先聽后說、專心致志(人和心思在一處)、正面思考等,這些原則有助于建立與別人的信任關系,使你成為更高超的溝通者。
            1. 先聽后說
            你有沒有發現自己在某次談話中總是想尋求一次講話的機會,而沒有真正在聽別人說什么?當你沒有聽時,你傳遞給那個對你講話的人什么信息呢?
            至少表面上,你顯得不在乎別人說什么。大部分人會很快厭倦這樣的談話,因為他們說的話白白在空氣中傳播卻沒人去聽。說話的人也許會想他還有更好的事要做,而結束此次談話。如果你只是偶爾這樣做,這種行為沒什么大不了的。如果這是你的習慣做法,那么你是在自己與別人之間構筑一道墻。
            你聽的時候,是不是在找機會糾正對方?即便談論的話題在往前走,但是你的思路還停留在剛才的某一點上?
            這種情況說明,我們并沒有在聽別人說什么。講話的人對你很在乎,從其忙碌的工作中抽出時間,為你提供這些寶貴的信息,所以應該認真去聽他說什么。
            當有人與你說話時,要看著他說,并試著理解他想溝通的內容。給對方足夠的時間來表達他的觀點,然后再向其詢問要澄清的問題。向他表達非語言的反饋,例如點頭,讓他知道你在關注這次談話。
            我認為羅馬人Epictetus說得好:“我們有兩個耳朵,一個嘴巴,所以我們應該多聽少說。”
           2. 專心致志
            不管你在哪里,都應專心致志。生活中有許多事情要分神,例如這個周末你要做什么,幾分鐘前開會回來如何解決會上的問題,怎樣找個辦法告訴老板某個負面的消息,小孩今晚的英式足球比賽幾點開場……所有這些瑣事都很容易讓你想入非非。
            一般來說,人在任何時刻最多只能同時處理7件±2件那么多的事。如果你的腦袋全是一些無關緊要的瑣事,你就無法專心致志地做事。要是有人對你說話,你就會完全聽不到他在講什么。倘若他在問你問題,你可能要他們再說一遍。這種情況下,你其實是在浪費別人的時間,他們不會高興的。如果房間里有個執行官,你就會給人家留下一個持久的壞印象:真是個浪費錢的家伙!
            請你讀些時間管理方面的書,列出每天需要關注事情的清單計劃。在計劃中安排好任務的優先級(當天、本周等),并標識每個任務準備投入的時間。這個辦法能夠讓你通過計劃安排好每件事,節省你的精力去記憶周圍各種正在發生的事。
            如果某個會議不是真的需要你參加,你就不要去;假如確實需要你參加,就一定要去,而且人和心思都花在那里。
            我發現,坐直、將腳放在座位正下方、做筆記、直視正在講話的人,能夠自然而然地全神貫注于會議正在進行的事情,從說話和肢體語言兩方面都給人以積極參與的正面印象。
            不管你做什么,都要專心致志!
            3. 正面思考
            當你表達信息時,總有許多種方法去傳遞它們。信息需要真實和準確,然而表現出其意義的方式可以多種多樣。
            你可以以積極意義或消極意義提供信息。你可以基于所期望的結果選擇某種方法。也可以采用不偏不倚的方式,不帶情緒地列舉事實,盡管這通常很難做到。
            從溝通的觀點來看,人們容易注意負面的東西。通常負面消息總會帶來恐懼(當我感覺恐懼鄰近時,我會把它當做“要求集中精力的行動”的信號)。
            作為架構師,你需要避免不必要的偏見信息,讓別人能夠選擇他們要關注的信息。你可以提供若干種替代方案,但這些方案應當是客觀平等的。你需要察覺可能的辦法,而不是為別人留下疑惑。
            4. 盡早道歉
            在一天的事務中,你可能注意到對他人做的某個事情不合適或不正確。記住放下自尊去給受影響的對方道一個歉。向別人誠心道歉并不是好玩或者容易之舉,但你可以贏得別人的尊敬,展示你在盡力成長,嘗試變得更好的意圖。
            如果你道歉,對方就有可能重新審視事情,而原諒你帶來的任何苦惱傷痛。有些讓人尷尬的事情轉而有了積極意義。你與那人的關系就有了增進的機會,而不是就此冷淡。
            人的本能傾向就是讓冒犯別人后的情勢不了了之。遺憾的是,你可能埋下了讓它長大成禍患的種子,以致對你造成長期的影響。被得罪的人可能會耿耿于懷,在很長很長時間內記住這件事。那個人也許會把這件事告訴別人,說你是個什么類型的人。你和此人及周圍其他人的交往能力可能大打折扣。最后,或許你已經忘記做過的事,但是對方卻沒有忘記。
            道歉時,你要清楚地表達出要道歉的是什么,你說的是什么意思。如果你不是誠心道歉,虛假的說辭可能把事情弄得更糟。如果你不能表達誠意,就不要道歉,但你的目標應當是努力與你所交往的人修繕積極的關系。避免讓道歉使你向錯誤的方向發展,限制你的個人成長。
            5. 不要在缺陷上招致惱羞成怒
            當你在開評審會(例如產品概念評估、需求評審、設計評審、代碼評審、測試評審、產品發布評審)時,通常會檢查出評審項目的一些缺陷。評審項目的作者對于這些暴露出的缺陷當然會感到不自在。
            二、溝通策略
            在我們研究了溝通的核心原則后,現在你可以應用一系列策略來展示恒定、高效的溝通風格。
            1,多說“是”,少說“不是”
            多想解決方案,解決問題,而不是粗暴的反對。
            2,抑制想自衛的沖動
            通常在交談中,當我們聽到并不完全對自己有正面意義的事情時,我們可能會找借口,我們可能會找辦法轉移話題,并責怪他人,以使自己脫離干系?;蛘呶覀兿霃娫~奪理,以闡述那些語句。應當避免做出此反應的沖動。相反,代之以等待,并接受別人所說的話。
            在上一段描述的反應中,會談的真正興趣已經從對別人轉移到你身上。聽別人說話的行為至少暫時結束了,我們開始與會談者發出警示信號:“我們把話題引向另一個方向吧,一個和我沒關系的方向。”注意你正在用的肢體語言—胳膊交叉在胸前,或者頭轉向一邊告訴別人“我不想聽了”。
            問自己這個問題:我能從這個人說的話中學到什么?”通常,他給出的信息也許并不是你樂意聽到的,但其動機是好的,仍是你接受信息并獲得個人成長的機會。
            抑制想自衛的沖動的一個例外就是當手頭的問題涉及企業政策或你的正直時。如果別人說的話使你真正涉及與公司政策沖突或你出于正直未做某事(假如,你已經正確做出了行動)時,你需要立即抨擊這些說法。你可能想用澄清問題的辦法來明確要點,比如“你的意思是我做過某事嗎”。如果別人說“是的”,你就以“這并不準確”來明確回應;倘若人家回答“不是”,要感謝他澄清了此事。

          posted @ 2014-08-01 09:44 順其自然EVO 閱讀(172) | 評論 (0)編輯 收藏

          測試佳話—人人都是測試大牛

           何為測試?測試就是檢測,審查一個事務是否符合既定的標準。測試就像是空氣和影子,如此親密無間。曾聽聞有人說“人人都是產品經理”。這話有些過了。今日我說——人人都是測試大牛,這卻是實實在在。
            不止以下場景你是否熟悉?
            1)菜的時候看看蔬菜新鮮否?
            2)找錢時候看看真假。
            3)買衣服時看看款式默默料子。
            4)甚至打英雄聯盟時,記得插眼看看情況。
            如此之類不勝枚舉,其實測試天賦是天生的,只要人有欲有求,就有測試,只有有原則,有所謂的世界觀,價值觀,就有測試,因為你為人處事,不也拿實際情況和內心的標準做對比嘛?
            我說,其實每個人都是被封印的測試大牛,測試工作,更容易無師自通。測試思維鍛煉在于平常。厚積而薄發,遲早你會有功成名就的一天。不是嗎?下面我們來看面試官總愛問的一道看似無理的問題“我身邊有個桌子,你測試下吧”看似無從著手嘛?錯,其實靈感就來源于生活。
            1)一個桌子的本質就是放東西吧,測測其承重力。
            2)或許他是一個家具,就測測其樣子,形貌。
            3)熱的食物放在上面,就是個問題,何不測測其耐熱能力,甚至是防火,放水等。
            4)桌子旁邊坐的是人,何不測測它的容量。
            5)家里有孩子會不會磕到?測測其安全系數。
            6)桌子的伴侶是椅子,何不測測它的百搭系數?
            7)古語有個拍案而起,生氣了喜歡敲桌子,何不測測其抗擊打,甚至是抗磨損能力。
            8)如果你用它打游戲,怎能不要求平穩能力?
            諸如此類等等,等等……其實測試思維來源于生活的思考和積累,正如那句話,世界上不是缺少美,而是缺少發現美的眼睛,不用等著所謂的大牛去點化你,只要你夠用心,善于總結思考,你就是大牛了。大道至簡,最總要返璞歸真,測試也不例外,不過是讓一個產品的質量盡可能高。
            在此我不妨啰嗦一句,有的不負責任的測試人員說,測試不能提高產品的質量,想要提高只能靠研發,和產品同學。我說大謬,那老板要你吃白飯嘛?所謂不以善小而不為,起碼我們能保證用戶看到盡可能高質量的產品,能對內提出合理的改進意見,只要言辭得當,相信大家也會樂意配合。天下興亡匹夫有責,何況測試人員在質量問題上責無旁貸。哪怕你就當自己是個監軍,你卻真的明白監軍的職責和任務嘛?
            自豪的做個測試人員,因為我們是天縱英豪。意隨心動,發覺自己的測試天賦。

          posted @ 2014-08-01 09:42 順其自然EVO 閱讀(211) | 評論 (0)編輯 收藏

          Unity3d與iOS交互開發—接入平臺SDK必備技能

          前言廢話:開發手機游戲都知道,你要接入各種平臺的SDK。那就需要Unity3d與iOS中Objective-C的函數有交互,所以你就需要用到如下內容:
            一、Unity3d  To  iOS:
            1、創建一個C#文件 SdkToIOS.cs 這是調用iOS函數的接口:
          public class SdkToIOS: MonoBehaviour
          {
          //平臺接入開關
          public static bool isOpenPlatform = false;
          //導入定義到.m文件中的C函數
          [DllImport("__Internal")]
          private static extern void _PlatformInit();
          //定義接口函數供游戲邏輯調用
          public static void InitSDK()
          {
          if (isOpenPlatform)
          {
          _PlatformInit();
          }
          }
          }
            2、編寫與接口對應的Objective-c函數:
          //  MyIOSSdk.h
          #import <Foundation/Foundation.h>
          @interface MyIOSSdk : NSObject
          @end
          //  MyIOSSdk.m
          #import "MyIOSSdk.h"
          //這里引用SDK的頭文件
          #import "SDKPlatform.h"
          #if defined(__cplusplus)
          extern "C"{
          #endif
          extern void UnitySendMessage(const charchar *, const charchar *, const charchar *);
          extern NSString* _CreateNSString (const char* string);
          #if defined(__cplusplus)
          }
          #endif
          //*****************************************************************************
          @implementation MyIOSSdk
          //**********************
          //message tools
          + (void)sendU3dMessage:(NSString *)messageName param:(NSDictionary *)dict
          {
          NSString *param = @"";
          if ( nil != dict ) {
          for (NSString *key in dict)
          {
          if ([param length] == 0)
          {
          param = [param stringByAppendingFormat:@"%@=%@", key, [dict valueForKey:key]];
          }
          else
          {
          param = [param stringByAppendingFormat:@"&%@=%@", key, [dict valueForKey:key]];
          }
          }
          }
          UnitySendMessage("SDK_Object", [messageName UTF8String], [param UTF8String]);
          }
          //**********************
          //SDK fun
          //初始化SDK
          -(void)SDKInit
          {
          SDKcfg *cfg = [[[SDKcfg alloc] init] autorelease];
          cfg.appid =123456;
          cfg.appKey =@"aoaoaoaoaoaoaoaoaoaoaoaoaaoaoaoaoaoaoao";
          cfg.orientation = UIDeviceOrientationLandscapeLeft;
          //調用SDK的初始化函數
          [[SDKPlatform defaultPlatform] SDKInit:cfg];
          //添加回調監聽
          [[SDKPlatform defaultPlatform] addObserver:self selector:@selector(SNSInitResult:) name:(NSString *)kInitNotification object:nil];
          }
          //獲取用戶ID
          -(NSString*)SDKGetUserID
          {
          [[SDKPlatform defaultPlatform] SDKGetUserID];
          }
          //**********************
          //call back fun
          //初始化更新回調
          - (void)SNSInitResult:(NSNotification *)notify
          {
          [MyIOSSdk sendU3dMessage:@"SDKMsgInit" param:nil];
          }
          @end
          //*****************************************************************************
          #if defined(__cplusplus)
          extern "C"{
          #endif
          //字符串轉化的工具函數
          NSString* _CreateNSString (const char* string)
          {
          if (string)
          return [NSString stringWithUTF8String: string];
          else
          return [NSString stringWithUTF8String: ""];
          }
          char* _MakeStringCopy( const char* string)
          {
          if (NULL == string) {
          return NULL;
          }
          char* res = (char*)malloc(strlen(string)+1);
          strcpy(res, string);
          return res;
          }
          static MyIOSSdk *mySDK;
          //供u3d調用的c函數
          void _PlatformInit()
          {
          if(mySDK==NULL)
          {
          mySDK = [[MyIOSSdk alloc]init];
          }
          [lsSDK SDKInit];
          }
          //注意這個函數是返回字符串
          const char* _PlatformGetUin()
          {
          if(lsSDK==NULL)
          {
          lsSDK = [[MyIOSSdk alloc]init];
          }
          return _MakeStringCopy([[lsSDK SDKGetUserID] UTF8String]);
          }
          #if defined(__cplusplus)
          }
          #endif
            值得一提的是在上面的代碼中特意寫了一個返回字符串的例子,因為你要獲取用戶ID 、昵稱什么的。對應在cs文件中導入函數如下:
            [DllImport ("__Internal")]
            private static extern string _PlatformGetUin();
            這里的const char* 會被C#自動轉換成string因為在m文件中使用了內存申請,該段內存自然是處在堆內存中,這樣轉成string符合c#的內存管理機制,我們不用擔心它的釋放問題。
            3、在你的工程目錄中找個地方保存iOS的文件
            打包出XCode工程后導入進去,加入你的SDK就可以了。
            有一點需要說明,如果存放目錄為\Assets\Plugins\iOS,那么Unity3d會自動將該目錄下的所有文件(暫不支持子文件夾)當做插件文件打包到Xcode工程下的Libraries目錄下,這樣你就不需要在手動添加了,否則會報錯重復聲明什么的。
            這種文件各個平臺會有多個,可以使用同一頭文件且定義的C函數名也都相同,這樣更有利于多版本管理。
            二、iOS To  Unity3d:
            這個在上面的 MyIOSSdk.m 文件中已經有劇透了,就是利用unity3d 的UnitySendMessage函數,其中參數1是場景中接受消息的對象,參數2是要執行的函數名,參數3為傳入參數,只要按照如下步驟就可以實現這個機制:
            1、在場景中創建一個對象用于接受iOS消息,或者用現有的也可以;
            2、為SDK消息寫一個腳本,里面包含各種消息函數;
            3、將腳本掛到之前創建的對象上完事;
            需要注意:這個對象在場景切換時候要始終存在,或者你在每個場景中都加個這玩意也可以,總之只要能收到消息就行了;
            另外,針對參數的傳遞對應上面的sendU3dMessage函數,我還在消息接受腳本中寫過一個消息參數的解析:
          void ParseMsg(string msg, out Dictionary<string, string> dicMsg){
          if( null == msg || 0 == msg.Length ){
          dicMsg = null;
          return;
          }
          dicMsg = new Dictionary<string, string>();
          string[] msgArray = msg.Split('&');
          for( int i=0; i<msgArray.Length; i++){
          string[] elementArray = msgArray[i].Split('=');
          dicMsg.Add(elementArray[0],elementArray[1]);
          }
          }
            這個我自己都還沒有實際使用過,有錯誤自行解決大致是這樣。
            ps:關于SDK的接入還有 android版本的尚未研究網上有很多可以參照;
            pps:這種交互方式在iOS的模擬器上貌似不行,測試請使用真機;

          posted @ 2014-07-31 10:09 順其自然EVO 閱讀(3170) | 評論 (1)編輯 收藏

          配置Mysql數據庫主從同步

          項目需求:
            1:主數據庫ip:192.168.1.31從數據庫ip:192.168.1.32
            2:建立主從關系,實現數據主從同步
            實現步驟:
            1:配置主數據庫的主配置文件,重啟服務
            [root@zhu~]#vim/etc/my.cnf
            [mysqld]
            server_id=31
            log_bin
            [root@zhu~]#servicemysqlrestart
            2:給從數據庫用戶授權
            mysql>grantreplicationslaveon*.*toslave@"192.168.1.32"identifiedby"123";
            3:配置從數據庫的主配置文件,重啟服務
            [root@cong~]#vim/etc/my.cnf
            [mysqld]
            server_id=32
            [root@cong~]#servicemysqlrestart
            4:從數據庫指定主數據庫參數
            mysql>changemasterto
            ->master_host="192.168.1.31",
            ->master_user="slave",
            ->master_password="123",
            ->master_log_file="localhost-bin.000001",
            ->master_log_pos=472;
            5:開啟從數據庫同步功能

          posted @ 2014-07-31 10:08 順其自然EVO 閱讀(203) | 評論 (0)編輯 收藏

          Java路徑問題解決方案匯集

          Java路徑中的空格問題
            1、 URLTest.class.getResource("/").getPath();
            URLTest.class.getResource("/").getFile();
            URLTest.class.getClassLoader().getResource("").getPath();
            Thread.currentThread().getContextClassLoader().getResource("").getPath();等多種相似方式獲得的路徑,不能被FileReader()和FileWriter()直接應用,原因是URL對空格,特殊字符(%,#,[]等)和中文進行了編碼處理。如果文件中URLTest.class.getResource("/").getPath();必須以"/"開頭然后再加文件名,而URLTest.class.getClassLoader().getResource("").getPath();不用加"/"可以直接添加文件名。
            路徑中包含空格時,如果空格變為"%20"有如下處理方法:
            1)使用repaceAll("%20",' ')替換,但只能解決空格問題,如果路徑中包含其他特殊字符和中文就不能解決問題。
            2)使用URLDecoder.decode(str,"UTF-8")解碼,但是只能解決一部分,若路徑中含有+,也是不能解決的,原因是URL并不是完全用URLEncoder.encode(str,"UTF-8")編碼的,+號被解碼后,則變成空格。
            3)解決所有的問題,用URLTest.class.getClassLoader().getResource("").toURI().getPath();,但是需要處理URISyntaxException異常,比較麻煩一些。
            2、new URL();的參數可以為正確的URI,或者為URI格式的字符串;若字符串是非完整的URI格式,則創建失敗。java.net.URI返回的路徑中的空格以“空格”的形式出現方法為Thread.currentThread().getContextClassLoader()http://www.huiyi8.com/jiaoben/網頁特效代碼 .getResource("").toURI().getPath();但是Thread.currentThread().getContextClassLoader().getResource("").toURI().toString();則會以“%20”的形式出現。java.net.URL返回的一切路徑中的空格都是以“%20”的形式出現。URL/URI返回的路徑分隔符都是“/”(控制臺輸出"/")。
            3、new File(String filePath);接受正確URI格式的參數和帶“空格”(非%20)的正確相對/絕對字符串路徑,否則即使給的路徑是正確的也會出現找不到文件的異常。File返回的路徑分隔符都為“\”(控制臺輸出"\"),對于存在的文件返回的路徑字符串,空格都以"空格"出現,而不存在的路徑new出的file,getPath()返回的路徑中的空格,仍是new File(String filePath)的參數中原有的形式,即若filePath中是空格的getPath()返回的仍是空格,是“%20”的仍是“%20”。File.toURI() 會將file的路徑名中的“空格”轉化為“%20”,然后在路徑前加protocol:"file:/",而File.toURL()只會在file路徑 前簡單的加上protocol:"file:/",而不會將“空格”轉化為“%20”,原來的無論是“空格”還是“%20”都只會原樣保留。
            實際使用中遇到的問題總結如下:
            1、相對路徑(即相對于當前用戶目錄的相對路徑)均可通過以下方式獲得(不論是一般的java項目還是web項目)String relativelyPath=System.getProperty("user.dir"); 對于一般的java項目中的文件是相對于項目的根目錄,而對于web項目中的文件路徑,可能是服務器的某個路徑,同時不同的web服務器也不同 (tomcat是相對于 tomcat安裝目錄\bin)。為此,個人認為,在web項目中,最好不要使用“相對于當前用戶目錄的相對路徑”。然而默認情況下,java.io 包中的類總是根據當前用戶目錄來分析相對路徑名。此目錄由系統屬性 user.dir 指定,通常是 Java 虛擬機的調用目錄。這就是說,在使用java.io包中的類時,最好不要使用相對路徑。否則,雖然在SE程序中可能還算正常,但是到了EE程序中,可能會出現問題。
            2、web項目根目錄獲取
            1)建立一個servlet,在其init()方法中添加如下代碼
            ServletContext context = this.getServletContext();
            String strs = context.getRealPath("/");
            2)利用httpServletRequest,得到相應的項目路徑
            String pathUrl = request.getSession().getServletContext().getRealPath("/");

          posted @ 2014-07-31 10:07 順其自然EVO 閱讀(190) | 評論 (0)編輯 收藏

          項目經理應該具備的技能

           作為一個優秀的項目經理應該具備五個方面的技能:
            項目管理知識體系
            應用領域的相關知識、標準和規則
            項目環境知識
            一般管理知識
            軟技能/人際關系技能
            項目管理知識體系
            就是要掌握常說的9大知識領域:范圍、時間、成本、質量、人力資源、風險、溝通、采購再加上集成管理,以及項目經理使用的工具和技術,包括甘特圖、進程報告、范圍說明書、WBS等等常見的工具。
            應用領域的相關知識、標準和規則
            以我的理解就是要掌握所管理的項目所在行業的基本的東西,這樣有助于獲取需求、與客戶溝通等等。
            項目環境知識
            這一點對于項目經理很重要。對于不同的組織和項目,項目環境不盡相同,但是有些技能確實可以共享的。這些技能包括感知周圍的變化(比如客戶單位人員變動、該領域的政策的變化、客戶人員之間微妙的復雜關系等等),感知組織如何在其特定的政治、社會和自然環境下運轉(比如客戶企業在該領域所處地位、其產品情況等等)。另外,在組織中大多數項目都會引起組織的變化,并且許多項目自身也包含著變化,所以項目經理必須善于引導和處理變化。
            一般的管理知識和技能
            項目經理應該了解財務管理、會計、合同、融資、銷售、營銷、物流、組織結構、人事管理等等。
            軟技能/人際關系技能
            這一點對項目經理尤為重要,原因之一,是為了理解、引導和滿足利益相關者的需求和期望,項目經理必須帶頭、溝通、談判、解決問題并影響組織。另外,他們需要積極傾聽他人意見,幫助開發解決問題的新方法,并說服他人為了達到項目目標而一起工作。其次,項目經理必須通過提供愿景、分配工作、創造有活力和積極的環境,以及為其他人樹立一個合適、有效的行為榜樣來領導項目團隊。他需要能夠激勵不同類型的員工,并且需要保持項目團隊和其他項目利益相關者之間培養起團隊精神。再者,由于大多數項目存在變化,并且需要保持各個沖突項目目標之間的平衡,隨意具有較強的應對技能也是十分重要的。
            根據調查來自不同行業的項目管理專家,得出10項最主要的技能:
            1、人際關系技能
            2、領導能力
            3、善于傾聽
            4、正直、道德行為、堅定
            5、善于建立信任關系
            6、口頭溝通
            7、善于創建團隊
            8、解決沖突、沖突管理
            9、批判式思考,解決問題
            10、理解、權衡優先
            所以項目經理都應該不斷豐富自己在項目管理、一般管理、軟技能和所在行業所需要的知識和經驗。但是很有有IT專業人員在培養自己的商業頭腦方面花費時間。任何人,無論在技術方面多么擅長,也都應該培養自己的商業技能和軟技能。

          posted @ 2014-07-31 10:06 順其自然EVO 閱讀(805) | 評論 (0)編輯 收藏

          淺談軟件項目的需求管理

          軟件項目區別于其它項目的最顯著的特征是其不可見性,它不像硬件購銷、建筑工程,都是實實在在可見的東西。而軟件項目在系統交付之前很長一段時間,客戶是無法感知自己想要的系統究竟是什么樣子。因此,需求管理就顯得十分重要,據相關統計數據分析,軟件項目90%以上失敗的原因都在于沒有重視需求或者需求管理方面做的不到位導致的。
            需求管理作為軟件項目管理的一個重要內容,貫穿項目實施的全生命周期。俗話說:萬事開頭難。需求作為軟件開發的第一個環節,其重要性不言而喻。市面上關于需求管理的相關理論和書籍很多,但多數停留在理論層面,實操性不強。本文主要是根據我們以往項目的經驗,進行一些需求管理方面的探討。我們可以簡單的將軟件項目的需求管理分為需求獲取、需求分析與驗證、需求變更控制三個核心內容。
            (一)需求獲取
            需求獲取是軟件項目需求管理的第一個過程,在這個過程中我們需要運用科學的方法以及相關的項目經驗庫輔助我們進行需求獲取。需求獲取的核心內容是通過調研掌握軟件項目的實際需求,以便于指導整個項目的實施。需求獲取的主要方法包括:用戶訪談、問卷調查、現場觀摩、頭腦風暴等方法。在實際的項目操作過程中,相對比較明確的需求,我們可采用比較固定的需求獲取方式,比如:問卷調查等。而對于相對比較模糊的需求或者說用戶無法清晰表述自己需要的是什么的時候,我們可采用比較靈活的方式,例如:用戶訪談、現場觀摩等。
            需求的類型主要包括:業務需求、用戶需求和功能需求。在需求獲取的過程中,無論采用哪種方法,我們都需要自頂向下或自下向上去了解用戶真實的想法。業務需求的獲取對象主要是客戶的高層領導,我們都知道,項目的發起、實施、最終的成敗很大程度上都取決于高層領導,我們需要對他們進行訪談,了解高層領導的公司戰略、發展方向,更為重要的是獲取他們對將要開發的軟件系統的期望,以及希望該系統在解決現有業務問題,對公司整體戰略的支撐方面的期望。幫助我們去更好地理解系統的宏觀構想。在掌握了業務需求后,我們需要對中層管理人員進行調研,核心問題是搞清楚在宏觀戰略目標落地的這層,或者說指標細化并負責實施的中層他們對軟件系統的期望以及實際要求,他們或希望此系統能夠帶來工作便利,或希望此系統能夠做到精細化管理,如此等等。但他們都是具體的業務部門負責人,對自身的業務以及系統對業務的促進方面,有比較深刻的體會。最后,我們需要在掌握了業務需求、用戶需求的基礎之上,通過對IT管理部門、主要操作人員的需求調研或根據我們對需求的理解,細化出系統的功能需求,這個需求是最低層次的需求,也是一個層層落地的過程。
            (二)需求分析與驗證
            在獲取到軟件項目需求后,接下來的工作就是對需求進行分析與驗證,在項目的實際操作過程中,主要包括:需求分析建模、需求規格說明書編寫和需求評審三個大的階段。
            需求分析建模主要是對已搜集到的信息進行提煉、分析和仔細審查,為最終用戶所看到的系統建立一個概念模型,確保所有干系人都明白其含義,并能找出其中的錯誤、遺漏或不足。需求分析是軟件項目需求管理的最重要一環。
            在需求分析與建模過程中,對于用戶需求不確定或用戶無法清晰表述需求的,為了加快項目進度,我們往往采用原型法進行需求分析與建模,即根據我們的經驗以及對用戶基本需求的理解,用Axure等原型設計工具搭建一套原型系統。另外,我們還需要采用UML工具進行用例分析、用例描述等,并最終編寫形成《軟件需求規格說明書》。
            需求驗證或需求評審是衡量需求階段產出成果的重要手段,在完成需求分析與建模后,項目相關干系人應組織召開需求評審會,邀請相關專家、外部相關單位等進行需求評審,就需求分析的結果《需求規格說明書》、原型系統等進行評審,并對評審結果進行簽字確認,確保需求沒有偏離用戶要求,又略高于用戶要求。
            (三)需求變更控制
            需求管理貫穿于軟件項目開發的全生命周期,在完成需求獲取、分析與驗證等任務后,項目組將根據形成的相關報告進行系統設計、編碼、測試、發布等工作,這些過程其實都會涉及到需求的變更,這就需要我們有一套較好的機制和方法來管理和控制需求變更,以便于項目能夠按期保質又在成本范圍內完成。
            通常的做法是我們為了避免需求變更的無序、頻繁、過度,在項目啟動時會制定一套章程,會有一個CCB(變更控制委員會),通過召開項目啟動會的方式,給相關干系人確定項目的實施方法、里程碑、溝通計劃,并著重強調需求變更的流程。
            在實際操作中,首先是通過VSS等版本控制工具對需求文檔進行管理,建立需求基線,并通過需求跟蹤矩陣對需求項進行詳細標注。
            其次,是在項目執行過程中對需求進行變更控制,有一套規范的流程,過程雖然繁瑣,但能夠給項目的風險控制帶來很好的效果。用戶提出需求變更申請,由項目實施團隊進行需求變更的評估,評估包括可能造成的對系統其它功能的影響、實施此次變更需要投入的工作量等,評估完成后由變更控制委員會確定是否同意變更。如果同意,則由項目組進行變更的實施,并對上線后的變更內容以及整個系統進行驗證,確保不影響系統運行和操作。如果不同意,則變更不成立,直接駁回用戶方。通過這樣一種雖然看似繁瑣的方法能夠很好地進行需求變更的控制,可以有效避免無序、無理、過度的需求變更,確保項目在可控范圍內實施。
            以上是我們對軟件項目需求管理的一點認識,軟件需求管理之所以重要,主要是因為絕大多數項目的失敗主要由需求的理解不到位、需求的變更沒有得到有效控制等原因造成的。因此,這就要求我們在軟件項目的需求管理方面,要下更大的力氣去做好需求的獲取、分析、變更控制,結合項目管理的相關理論,如PMBOOK、CMMI等,在項目實踐中,不斷總結經驗教訓,做好需求管理。

          posted @ 2014-07-31 10:05 順其自然EVO 閱讀(218) | 評論 (0)編輯 收藏

          Silk Mobile – 縮水移動應用的測試周期

          Micro Focus已將從Borland接管的Silk Mobile?投放到市場,作為一種新的強大的移動應用測試解決方案,它將使企業能夠開發出更先進更可靠的移動商業軟件。
            作為市場上最完整的移動應用測試解決方案,Silk Mobile為移動設備上的應用提供了強大、易用的功能測試方法。Silk Mobile能夠進行跨平臺的測試,支持Android, iOS, Blackberry, Windows Mobile, Symbian和HTML5在內的多種平臺。該工具的手勢支持包括了多點觸摸,掃,拖動,縮放,滾動,專門為最終用戶與設備交互的各種方式而定制。所以,用Silk Mobile編寫的測試腳本可以將最終用戶和不同設備之間各種交互方式捕獲為成合適的信息與數據。為了增加測試腳本的多樣性,Silk Mobile測試腳本可以導出為多種腳本語言,包括Java, C#, Python和Perl.
            在當今的數字時代,移動應用在所有的大型企業的商業策略中都扮演著非常重要的角色。事實上,Micro Focus最近委托的一項調查發現,超過75%的調查對象計劃在接下來的兩年里擴大從大型機到移動設備的各種業務。Silk Mobile促進和提高了移動應用的開發質量,使得商業公司可以和客戶保持緊密聯系,從而在競爭中獲得領先。
            Micro Focus的Borland解決方案部總監Archie Roboostoff說:“開發機構比以往受到更多的持續的壓力,他們需要更快速和頻繁地交付高質量的移動應用。Silk Mobile為開發團隊提供了能夠幫助他們按期按預算交付產品的測試工具。我們的目標是讓軟件開發者的測試變得簡單起來,而Silk Mobile恰恰做到了這一點。”
            Silk Mobile是Silk軟件測試品牌的一部分,它提供了完整的自動測試以及軟件質量管理解決方案。Silk產品和測試集相配合,能夠確保整個軟件被徹底地測試,從而高質量高可靠地交付客戶。配合著Silk Mobile,Borland產品現在提供了一個全面的,端對端的應用測試解決方案,它包括移動自動測試,移動性能測試,移動網絡速度模擬,以及移動測試管理。
            使用Silk Mobile創建健壯、可重復、可維護的移動應用測試套件
            Silk Mobile測試工具的特點和優點包括:
            *廣泛的移動操作系統平臺支持*
            Silk Mobile支持在最新的多種平臺上進行軟件測試,這些平臺包括Android,iOS, Blackberry, Windows Mobile, Symbian和HTML5。無論公司策略如何,客戶都有一個抉擇:接受BYOD概念(譯者注:Bring Your Own Device指攜帶自己的設備辦公)或者繼續支持標準設備。不論哪一種選擇,Silk Mobile是跨越所有移動應用平臺的唯一選擇。
            *可視所以易用*
            通過可視化捕捉功能,直接在移動設備上錄制測試,并且可視化地創建,回放和編輯這些測試。另外,可視化的操作和驗證命令可以直接加入到測試腳本中而不用編寫任何代碼。
            *原生的圖像和光學字符識別*
            測試功能不會因為操作系統的改變而受到影響,因為Silk Mobile使用了“三層方法”來識別導航和屏幕內容。客戶永遠不用停止測試來等待最新的操作系統發布,這意味著不會耽誤自動測試的過程。
            *手勢支持,像用戶那樣使用*
            像最終用戶那樣和移動設備進行交互。Silk Mobile支持多點觸摸,掃,拖拽,放大縮小,滾動等操作。測試應用同時還和手勢、虛擬鍵盤、報警/通知等互補,所以設備信息的獲取對于捕捉設備是如何被實際被使用的來說是相當關鍵的。
            *廣泛的腳本語言選擇*
            Silk Mobile可以將測試腳本導出為Borland Silk4j, Silk4Net, JUnit, NUnit, C#, MSTest, Python和Perl?,F在移動測試可以作為持續交付過程或是已有自動測試套件的一部分來運行。
            *集成的測試管理*
            使用Borland的Silk Center執行,計劃,維護導出的移動測試腳本。另外,Silk Center的配置測試功能允許一個私有的設備中樞進行移動應用安全測試的管理。移動測試會變成“僅僅是另一個測試”,允許客戶管理和追蹤他們的移動應用,而忽略設備平臺的差異性。
            關于Borland
            Borland軟件公司成立于1983年,是世界級的需求、測試和變更管理解決方案提供商。作為Mirco Focus有限公司(FTSE 250)的一部分, Borland提供了橫跨整個應用開發生命周期的多種開放、敏捷的工具,使得客戶可以更好更快地開發軟件。

          posted @ 2014-07-31 10:03 順其自然EVO 閱讀(203) | 評論 (0)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 74 75 76 77 78 79 80 81 82 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 桐梓县| 武邑县| 贞丰县| 老河口市| 松江区| 丹东市| 当阳市| 松原市| 新余市| 大兴区| 邹平县| 名山县| 宝鸡市| 晋中市| 柘城县| 上思县| 邹平县| 邓州市| 石渠县| 西华县| 仙居县| 乌兰浩特市| 高清| 大新县| 岑溪市| 崇礼县| 呼图壁县| 大兴区| 拉孜县| 尼木县| 平南县| 台中市| 兴宁市| 漾濞| 舞钢市| 阳西县| 黔东| 抚顺市| 分宜县| 原阳县| 邵阳县|