先決條件: | 熟悉核心 HTML , CSS 和 JavaScript 語(yǔ)言; 高級(jí)跨瀏覽器測(cè)試原則和自動(dòng)測(cè)試的概念。 |
---|---|
目的: | 展示如何在本地設(shè)置Selenium測(cè)試環(huán)境并使用它運(yùn)行測(cè)試,以及如何將它與諸如Sauce Labs之類(lèi)的應(yīng)用程序集成。 |
Selenium 是最流行的瀏覽器自動(dòng)化工具。 還有其他方法,但使用Selenium的最好方法是通過(guò)WebDriver,一個(gè)強(qiáng)大的API,建立在Selenium之上,并調(diào)用瀏覽器自動(dòng)化,執(zhí)行諸如"打開(kāi)此網(wǎng)頁(yè)","移動(dòng) 頁(yè)面上的此元素","單擊此鏈接","查看鏈接是否打開(kāi)此URL"等。這是運(yùn)行自動(dòng)測(cè)試的理想選擇。
如何安裝和使用WebDriver取決于您想要用來(lái)編寫(xiě)和運(yùn)行測(cè)試的編程環(huán)境。 最流行的環(huán)境提供了一個(gè)包或框架,它將安裝WebDriver和使用這種語(yǔ)言與WebDriver通信所需的綁定,例如Java,C#,Ruby,Python,JavaScript(Node)等。參見(jiàn) >設(shè)置Selenium-WebDriver項(xiàng)目了解有關(guān)Selenium設(shè)置的更多詳細(xì)信息 不同的語(yǔ)言。
不同的瀏覽器需要不同的驅(qū)動(dòng)程序,以允許WebDriver與其通信和控制它們。 有關(guān)從何處獲取瀏覽器驅(qū)動(dòng)程序的詳細(xì)信息,請(qǐng)參閱 Selenium支持的平臺(tái)等。
我們將介紹使用Node.js編寫(xiě)和運(yùn)行Selenium測(cè)試,因?yàn)樗焖俣菀咨鲜?,并為前端開(kāi)發(fā)人員提供了一個(gè)更熟悉的環(huán)境。
注意:如果您想了解如何在其他服務(wù)器端環(huán)境中使用WebDriver,請(qǐng)查看 /platforms.jsp">由Selenium支持的平臺(tái)一些有用的鏈接。
selenium-test
.npm install selenium-webdriver
注意:即使您之前安裝了selenium-webdriver并下載了瀏覽器驅(qū)動(dòng)程序,仍然遵循這些步驟仍然是個(gè)好主意。 你應(yīng)該確保一切都是最新的。
接下來(lái),您需要下載相關(guān)的驅(qū)動(dòng)程序,以允許WebDriver控制您要測(cè)試的瀏覽器。 您可以在 selenium-webdriver 頁(yè)面上查看從何處獲取詳細(xì)信息(請(qǐng)參閱 顯然,一些瀏覽器是操作系統(tǒng)特定的,但我們將堅(jiān)持使用Firefox和Chrome,因?yàn)樗鼈兛捎糜谒械闹饕僮飨到y(tǒng)。
chromedriver
and geckodriver
driver's location to your system PATH
variable. This should be an absolute path from the root of your hard disk, to the directory containing the drivers. For example, if we were using a Mac OS X machine, our user name was bob, and we put our drivers in the root of our home folder, the path would be /Users/bob
.注意:只需重申,您添加到 PATH
的路徑需要是包含驅(qū)動(dòng)程序的目錄的路徑,而不是驅(qū)動(dòng)程序本身的路徑! 這是一個(gè)常見(jiàn)的錯(cuò)誤。
在Mac OS X /大多數(shù)Linux系統(tǒng)上設(shè)置 PATH
變量:
.bash_profile
(or .bashrc
) file (if you can't see hidden files, you'll need to display them, see Show/Hide hidden files in Mac OS X or Show hidden folders in Ubuntu).#Add WebDriver browser drivers to PATH export PATH=$PATH:/Users/bob
PATH
variable by entering the following into your terminal: echo $PATH
要在Windows上設(shè)置 PATH
變量,請(qǐng)按照 -folder-my-system-path">如何將新文件夾添加到我的系統(tǒng)路徑?
好,讓我們嘗試一個(gè)快速測(cè)試,以確保一切正常。
google_test.js
:var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until; var driver = new webdriver.Builder() .forBrowser('firefox') .build(); driver.get('http://www.google.com'); driver.findElement(By.name('q')).sendKeys('webdriver'); driver.findElement(By.name('btnG')).click(); driver.sleep(2000).then(function() { driver.getTitle().then(function(title) { if(title === 'webdriver - Google Search') { console.log('Test passed'); } else { console.log('Test failed'); } }); }); driver.quit();
node google_test
您應(yīng)該會(huì)看到Firefox的一個(gè)實(shí)例自動(dòng)打開(kāi)! Google應(yīng)自動(dòng)加載到標(biāo)簽中,應(yīng)在搜索框中輸入"webdriver",然后點(diǎn)擊搜索按鈕。 WebDriver會(huì)等待2秒; 然后訪問(wèn)文檔標(biāo)題,如果是"webdriver - Google搜索",我們將返回一條消息以聲明測(cè)試通過(guò)。 WebDriver將關(guān)閉Firefox實(shí)例并停止。
也沒(méi)有什么可以阻止你在多個(gè)瀏覽器上同時(shí)運(yùn)行測(cè)試。 讓我們?cè)囋囘@個(gè)!
google_test_multiple.js
. You can feel free to change the references to some of the other browsers we added, remove them, etc., depending on what browsers you have available to test on your operating system. In terms of what string to use inside the .forBrowser()
method for other browsers,? see the Browser enum reference page.var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until; var driver_fx = new webdriver.Builder() .forBrowser('firefox') .build(); var driver_chr = new webdriver.Builder() .forBrowser('chrome') .build(); var driver_saf = new webdriver.Builder() .forBrowser('safari') .build(); searchTest(driver_fx); searchTest(driver_chr); searchTest(driver_saf); function searchTest(driver) { driver.get('http://www.google.com'); driver.findElement(By.name('q')).sendKeys('webdriver'); driver.findElement(By.name('btnG')).click(); driver.sleep(2000).then(function() { driver.getTitle().then(function(title) { if(title === 'webdriver - Google Search') { console.log('Test passed'); } else { console.log('Test failed'); } }); }); driver.quit(); }
node google_test_multiple
所以這里我們像以前一樣進(jìn)行測(cè)試,除了這次我們將它包裝在一個(gè)函數(shù) searchTest()
中。 我們?yōu)槎鄠€(gè)瀏覽器創(chuàng)建了新的瀏覽器實(shí)例,然后將每個(gè)瀏覽器傳遞給函數(shù),以便在所有三個(gè)瀏覽器上執(zhí)行測(cè)試!
有趣嗎? 讓我們繼續(xù),看一下WebDriver語(yǔ)法的基礎(chǔ)知識(shí),更詳細(xì)一點(diǎn)。
讓我們來(lái)看看webdriver語(yǔ)法的幾個(gè)主要特性。 有關(guān)更完整的詳細(xì)信息,請(qǐng)參閱 selenium-webdriver JavaScript API 參考以獲取詳細(xì)參考,以及Selenium主文檔的 Selenium WebDriver 和 a class ="external"> WebDriver:Advanced Usage 頁(yè)面,其中包含多個(gè)以不同語(yǔ)言編寫(xiě)的示例。
要啟動(dòng)新測(cè)試,您需要包含 selenium-webdriver
模塊,如下所示:
var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until;
接下來(lái),您需要使用 new webdriver.Builder()
構(gòu)造函數(shù)創(chuàng)建驅(qū)動(dòng)程序的新實(shí)例。 這需要將 forBrowser()
方法鏈接到它上,以指定要使用此構(gòu)建器測(cè)試的瀏覽器以及 build()
方法來(lái)實(shí)際構(gòu)建它 詳細(xì)信息,請(qǐng)參見(jiàn) Builder類(lèi)參考 對(duì)這些功能)。
var driver = new webdriver.Builder() .forBrowser('firefox') .build();
注意,可以為要測(cè)試的瀏覽器設(shè)置特定的配置選項(xiàng),例如,您可以在 forBrowser()
方法中設(shè)置要測(cè)試的特定版本和操作系統(tǒng):
var driver = new webdriver.Builder() .forBrowser('firefox', '46', 'MAC') .build();
注意,可以為要測(cè)試的瀏覽器設(shè)置特定的配置選項(xiàng),例如,您可以在 forBrowser()
方法中設(shè)置要測(cè)試的特定版本和操作系統(tǒng):...
SELENIUM_BROWSER=firefox:46:MAC
讓我們創(chuàng)建一個(gè)新的測(cè)試,讓我們探討這段代碼,我們談?wù)撍?在selenium測(cè)試項(xiàng)目目錄中,創(chuàng)建一個(gè)名為 quick_test.js
的新文件,并在其中添加以下代碼:
var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until; var driver = new webdriver.Builder() .forBrowser('firefox') .build();
要加載您實(shí)際想要測(cè)試的頁(yè)面,可以使用之前創(chuàng)建的驅(qū)動(dòng)程序?qū)嵗?code> get()方法,例如:
driver.get('http://www.google.com');
注意:請(qǐng)參閱 -webdriver / lib / webdriver_exports_WebDriver.html"> WebDriver類(lèi)參考,了解本節(jié)中的功能及其下面的功能的詳細(xì)信息。
您可以使用任何網(wǎng)址指向您的資源,包括用于測(cè)試本地文檔的 file://
網(wǎng)址:
driver.get('file:///Users/chrismills/git/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html');
要么
driver.get('http://localhost:8888/fake-div-buttons.html');
但是最好使用遠(yuǎn)程服務(wù)器位置,以便代碼更靈活 - 當(dāng)您開(kāi)始使用遠(yuǎn)程服務(wù)器運(yùn)行測(cè)試(見(jiàn)后文)時(shí),如果您嘗試使用本地路徑,您的代碼將會(huì)中斷。
現(xiàn)在將此行添加到 quick_test.js
的底部:
driver.get('http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html');
現(xiàn)在我們有一個(gè)文檔要測(cè)試,我們需要以某種方式與它交互,這通常涉及首先選擇一個(gè)特定的元素來(lái)測(cè)試一些東西。 您可以在WebDriver中以多種方式選擇UI元素, 包括通過(guò)ID,類(lèi),元素名稱(chēng)等。實(shí)際選擇由 findElement()
方法完成,該方法接受選擇方法作為參數(shù)。 例如,要通過(guò)ID選擇元素:
var element = driver.findElement(By.id('myElementId'));
通過(guò)CSS查找元素的最有用的方法之一 - By.css方法允許您使用CSS選擇器選擇一個(gè)元素
現(xiàn)在在 quick_test.js
代碼的底部輸入以下內(nèi)容:
var button = driver.findElement(By.css('button:nth-of-type(1)'));
有很多方法可以與您的Web文檔和元素進(jìn)行交互。 您可以從獲取文字值開(kāi)始查看有用的常見(jiàn)示例 WebDriver文檔。
如果我們想要在我們的按鈕中獲取文本,我們可以這樣做:
button.getText().then(function(text) { console.log('Button text is \'' + text + '\''); });
現(xiàn)在將它添加到 quick_test.js
中。
確保您在項(xiàng)目目錄中,嘗試運(yùn)行測(cè)試:
node quick_test.js
您應(yīng)該會(huì)在控制臺(tái)中看到按鈕的文字標(biāo)簽。
讓我們做一些更有用的東西。 刪除以前的代碼條目,然后在底部添加此行代替:
button.click();
嘗試再次運(yùn)行測(cè)試; 該按鈕將被點(diǎn)擊,并且應(yīng)出現(xiàn) alert()
彈出窗口。 至少我們知道按鈕是工作!
您可以與彈出窗口進(jìn)行交互。 將以下代碼添加到代碼的底部,然后嘗試重新測(cè)試:
var alert = driver.switchTo().alert(); alert.getText().then(function(text) { console.log('Alert text is \'' + text + '\''); }); alert.accept();
接下來(lái),讓我們嘗試在一個(gè)表單元素中輸入一些文本。 添加以下代碼,然后嘗試再次運(yùn)行測(cè)試:
var input = driver.findElement(By.id('input1')); input.sendKeys('Filling in my form');
有些時(shí)候,你想讓W(xué)ebDriver等待某事完成后再繼續(xù)。 例如,如果加載新頁(yè)面,您將需要等待頁(yè)面的DOM完成加載,然后再?lài)L試與其任何元素交互,否則測(cè)試可能會(huì)失敗。
例如,在我們的 google_test.js
測(cè)試中,我們添加了此塊:
driver.sleep(2000).then(function() { driver.getTitle().then(function(title) { if(title === 'webdriver - Google Search') { console.log('Test passed'); } else { console.log('Test failed'); } }); });
sleep()
方法接受一個(gè)值,該值指定以毫秒為單位的等待時(shí)間 - 該方法返回一個(gè)在該時(shí)間結(jié)束時(shí)解析的promise,此時(shí) then
)執(zhí)行。 在這種情況下,我們使用 getTitle()
方法獲取當(dāng)前頁(yè)面的標(biāo)題,然后根據(jù)它的值返回一個(gè)pass或fail消息。
我們可以在 quick_test.js
測(cè)試中添加 sleep()
方法 - 嘗試將最后一行代碼包裝在這樣的塊中:
driver.sleep(2000).then(function() { ? input.sendKeys('Filling in my form'); ? input.getAttribute("value").then(function(value) { ??? if(value !== '') { ????? console.log('Form input editable'); ??? } ? }); });
WebDriver現(xiàn)在將等待2秒鐘,然后填寫(xiě)表單字段。 然后,我們通過(guò)使用 getAttribute()
來(lái)檢索它的 value
屬性值,然后測(cè)試它的值是否被填入(即不為空) 不是空的。
注意:還有一個(gè)名為 webdriver / lib / webdriver_exports_WebDriver.html#wait"> wait()
,它反復(fù)測(cè)試條件一段時(shí)間,然后繼續(xù)執(zhí)行代碼。 這也使用 util library / a>,它定義了與 wait()
一起使用的公共條件。
運(yùn)行測(cè)試后,您應(yīng)該關(guān)閉所有打開(kāi)的dirver實(shí)例,以確保您不會(huì)在您的計(jì)算機(jī)上打開(kāi)大量的流氓瀏覽器實(shí)例! 這是使用 quit()
方法完成的。 只需在您的驅(qū)動(dòng)程序?qū)嵗险{(diào)用它,當(dāng)您完成它。 現(xiàn)在將此行添加到 quick_test.js
測(cè)試的底部:
driver.quit();
當(dāng)您運(yùn)行它時(shí),您現(xiàn)在應(yīng)該看到測(cè)試執(zhí)行和瀏覽器實(shí)例在文本完成后再次關(guān)閉。 這對(duì)于不使瀏覽器實(shí)例的負(fù)載混亂您的計(jì)算機(jī)很有用,尤其是如果你有這么多,導(dǎo)致計(jì)算機(jī)減速。
有很多關(guān)于寫(xiě)測(cè)試的最佳實(shí)踐的書(shū)。 您可以在測(cè)試設(shè)計(jì)注意事項(xiàng)中找到一些很好的背景信息。 一般來(lái)說(shuō),你應(yīng)該確保你的測(cè)試是:
google_test.js
test we looked at above is pretty good, as it just tests a single thing — whether the title of a search results page is set correctly. We could work on giving it a better name so it is easier to work out what it does if we add more google tests. Perhaps results_page_title_set_correctly.js
would be slightly better?此外,我們應(yīng)該提到測(cè)試結(jié)果/報(bào)告 - 我們已經(jīng)使用簡(jiǎn)單的 console.log()
語(yǔ)句報(bào)告了我們上面的例子中的結(jié)果,但這一切都是在JavaScript中完成的,所以你可以使用任何 測(cè)試運(yùn)行和度假系統(tǒng),無(wú)論是 Mocha / chaijs.com/\">海 /其他種類(lèi)的組合。
mocha_test.js
example inside your project directory. Put it inside a subfolder called test
. This example uses a long chain of promises to run all the steps required in our test — the promise-based methods WebDriver uses need to resolve for it to work properly.npm install --save-dev mocha
test
directory) using the following command: mocha --no-timeouts
--no-timeouts
flag to make sure your tests don't end up failing because of Mocha's arbitrary timeout (which is 3 seconds).注意: saucelabs-sample-test-frameworks 包含幾個(gè)有用的 示例說(shuō)明如何設(shè)置測(cè)試/斷言工具的不同組合。
事實(shí)證明,在刪除服務(wù)器上運(yùn)行測(cè)試不比在本地運(yùn)行困難。 您只需要?jiǎng)?chuàng)建驅(qū)動(dòng)程序?qū)嵗?,但需要指定一些其他功能,包括要測(cè)試的瀏覽器的功能,服務(wù)器的地址以及您需要訪問(wèn)的用戶憑據(jù)(如果有)。
在Sauce Labs上遠(yuǎn)程運(yùn)行Selenium測(cè)試很容易。 你需要的代碼應(yīng)該遵循下面看到的模式。
讓我們寫(xiě)一個(gè)例子:
sauce_google_test.js
.var webdriver = require('selenium-webdriver'), By = webdriver.By, until = webdriver.until, username = "YOUR-USER-NAME", accessKey = "YOUR-ACCESS-KEY"; var driver = new webdriver.Builder(). withCapabilities({ 'browserName': 'chrome', 'platform': 'Windows XP', 'version': '43.0', 'username': username, 'accessKey': accessKey }). usingServer("https://" + username + ":" + accessKey + "@ondemand.saucelabs.com:443/wd/hub"). build(); driver.get('http://www.google.com'); driver.findElement(By.name('q')).sendKeys('webdriver'); driver.findElement(By.name('btnG')).click(); driver.sleep(2000).then(function() { driver.getTitle().then(function(title) { if(title === 'webdriver - Google Search') { console.log('Test passed'); } else { console.log('Test failed'); } }); }); driver.quit();
YOUR-USER-NAME
and YOUR-ACCESS-KEY
placeholders in the code with your actual user name and access key values (and make sure you keep them secure).node sauce_google_testThe test will be sent to Sauce Labs, and the test result will be returned to your console. This shows the importance of including some kind of result reporting mechanism!
注意:Sauce實(shí)驗(yàn)室的平臺(tái)配置器 是一個(gè)有用的工具,用于根據(jù)要測(cè)試的瀏覽器/操作系統(tǒng)生成能力對(duì)象以供應(yīng)給您的驅(qū)動(dòng)程序?qū)嵗?/p>
注意:有關(guān)使用Sauce Labs和Selenium進(jìn)行測(cè)試的更多實(shí)用詳情,請(qǐng)查看 + with + Selenium + for + Automated + Website + Testing"> Selenium自動(dòng)化網(wǎng)站測(cè)試入門(mén)和 DOCS / Instant + Selenium + Node.js + Tests">即時(shí)Selenium Node.js測(cè)試。
您可以使用Sauce Labs API為測(cè)試注釋更多細(xì)節(jié),例如它是否通過(guò),測(cè)試的名稱(chēng)等。Sauce Labs默認(rèn)情況下不知道這些詳細(xì)信息!
為此,您需要:
npm install saucelabs --save-dev
sauce_google_test.js
file, just below the previous variable declarations: var SauceLabs = require('saucelabs');
var saucelabs = new SauceLabs({ username : "YOUR-USER-NAME", password : "YOUR-ACCESS-KEY" });Again, replace the
YOUR-USER-NAME
and YOUR-ACCESS-KEY
placeholders in the code with your actual user name and access key values (note that the saucelabs npm package rather confusingly uses password
, not accessKey
). Since you are using these twice now, you may want to create a couple of helper variables to store them in.driver
variable (just below the build()
line), add the following block — this gets the correct driver sessionID
that we need to write data to the job (you can see it action in the next code block): driver.getSession().then(function (sessionid){ driver.sessionID = sessionid.id_; });
driver.sleep(2000)
... block near the bottom of the code with the following: driver.sleep(2000).then(function() { driver.getTitle().then(function(title) { if(title === 'webdriver - Google Search') { console.log('Test passed'); var testPassed = true; } else { console.log('Test failed'); var testPassed = false; } saucelabs.updateJob(driver.sessionID, { name: 'Google search results page title test', passed: testPassed }); }); });
這里我們根據(jù)測(cè)試是通過(guò)還是失敗,將 testPassed
變量設(shè)置為 true
或 false
,然后我們使用 > saucelabs.updateJob()
方法來(lái)更新詳細(xì)信息。
如果您現(xiàn)在返回到 Sauce Labs自動(dòng)測(cè)試信息中心頁(yè)面,您應(yīng)該會(huì)立即看到您的新工作 具有附加的更新數(shù)據(jù):
margin:0px auto; width:1088px;">
如果您不想使用像Sauce Labs這樣的服務(wù),您可以隨時(shí)設(shè)置自己的遠(yuǎn)程測(cè)試服務(wù)器。 讓我們來(lái)看看如何做到這一點(diǎn)。
PATH
, do so now (see the Setting up Selenium in Node section).java -jar
selenium-server-standalone-3.0.0.jar
(update the .jar
filename) so it matches exactly what file you've got.http://localhost:4444/wd/hub
— try going there now to see what you get.現(xiàn)在我們讓服務(wù)器運(yùn)行,讓我們創(chuàng)建一個(gè)將在遠(yuǎn)程selenium服務(wù)器上運(yùn)行的演示測(cè)試。
google_test.js
file, and call it google_test_remote.js
; put it in your project directory.var driver =
) like so var driver = new webdriver.Builder() .forBrowser('firefox') .usingServer('http://localhost:4444/wd/hub') .build();
node google_test_remote.js
所以這是很酷。 我們已在本地測(cè)試過(guò),但您可以在任何服務(wù)器以及相關(guān)的瀏覽器驅(qū)動(dòng)程序上進(jìn)行設(shè)置,然后使用您選擇的網(wǎng)址將腳本連接到它。
另一點(diǎn)是,還可以將Selenium和Sauce Labs等相關(guān)工具與持續(xù)集成(CI)工具集成 - 這非常有用,因?yàn)樗馕吨梢酝ㄟ^(guò)CI工具運(yùn)行測(cè)試,并且只向代碼提交新的更改 如果測(cè)試通過(guò)的話。
在本文中詳細(xì)討論此區(qū)域不在此范圍內(nèi),但我們建議開(kāi)始使用Travis CI - 這可能是開(kāi)始使用的最簡(jiǎn)單的CI工具,并且與Web工具(如GitHub和Node 。
要開(kāi)始,請(qǐng)參閱示例:
這個(gè)模塊應(yīng)該已經(jīng)被證明是有趣的,應(yīng)該給你足夠的洞察寫(xiě)入和運(yùn)行自動(dòng)化測(cè)試,讓你去寫(xiě)自己的自動(dòng)化測(cè)試。
更多建議: