2015年5月28日 星期四

[Selenium] timeout of 30000ms exceeded. Ensure the done() callbacked is being called in this test

test case 寫得越來越多,越跑越多
目前都還是會出現這個錯誤
也確定done()有呼叫了,但還是一樣

一開始以為是元素沒被找才報得錯
但自己講完就覺得哪裡不對
後來守在電腦旁看,發現明明新視窗也跳出一陣子了,看test也還在跳,沒多久就報錯
該有的元素跟字串都有正確出現,
也曾看過新視窗都還沒跳出來就直接報錯

原本的寫法是

  driver.wait(webdriver.until.titleIs(testCase.firstLoginTitle),80000);   
  done();
照理說應該不會有錯阿,timeout的值也設得夠大 而且wait until titleIs也確定是這樣用,但跳出來的結果卻是時好時壞 後來決定改成這個,等晚一點全部run過看會怎樣
  driver.getTitle().then(function (title) {
    assert.equal(testCase.firstLoginTitle, title); 
    done();
  });


跑完了,嗯,用assert會比較方便一點,至少還可以看到錯誤的原因
但出現了"no such element"也是我頭痛的,這就表示真的沒找到東西

ps. 我今天整天在想可不可以把一些config的檔寫在外部,但很多人說設定global variable很不好,但...
又想起「過早最佳化是萬惡的根源」,雖然原文跟我現在所講的是有點不太一樣
但我的確常常還沒全部用完就想搞什麼最佳化,這幾年工作輕驗覺得這些作為的確有浪費時間之嫌阿
有時候會想說實在不需要低估自己處理稍微難或複雜的事情,太早先預設會怎樣實在是沒必要(但真的是非常大的專案我想是另當別論)


另外,想要把selenium的文更完整的收錄,但最近時間實在吃緊!!!

2015年5月23日 星期六

[生活] 與理髮師的愉快對話

今天去剪頭髮,從打薄頭髮開始,就不知不覺跟理髮師聊了起來
這是一個很新奇的體驗,以前的我明明不愛跟陌生人聊天的
但我今天竟然不只能面帶微笑的聽理髮師說話,也能適時的回話並讓話題延續

記得在<<未來工作在哪裡?>>曾說,你賺更多的錢你會花得更多,
追求金錢上富足是沒有到達終點的一天,相反的,人們應該多交朋友,與他人交流,這能使你心靈充足

剪頭髮中理髮師講了他的一些人生經驗,我覺得非常寶貴,我週遭並沒有這類的人
剪完頭髮後我感到非常愉快,不單是我覺得跟理髮師很投緣,頭髮我也剪得很喜歡,重點是原來人與人交流是可以這麼簡單的
感覺自己又成長了一點呢

------------------

這幾天我又回顧了最近的生活
近期每天會去某家咖啡店買早餐,店員都記得我要點的東西,說要先幫我製作
另一間包子店也是
這都是過去的我沒有過的體驗,雖然還是會太害羞而不敢直視店員的眼睛,只是低著頭說"嗯,對,請幫我先做我的飲品"
漸漸地發覺陌生人大部分還是好人的,

2015年5月22日 星期五

[Selenium] 如何關閉跳出來的廣告新視窗

原本以為第一個test case已經完成的差不多了,只要修點小東西就可以如法炮製了
心血來潮想要真的不盯著螢幕看,看會怎樣
之前為了剛過程,會先把跳出來的廣告視窗關掉

結果不把跳出來的視窗關掉的結果就是在第三步的時候就不動了
其實這也是很奇怪的結果
若當真是跳出新視窗會擋讓程式錯亂的話,但他第一第二步都還是正確運作
只有到第三步的某一頁會跳著,都是那一樣
本來還不願相信是新視窗的問題
但只要把跳出視窗關了 ,測試就會順利進行
後來找到這篇真是救了我一命!!
    driver.getAllWindowHandles().then(function (allhandles) {
        console.log(allhandles);
    });

使用getAlwindowHandles()就可以得到以陣列型式的可操作視窗的列表 大概像這樣
  ['CDwindow-fdafdsa-feawqfda-fdafdsaf', 'CDwindow-fdafdsa-feawqfda-fdafferwt4r3f']
因為跳出視窗一定是等第一個視窗load了之後才跳出來,所以跳出視窗是第二個視窗 所以我就先將主視窗移到第二個視窗上->關閉他->跳回原本的視窗
  driver.getAllWindowHandles().then(function (allhandles) {
    console.log(allhandles);
    driver.switchTo().window(allhandles[1]);
    driver.close();
    driver.switchTo().window(allhandles[0]);
  });
http://stackoverflow.com/questions/30114201/error-using-getwindowhandles-in-selenium-webdriverjs

[Selenium] 使用哪個language開發最好呢?

明明我也只會javascript, 但因為他的document真的相對很少,讓我還滿常思考這個問題

官方上主要載明的語言有java, c#, python, ruby, php, perl,雖然也有javascript,但其實是很零散的
從五月開始研究selenium,看過的論壇裡,目前看到最多人寫的是java,c#和python

我覺得要思考這個問題還是要以個人為主啦,無法說去論壇發文說"哪個語言寫selenium好"就可以得到答案。

我的想法是:

1. 你會用什麼語言
- 最主要也是是重要的,不會寫什麼都是枉然

2. 你能獲得最大的support是哪個
- 除非你會二三種以上的語言,已經到能讓你苦惱要選哪一個的時候(好奢侈的苦惱)
- 除了官方document的support外,如果說公司裡有人能直接指導你的那種support就會更有力

目前就只想到兩個,第一個的權重大概就要先乘10
其外還有想到成本阿,什麼的,但那些都是非常非常小部分的問題了
除非想要整個都外包出去,就會是一筆金額....

其實這篇是要說服我自己不要再跑去看其他語言的寫法,真的沒時間了T_T
(要是時間夠好想用ruby)

2015年5月21日 星期四

[Assert] 斷言

碰到測試就不得不提斷言
判斷實際值與預設值有沒有相同
先不談世面上幾個比較知名的測試用斷言

我想先知道簡單用javascript如果要檢測是否"含有"某幾個字該如何做呢?

以下文章提到ECMAScript 2015將會有一個method叫做includes()
現階段來說,主要就是用indexof方法

http://stackoverflow.com/questions/1789945/how-can-i-check-if-one-string-contains-another-substring

2015年5月20日 星期三

[Selenium] getText()

getText()是個還滿容易用到的字
但卻發現他拿到的字在某些時候不能用
當時我要把得到的字放到url上,卻一直顯示promise status pending 或fullfill的字樣
怪我js沒學好,promise也還不熟
後來要拿他來做最簡單的assertion也不行,我猜也是跟上面的問題有關

在webdriverjs的範例裡,都要先這樣
  driver.getTitle().then(function(title) {
    assertEquals("webdriver - Google Search", title);
  });

這一篇是有類似問題的,但他是用在protractor
stackoverflow也有講述: http://stackoverflow.com/questions/20213675/how-to-convert-a-promise-in-protractor-to-a-float

 下面是webdriver的
http://stackoverflow.com/questions/25027422/selenium-webdriver-javascript-promise-seems-to-not-be-resolved

[Selenium] Xpath

在selenium選取元件有很多種方式,其中一種是Xpath
今天我的網頁架構如下,我想要得到aaabbbccc這個值, 但這個table又沒有可以取得的class或id,於是就可以使用Xpath
  
item1 12345678910
item2 aaabbbccc

  webdriver.By.xpath("//tr[contains(.,'item2')]//td[2]")

用口語一點的說法是"在含有item2這個字的tr(tr[contains(.,'item2')])的下一層(//)裡的第二個td(td[2])

當時我有6成信心這樣寫應該是對的
但就是一直出錯,而且我還不知道要怎麼印出這個值
後來把他sendkey到一個input上才看到原因出在哪裡,
當時印出來變成item1 12345678910 ...
可能礙於那個input有字數限制,不然應該會把整個table裡的所有值都印出來
後來才發現原來這個table外面還有一個table:
也就是說tr[contains(.,'item2')]的這個寫法會被視為你要長的是最外層的那個tr,而不是item2外面的那個tr
而你現在要找最外層那個tr裡面的第二個td

  
... /*<-選到這個*/
item1 12345678910
item2 12345678910

所以最後寫法是
  webdriver.By.xpath("//table//tbody//tr//table//tr[contains(.,'item2')]//td[2]"))

2015年5月19日 星期二

[Selenium] 用javascript開發selenium的另一個選擇 - WebdriverIO


官方網站:http://webdriver.io/

稍微翻譯一下首頁

WebdriverIO是什麼呢?
WebdriverIO讓你能用少少幾行code就能操作瀏覽器或是手機應用程式你的測試程式會看起來很簡單、簡潔而且容易閱讀。
建立自動化測試就是這麼簡單:


var webdriverio = require('webdriverio');

var options = { desiredCapabilities: { browserName: 'chrome' } };

webdriverio

    .remote(options)

    .init()

    .url('http://www.google.com')

    .title(function(err, res) {

        console.log('Title was: ' + res.value);

        // outputs: "Title was: Google"

    })

    .end();






WebdriverIO要怎麼使用呢?
WebdriverIO是在nodejs上運行的一套開源(open source)測試程式。能讓人們用javascript撰寫超簡單的selenium測試,不論要BDD(註1)或TDD(註2)都行。
連Cucumber 測試都有支援呦!

基本上,WebdriverIO就是利用WebDriver Wire Protocol傳送請求(request)給Selenium Server,並處理他的回應。
這些請求(requests)都被包裝成好用的指令(command),提供callback去自動化測試你網站的許多外觀


註1
BDD: behavior-driven development 行為驅動開發

註2
TDD: Test-driven development 測試驅動開發



[Selenium] 使用javascript開發automation test

其實看了Selenium的官方網站
相較於java, python, ruby的文件,javascript真的少很多
但由於公司把automation test列為前端工作,所以就沒什麼選擇要用javascript來開發

目前官方的把使用javascript bingding for webdriver稱做WebDriverJs
https://code.google.com/p/selenium/wiki/WebDriverJs(最後更新2014.08)
目前我都是根據這個來執行

(但看他首頁寫目前文件都移到github了
https://github.com/SeleniumHQ/selenium/tree/master/javascript)


很快速的執行,在nodejs的command prompt裡打

npm install selenium-webdriver

其實就好了XD
到node js的modules裡找到selenium-webdriver > example
就可以執行裡面的code,立馬能看到神奇的效果

執行
node node_modules/selenium-webdriver/example/google_search_generator.js

就可以開始自動化測試了,就會看他開啟瀏覽器,然後很多動作
這時候就可以來做自己需要的自動化測試

當然例子用到的東西很少,更多功能要去看一下WebDriverJs有什麼可用的
javascript,java, python, ruby之間能用的方式其實都有些微的差別,舉例:

所以要好好查document呦!http://selenium.googlecode.com/git/docs/api/javascript/index.html
reference: http://www.slideshare.net/LivePersonDev/selenium-webdriver-element-locators

[Selenium] 跳出視窗的登入畫面要怎麼輸入

Selenium可以用selector選取畫面的元素,並指定此元素輸入值或其他操作
但像是這種視窗跳出要求登入的界面,要怎麼選取要怎麼輸入值來登入呢

你可以把帳密打在出現這個popup的url上,我已經試過可行了,感到神奇!

http://帳號:密碼@網址

http://username:password@xyz.com 

reference: http://stackoverflow.com/questions/12151958/login-popup-window-using-selenium-webdriver


對了,如果密碼含有特殊字元,要先encodeURIComponent

[Selenium] 在跑test suit時會因為一個錯誤導致後面的test case都不跑的解法

雖然現在連test case都還沒完整寫完一個,每個步驟都有不同的卡法T_T
但先記錄一下

每一個test之間都應該有不同的session
也就是開始一個test之前要init()初始新的session,結束了就要end()結束這個session
不能不同test之間用同一個seesion,這也能避免某一個test有出錯會影響到其他的test case


reference: http://stackoverflow.com/questions/13352860/node-js-mocha-webdriverjs-failed-tests-kill-suite

這觀念其實在單元測試也一樣
(結果因為語言的關係還跟美國那裡搞出了點誤會...)

這也是看測試時常見的幾個詞 setup(建立) 跟tear down(拆掉)
以jasmine來說(其實mocha也是這樣寫?),會有幾個功能是來設定這些的
beforeAll: 在所有測試之前; beforeEach: 在每一個測試之前
afterAll: 在所有測試之後; afterEach: 在每一個測試之後

而setup 跟tear down就是要在beforeEach時setup, afterEach時tear down

新案子 - 測試

先話說之前跟測試結下的緣,當初公司說可以申請買書,我申請的其中一本就是「可測試的Javascript」
主要是我覺得這本比較少聽人提起,我又想看看裡面寫什麼,
也可能是因為這樣,大家以為我對這個有興趣~所以請我接(但其實不是的XD)

我覺得測試是個滿特別的領域
原本以為是個滿直覺滿視覺化的事,但翻了書之後根本看不懂
尤其是單元測試...

從三月中開始執行testing的工作,是一個全新的領域,雖然讓我很焦慮,
但不時提醒自己未來要接觸未知的領域會越來越多,一定要習慣這種感覺,甚至要知道怎麼學習才是最快的

三月中到五月初時原本是在做單元測試(Unit Test)
說真的,單元測試真的深澳多了,為了讓一個單元能非常乾淨的測試,會使用到的其他function全要使用模擬的方式執行
而且嚴禁與server對話,不論前端,直到最近改成後端要做單元測試,也是不斷被糾正說只要跟server有連接的一律都不是單元測試
因為我是去接別人寫完的code寫單元測試,所以在很龐大的架構下要知道某個function到底會牽涉到哪些東西我並不是很了解
不知道是不是這個原因讓我覺得單元測試非常困難
如果我是開發的人,邊寫邊做單元測試不知是否會很簡單

只不過後來風向變了,現在要做整合測試(Integration Test)
到目前研究了約二個星期,預計三個星期要把所有的case做完,
來快速記錄一下

2015年5月5日 星期二

[VBA] 二種開啟文字檔資料剖析

一開始錄製巨集得到開啟檔案的方法是OpenText
你可以加入參數DataType:=xlDelimited,(DataType一定要是xlDelimited,才能使用Comma:=True)後告知Comma:=True,要以逗號為分隔字元
reference: https://msdn.microsoft.com/zh-tw/library/office/ff837097.aspx

但今天我的檔名未知,要巨集自動幫我跑整個資料夾內的資料
我找到的範例是使用Open方法,此時可以用Format這個參數,Format:=2就是以逗號為分隔
reference: https://msdn.microsoft.com/en-us/library/office/ff194819.aspx

2015年5月4日 星期一

用notepad++最小化(minify)code

為了壓縮檔案,或是單純需一整行的code,就會需要最小化(minify)整個code 想要把原本排版好的code改成一整行,除了手動一個一個刪掉空格跟跳行外 用notepad++的話可以簡單使用內建的功能
 1.這是原本的code
 

 2.Edit > Blank Operations > Remove Unnecessary Blank and EOL(移除不需要的空白和換行)
 

3.好囉!
 

當然Blank Operations(空白操作)還有很多方便的功能,這裡的Blank可以泛指空白鍵打出來的空格(space),縮排鍵的tab,enter鍵的換行(EOL, end of line) 像是把每行最前面的空格(space)縮減 Edit > Blank Operations > Trim Leading Space  


還有以下可操作的選項
Trim Trailing Space -> 縮減後方空格
Trim Leading Space -> 縮減前方空格
Trim Leading and Trailing Space -> 縮減前後方空格
EOL to Space -> 換行轉空格
Remove Unnecessary Blank and EOL -> 移除不需要的空白和換行

TAB to Space -> TAB轉轉空格
Space to Tab (All) ->空格轉TAB(全部)
Space to Tab (Leading) ->空格轉TAB(前面)  


使用心得:

使用起來順手快速,不過"移除不需要的空白和換行"之後不知為何換行會替換成空格,我預期希望是連空格都沒有

目前僅用HTML測試,在TAG裡的文字就算有空格也不會被刪除