在開始自動化時,您可能會遇到各類可能包含在自動化代碼中的方法,技術,框架和工具。有時,與提供更好的靈活性或解決問題的更好方法相比,這種多功能性致使代碼更加複雜。在編寫自動化代碼時,重要的是咱們可以清楚地描述自動化測試的目標以及咱們如何實現它。話雖如此,編寫「乾淨的代碼」以提供更好的可維護性和可讀性很重要。編寫乾淨的代碼也不是一件容易的事,您須要牢記許多最佳實踐。如下主題突出顯示了編寫更好的自動化代碼應得到的8條銀線。java
當咱們從手動轉向自動化或實際上以任何編程語言編寫代碼時,這確實是要牢記的經驗法則之一。遵循正確的命名約定有助於更輕鬆地理解代碼和維護。此命名約定暗含變量,方法,類和包。例如,您的方法名稱應特定於其用途。「 Register_User()」方法描述了在該方法中顯示用戶註冊的方法。明肯定義的方法名稱增長了腳本的易於維護和可讀性。這一樣適用於變量命名。我注意到許多人提到變量爲a,b,c等,甚至將Web元素稱爲Weblelement1,Webelement2等。這樣一來,用戶看不到變量名與預期的同樣。web
如下是顯示命名錯誤的示例:面試
public void Register_User() throws InterruptedException { driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); driver.get("https://www.lambdatest.com/ "); driver.manage().window().maximize(); WebElement web1= driver.findElement(By.xpath("//a[text()='Free Sign Up']")); web1.click(); WebElement web2=driver.findElement(By.xpath("//input[@name='organization']")); web2.sendKeys("LambdaTest"); WebElement web3=driver.findElement(By.xpath("//input[@name='first_name']")); web3.sendKeys("Test"); WebElement web4=driver.findElement(By.xpath("//input[@name='last_name']")); web4.sendKeys("User"); WebElement web5=driver.findElement(By.xpath("//input[@name='email']")); web5.sendKeys("sadhvi.singh@navyuginfo.com"); WebElement web6=driver.findElement(By.xpath("//input[@name='password']")); web6.sendKeys("TestUser123"); WebElement web7=driver.findElement(By.xpath("//input[@name='phone']")); web7.sendKeys("9412262090"); WebElement web8=driver.findElement(By.xpath("//button[text()='SIGN UP']")); web8.click(); Thread.sleep(3500); }
上面的代碼顯示了「 method1」如何不向用戶提供任何線索,就像該方法的確切做用同樣。另外,全部的web元素都經過web1,web2等表示。用戶沒法識別哪一個Web元素捕獲了哪一個字段。chrome
對於上述相同的代碼,能夠以下標記正確的表示方式:數據庫
public void Register_User() throws InterruptedException { driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); driver.get("https://www.lambdatest.com/ "); driver.manage().window().maximize(); WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']")); link.click(); WebElement organization=driver.findElement(By.xpath("//input[@name='organization']")); organization.sendKeys("LambdaTest"); WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']")); first_name.sendKeys("Test"); WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']")); last_name.sendKeys("User"); WebElement email=driver.findElement(By.xpath("//input[@name='email']")); email.sendKeys("sadhvi.singh@navyuginfo.com"); WebElement password=driver.findElement(By.xpath("//input[@name='password']")); password.sendKeys("TestUser123"); WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']")); phone_number.sendKeys("9412262090"); WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']")); button.click(); Thread.sleep(3500); String url= driver.getCurrentUrl(); assertEquals("fail- unable to register", url, "https://accounts.lambdatest.com/user/email-verification"); }
在這裏,方法名稱'Register_User'經過名稱明肯定義了用戶,指示該方法包含與用戶註冊相關的代碼。一樣,全部Web元素或變量都具備與用於定義意圖的捕獲字段相關的名稱。編程
一般,一般鼓勵使用駝峯式大小寫來記錄方法或變量,由於它在可讀性和維護腳本方面更加清晰。瀏覽器
確保將您的方法分解到用戶場景的最小塊上很是重要。它們應涵蓋簡單和單一的流程。不要讓您的方法與單一方法涵蓋的多個功能過於複雜。例如,登陸功能須要在應用程序上註冊用戶。將您的註冊功能保留在另外一個方法中,若是須要,請在登陸方法中調用該方法。下降方法的複雜度可簡化代碼的可維護性。框架
另外,在須要的地方重複使用您的方法,請勿將相同的代碼複製粘貼到不一樣的方法中。這致使代碼中沒必要要的重複和冗餘。增長代碼行並不意味着您已經編寫了不錯的代碼。重構和優化代碼是編寫穩定,健壯和更好的自動化代碼的關鍵。編程語言
回收也是編寫更好的自動化代碼的另外一個有用技巧。我有經驗豐富的人員能夠自動化遺留系統,不傾向於在自動化框架中更改現有方法,而不會在現有功能發生變化時重寫另外一種方法。這只是使框架變得脆弱。每當流程改變時,老是要更新現有方法,儘管它有其自身的挑戰,即新用戶可能不知道該方法可能具備的依賴性,可是我認爲咱們應該始終以長遠的眼光來看待問題,而不是實現那些較短的目標。 。工具
下面是一個示例,說明如何將登陸代碼簡化爲一小部分功能,並使用了另外一種註冊方法來簡化整個過程。
@Test public void Register_User() throws InterruptedException { driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); driver.get("https://www.lambdatest.com/ "); driver.manage().window().maximize(); WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']")); link.click(); WebElement organization=driver.findElement(By.xpath("//input[@name='organization']")); organization.sendKeys("LambdaTest"); WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']")); first_name.sendKeys("Test"); WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']")); last_name.sendKeys("User"); WebElement email=driver.findElement(By.xpath("//input[@name='email']")); email.sendKeys("sadhvi.singh@navyuginfo.com"); WebElement password=driver.findElement(By.xpath("//input[@name='password']")); password.sendKeys("TestUser123"); WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']")); phone_number.sendKeys("9412262090"); WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']")); button.click(); } @Test public void Login_User() { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123"); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); } @AfterClass public static void BrowserClose() { driver.quit(); } }
好的,這確實是確保更好的自動化代碼的主要可操做看法之一。它不只易於理解,並且在維護上無需花費太多精力。從長遠來看,藉助框架來構建測試能夠增長工做價值,並減小維護工做。您能夠經過使用由JUnit和TestNG之類的框架提供的註釋來控制應用程序的流程。例如,使用@BeforeClass之類的註釋能夠幫助您指導耗時的活動,例如鏈接到數據庫,設置瀏覽器等與此方法相關的代碼以及與此相關聯的@BeforeClass註釋。這能夠幫助自動化測試儀當即知道該方法的確切功能以及什麼時候調用該方法。試想一下,您的設置過程很清楚,而且已從代碼的其餘部分中整理出來。
下面的示例突出顯示了經過TestNG框架展現了一種更好的結構化方法:
import static org.junit.Assert.*; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class Lamdatest { static WebDriver driver; @BeforeClass public static void BrowserOpen() { System.setProperty("webdriver.chrome.driver", "chromepath"); driver= new ChromeDriver() ; driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); } @Test(priority=1) public void Register_User() throws InterruptedException { driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); driver.get("https://www.lambdatest.com/ "); driver.manage().window().maximize(); WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']")); link.click(); WebElement organization=driver.findElement(By.xpath("//input[@name='organization']")); organization.sendKeys("LambdaTest"); WebElement first_name=driver.findElement(By.xpath("//input[@name='first_name']")); first_name.sendKeys("Test"); WebElement last_name=driver.findElement(By.xpath("//input[@name='last_name']")); last_name.sendKeys("User"); WebElement email=driver.findElement(By.xpath("//input[@name='email']")); email.sendKeys("sadhvi.singh@navyuginfo.com"); WebElement password=driver.findElement(By.xpath("//input[@name='password']")); password.sendKeys("TestUser123"); WebElement phone_number=driver.findElement(By.xpath("//input[@name='phone']")); phone_number.sendKeys("9412262090"); WebElement button=driver.findElement(By.xpath("//button[text()='SIGN UP']")); button.click(); String url= driver.getCurrentUrl(); assertEquals("fail- unable to register", url, "https://accounts.lambdatest.com/user/email-verification"); } @Test(dependsOnMethods="Register_User") public void Login_User() { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123"); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); } @AfterClass public static void BrowserClose() { driver.quit(); } }
肯定哪些註釋應該與哪一種測試方法相關聯是很重要的。經過明確的依賴關係和優先級,能夠根據應用程序的流程來構造測試和代碼。
做爲質量檢查人員,您要作的就是驗證您的預期和實際知足狀況,這與您的自動化代碼相同。若是您的腳本不符合驗證要求,那麼建立一個腳本將毫無心義,也沒有任何意義。理想狀況下,每一個用戶操做都應該像測試用例步驟同樣進行驗證,不管它是在驗證元素的可見性,仍是要記住版式提示,文本表示形式,頁面重定向或任何形式的視覺驗證,甚至是關於評估數據庫的結果。
即便您的驗證沒法肯定,也會顯示失敗消息,以便您能夠找出問題所在。咱們在驗證代碼方面犯的最大錯誤是從確保驗證經過的角度編寫。咱們從未考慮過若是代碼失敗或未達到預期效果會發生什麼,那麼繼續下去將須要什麼。
若是您但願在驗證失敗後當即中斷測試並跳至另外一測試,則可使用硬斷言,而若是您但願在同一頁面上驗證多個檢查,則能夠選擇軟斷言。決定徹底使用哪一個斷言取決於用例。
如下是在登陸頁面上執行的斷言示例。在此方法中,將建立一種方法,其中使用有效憑據登陸用戶,而後使用另外一種方法確保用戶不會使用無效憑據登陸並顯示錯誤消息。
//validate user able to login with valid credentials @Test public void Login_User() throws IOException { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123"); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); WebDriverWait wait= new WebDriverWait(driver, 15); wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")))); String Current_url= driver.getCurrentUrl(); Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url); System.out.println("user logged in sucesfully"); driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click(); driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click(); } //validate user is unable to login with invalid credentials @Test public void Login_invalid_User() throws IOException { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User21@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TestUser123"); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); WebDriverWait wait= new WebDriverWait(driver, 15); String str= driver.findElement(By.xpath("//p[@class='error-mass']")).getText(); String Current_url= driver.getCurrentUrl(); Assert.assertEquals("https://accounts.lambdatest.com/login", Current_url); System.out.println(str); }
覆蓋多個驗證檢查的方法可能有所不一樣,或者您能夠像我上面所作的那樣爲每一個驗證選擇不一樣的方法,或者能夠選擇在try-catch塊下的單個方法中進行全部驗證。
咱們傾向於相信的最大神話,尤爲是當咱們剛接觸自動化領域時,是經過爲腳本提供足夠的等待量,必要或沒必要要的等待會致使腳本順利執行。相反,它使腳本不穩定,並增長了整體執行時間。這種靜態睡眠的主要問題是,咱們不瞭解運行測試的機器的負載,所以可能致使超時。所以,應避免使用thread.sleep來維護更好的自動化代碼。對腳本使用等待的一種更好的方法是經過條件綁定,其中腳本能夠像人類同樣等待直到知足特定條件。例如,等待直到某個元素可見或不可見。
做爲開發更好的自動化代碼的一種選擇,顯式和流暢的等待更加適應。
在對多種形式的數據進行測試時,測試變得更加有效,當編寫更好的自動化代碼以測試Web應用程序或任何其餘軟件時,測試也是如此。在自動化中,關鍵是經過多種形式的數據測試測試代碼,而不是爲每一個數據編寫不一樣的測試腳本。這能夠經過數據驅動的測試框架輕鬆實現。它有助於將測試數據輸入存儲到外部數據庫中,例如CSV文件,excel文件,文本文件,XML文件甚至是ODBC存儲庫。此數據被調用到腳本中,並一次又一次地運行在相同的測試代碼中。與手動工做相比,這有助於減小冗餘並加快執行速度。發現新的bug。這種方法的另外一個好處是,它減小了您可能必須添加的測試腳本的數量,從而加快了測試周期。
與之保持同步,它還有助於簡化腳本的可維護性。若是應用程序發生任何更改,代碼中的全部硬編碼值均可能會中斷。實現此目的的一種更簡單的方法是將全部硬編碼組件設置爲變量驅動。例如,經過將它們各自的值存儲在excel工做表中並在腳本中調用它們,可使全部定位器都不受代碼限制。萬一您的任何定位器損壞了,您只須要在excel中更改定位器的值便可,而根本不須要觸摸腳本。
數據驅動測試的一個基本示例是:
public void Login_User() throws IOException { File f1= new File("C://Users//navyug//Desktop//Test.xlsx"); FileInputStream scr= new FileInputStream(f1); XSSFWorkbook book= new XSSFWorkbook(scr); XSSFSheet sheet=book.getSheetAt(0); for(int i=0; i<=sheet.getLastRowNum(); i++ ) { //XSSFCell cell= sheet.getRow(i).getCell(1); Row row = sheet.getRow(i); Cell cell = row.getCell(0); driver.findElement(By.xpath("//input[@name='email']")).sendKeys(cell.toString()); cell= row.getCell(1); driver.findElement(By.xpath("//input[@name='password']")).sendKeys(cell.toString()); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); WebDriverWait wait= new WebDriverWait(driver, 15); wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")))); String Current_url= driver.getCurrentUrl(); Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url); System.out.println("user logged in sucesfully"); takescreenshot(); driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click(); driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click(); } }
上面的代碼顯示了從Excel獲取的用於不一樣登陸憑據的數據。對於Xpath也能夠擴展一樣的功能,其中XPath值也能夠從excel中提取。在這裏,經過數據驅動方法解決的關鍵點是從咱們的代碼中刪除硬編碼的值,使其成爲面向變量,並使其在多組輸入中運行同一段代碼。
若是自動化代碼沒有向您報告結果,則該代碼將沒法正常工做。爲了優化您做爲自動化工程師的工做,重要的是要知道哪些測試代碼經過了,哪些失敗並附帶了屏幕截圖。您能夠向利益相關者展現的最佳投資回報是經過報告。共享這些詳細的報告可提供可見性,並減小您驗證測試執行腳本的時間。您能夠經過TestNG HTML報告生成,JUnit報告生成等各類技術來實現報告,也可使用擴展庫來實現報告。
下面的代碼顯示了一個示例,其中登陸功能的完成後已截取了屏幕截圖做爲驗證經過的證實,而下面是執行後生成的TestNG報告的示例:
//validate user able to login with valid credentials @Test public void Login_User() throws IOException { driver.get("https://accounts.lambdatest.com/login"); driver.findElement(By.xpath("//input[@name='email']")).sendKeys("User2@gmail.com"); driver.findElement(By.xpath("//input[@name='password']")).sendKeys("TetsUser123"); driver.findElement(By.xpath("//button[@class='sign-up-btn']")).click(); WebDriverWait wait= new WebDriverWait(driver, 15); wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")))); String Current_url= driver.getCurrentUrl(); Assert.assertEquals("https://accounts.lambdatest.com/user/email-verification", Current_url); System.out.println("user logged in sucesfully"); takescreenshot(); driver.findElement(By.xpath("//a[@class='user-profile dropdown-toggle']")).click(); driver.findElement(By.xpath("//a[contains(text(),'Logout')]")).click(); } public void takescreenshot() throws IOException { TakesScreenshot scr= ((TakesScreenshot)driver); File file1= scr.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\Desktop\\Login_user.PNG")); }
若是對軟件測試、接口測試、自動化測試、面試經驗交流。感興趣能夠加軟件測試交流:1085991341,還會有同行一塊兒技術交流。
現在,全部Web應用程序都支持多種瀏覽器和版本。重要的是,您的代碼應針對多個瀏覽器,而不是針對特定的瀏覽器。在特定的瀏覽器上運行代碼會失去應用程序的跨瀏覽器兼容性。執行跨瀏覽器測試,以確保您的應用程序在全部主要瀏覽器上都能提供無縫的用戶體驗,咱們能夠擴展此測試的自動化範圍。諸如TestNG之類的框架有助於輕鬆地在各類瀏覽器中執行測試。
下面的代碼顯示瞭如何經過TestNG在多個瀏覽器上運行自動化代碼
public class crowssbrowser { static WebDriver driver; @Parameters("browser") @BeforeClass public static void Browser_Select(String browser) { if(browser.equalsIgnoreCase("firefox")) { System.setProperty("webdriver.firefox.marionette", "geckodriverpath"); driver = new FirefoxDriver(); // If browser is IE, then do this }else if (browser.equalsIgnoreCase("chrome")) { // Here I am setting up the path for my IEDriver System.setProperty("webdriver.chrome.driver", "chromedriverpath"); driver= new ChromeDriver() ; } driver.get("https://accounts.lambdatest.com/login"); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); }
XML代碼:
<?xml ve rsion="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite" parallel="none"> <test name="FirefoxTest"> <parameter name="browser" value="firefox" /> <classes> <class name="crowssbrowser" /> </classes> </test> <test name="chrometest"> <parameter name="browser" value="chrome" /> <classes> <class name="crowssbrowser" /> </classes> </test> </suite>
上面的代碼顯示了一種以瀏覽器爲參數的方法,其中設置了不一樣的瀏覽器驅動程序。使用TestNG XML文件,咱們已將參數傳遞爲不一樣的瀏覽器,在這些瀏覽器上將運行用於Firefox和chrome上的登陸功能的代碼。以上內容就是本篇的所有內容以上內容但願對你有幫助,有被幫助到的朋友歡迎點贊,評論。