在开始自动化时,您可能会遇到各类可能包含在自动化代码中的方法,技术,框架和工具。有时,与提供更好的灵活性或解决问题的更好方法相比,这种多功能性致使代码更加复杂。在编写自动化代码时,重要的是咱们可以清楚地描述自动化测试的目标以及咱们如何实现它。话虽如此,编写“干净的代码”以提供更好的可维护性和可读性很重要。编写干净的代码也不是一件容易的事,您须要牢记许多最佳实践。如下主题突出显示了编写更好的自动化代码应得到的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上的登陆功能的代码。以上内容就是本篇的所有内容以上内容但愿对你有帮助,有被帮助到的朋友欢迎点赞,评论。