使用Selenium和openCV對HTML5 canvas遊戲進行自動化功能測試(一)

上一篇講了HTML5 canvas遊戲的基本工做原理,接下來說如何進行自動化功能測試。css

Selenium是一個跨平臺的跨瀏覽器的對網頁進行自動化測試的工具。從Selenium 2.0開始Selenium就和WebDriver合體了。若是你還不瞭解Selenium怎麼用,能夠看看官網上的例子。Selenium支持各類語言的binding,方便起見,下面的測試腳本都用Python來寫。html

自動化功能測試用例流程基本上是這樣的:啓動瀏覽器 -> 打開遊戲(網頁)-> 對遊戲圖像進行模板匹配,確保UI元素顯示正確 -> 模擬用戶操做 -> 到下一場景  -> 繼續模板匹配 -> 繼續模擬操做 -> 關閉遊戲(網頁)以及瀏覽器。若是發現問題,就意味着測試用例失敗,須要報告問題。web

假如我想測試一個HTML5 canvas遊戲,那麼首當其衝就是要找它的canvas標籤了。Selenium支持各類查找方法:canvas

  • find_element()
  • find_element_by_id()
  • find_element_by_name()
  • find_element_by_tag_name ()
  • find_element_by_css_selector()
  • find_element_by_link_text()
  • find_element_by_partial_link_text()
  • find_element_by_xpath()

挑個最容易的吧: canvas = browser.find_element_by_xpath("//canvas")瀏覽器

那麼我怎樣得到canvas中的圖像呢?有兩種辦法。一種是經過canvas.toDataURL():緩存

var strData = canvas.toDataURL('image/png');

這種方法返回一個表明整個圖像的Base64字符串。看上去就像:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg==" (若是你知道怎麼解碼,就能發現這個字符串表示了一個小圓紅點點。)jsp

另外一種方法是使用context.getImageData():工具

var dataObj= context.getImageData(x, y, w, h);

返回一個對象包含RGBA字節緩存。測試

後者比前者要快不少,而且能夠指定裁剪區域,推薦用後者。spa

不過這二者都是Javascript調用,如何和Selenium的Python腳本聯繫起來呢?

幸運的是Selenium支持直接調用Javascript:

複製代碼
def getClippedImageFromCanvas(browser, canvas, x, y, w, h):
    '''Get a clipped image from canvas using context.getImageData.'''
    data = browser.execute_script("\
        var canvas= arguments[0];\
        var x=arguments[1];\
        var y=arguments[2];\
        var w=arguments[3];\
        var h=arguments[4];\
        var context = canvas.getContext('2d');\
        var dataObj= context.getImageData(x, y, w, h);\
        var data = dataObj.data;\
        return data;"
        ,canvas, x, y, w, h) 
    data_bytes = array.array('B', data).tostring()
    im = Image.fromstring("RGBA", (w, h), data_bytes)
    return im
複製代碼

這樣咱們就得到了能夠用於Python腳本的圖像。接下去須要作的就是對圖像進行模板匹配,好比看看預期的UI元素是否出如今正確的位置。這個工做能夠由openCV完成。

除了圖像識別,咱們還須要模擬用戶操做,如鼠標點擊:

webdriver.ActionChains(browser).move_to_element_with_offset(canvas, x, y).click().perform()

Selenium/Webdriver支持鏈式操做,很cool。

相關文章
相關標籤/搜索