2023, 8 must-have Selenium skills for writing automation use cases (recommended collection)

When starting to automate, you may come across various methods, techniques, frameworks and tools that you may include in your automation code. Sometimes this versatility leads to more complex code than it offers better flexibility or a better way to solve a problem. When writing automation code, it is important that we are able to clearly describe the goal of the automation test and how we will achieve it.

Having said that, it is important to write "clean code" for better maintainability and readability. Writing clean code is also not an easy task and you need to keep many best practices in mind. The following topics highlight the 8 silver threads you should earn for writing better automation code.

1. Naming convention

This is really one of the rules of thumb to keep in mind when we move from manual to automated or actually coding in any programming language. Following proper naming conventions makes code easier to understand and maintain. This naming convention implies variables, methods, classes and packages. For example, your method names should be specific to their purpose. The "Register_User()" method describes how to display user registration in this method. Well-defined method names increase the ease of maintenance and readability of scripts. The same applies to variable naming. I've noticed that many people mention variables as a, b, c, etc., and even refer to web elements as Weblelement1, Webelement2, etc. This way, the user doesn't see the variable names as expected.

Here's an example showing a naming error:

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("[email protected]");
        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);

    }   

The code above shows how "method1" doesn't give the user any clues as to what exactly the method does. Additionally, all web elements are represented by web1, web2, etc. Users cannot identify which web element captures which field.

For the same code above, the correct representation can be marked as follows:

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("[email protected]");
        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");

    }

Here, the method name 'Register_User' clearly defines the user by name, indicating that the method contains code related to user registration. Likewise, all web elements or variables have names associated with capture fields used to define intents.

In general, camel case is usually encouraged to document methods or variables, as it is clearer in terms of readability and maintaining scripts.

2. Reduce, reuse and recycle

It's important to make sure you break down your methods into the smallest chunks of your user scenario. They should cover simple and single processes. Don't overcomplicate your approach with multiple functions covered by a single method. For example, the login functionality requires the user to be registered on the application. Keep your registration functionality in another method and call that method in your login method if needed. Reducing method complexity simplifies code maintainability.

Also, reuse your methods where needed, don't copy paste the same code into different methods. This leads to unnecessary duplication and redundancy in the code. Adding lines of code doesn't mean you've written decent code. Refactoring and optimizing code is the key to writing stable, robust and better automation code.

Recycling is also another useful trick for writing better automation code. I've had people with experience automating legacy systems not inclined to change an existing method in an automation framework without rewriting another method when existing functionality changes. This just makes the framework fragile. Always update existing methods whenever the process changes, although it has its own challenges that new users may not be aware of the dependencies the method may have, but I think we should always take the long view, Instead of achieving those shorter goals. .

Here's an example of how to reduce the login code to a small piece of functionality, and use an alternative signup method to simplify the overall process.

@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("[email protected]");
        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("[email protected]");
          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();
    }

    }

3. Organize your tests properly

Ok, this is indeed one of the main actionable insights to ensure better automation code. Not only is it easy to understand, it also requires little effort to maintain. In the long run, building tests with the help of a framework adds value and reduces maintenance effort. You can control the flow of your application by using annotations provided by frameworks like JUnit and TestNG. For example, using annotations like @BeforeClass can help you guide time-consuming activities like connecting to database, setting up browser etc. code related to this method and the @BeforeClass annotation associated with this. This helps automated testers know immediately what exactly the method does and when it is called. Just imagine, your setup process is clear and sorted out from other parts of your code.

The example below highlights a better structured approach via the TestNG framework:

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("[email protected]");
        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("[email protected]");
          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();
    }

    }

It is important to determine which annotations should be associated with which test methods. With clear dependencies and priorities, tests and code can be structured according to the flow of the application.

4. Thoroughly validate your tests

As a QA, all you have to do is verify that your expectations and actual fulfillment are the same as your automation code. If your script doesn't meet the validation requirements, there's no point and no point in creating one. Ideally, every user action should be validated like a test case step, whether it's validating element visibility, remembering typographic hints, text representations, page redirects, or any form of visual validation, even is about evaluating the results of the database.

Even if your validation is inconclusive, a failure message is displayed so you can identify the problem. The biggest mistake we make with validation code is writing it in terms of making sure validation passes. We never considered what would happen if the code failed or didn't work as expected, and what it would take to continue.

If you want to break a test and jump to another test as soon as a validation fails, you can use hard asserts, and if you want to verify multiple checks on the same page, you can choose soft asserts. Deciding exactly which assert to use depends on the use case.

Below is an example of an assertion performed on a login page. In this method, you will create a method where the user is logged in with valid credentials, and then use another method to ensure that the user does not log in with invalid credentials and display an error message.

//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("[email protected]");
            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("[email protected]");
                      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);
                }

The method of overriding multiple validation checks can vary, or you can choose a different method for each validation like I did above, or you can choose to do all validation in a single method under a try-catch block.

5.sleep does not improve stability

The biggest myth we tend to believe, especially when we're new to the world of automation, is that by giving scripts enough waits, necessary or unnecessary waits will lead to smooth script execution. Instead, it destabilizes the script and increases the overall execution time. The main problem with this kind of static sleep is that we don't know the load of the machine running the test, so it can cause timeouts. Therefore thread.sleep should be avoided to maintain better automated code. A better way to use wait with scripts is through conditional binding, where a script can wait like a human until a certain condition is met. For example, waiting until an element is visible or invisible.

Explicit and fluent waits are more adaptable as an option for developing better automation code.

6. Be Tested, Data Driven

Testing becomes more effective when testing against multiple forms of data, and so does testing when writing better automated code for testing web applications or any other software. In automation, the key is to test the test code through multiple forms of data, rather than writing different test scripts for each data. This can be easily achieved with a data-driven testing framework. It helps to store test data input into external database like CSV file, excel file, text file, XML file or even ODBC repository. This data is called into the script and run through the same test code over and over again. This helps reduce redundancy and speed up execution compared to manual work. Discover new bugs. Another benefit of this approach is that it reduces the number of test scripts you may have to add, thus speeding up the testing cycle.

Keeping in sync with it, it also helps ease the maintainability of your scripts. Any hardcoded values ​​in the code may break if any changes occur to the application. An easier way to achieve this is to make all hardcoded components variable driven. For example, all locators can be made code-free by storing their respective values ​​in an excel sheet and calling them in a script. In case any of your locators are broken, you just need to change the value of the locators in excel without touching the script at all.

A basic example of data-driven testing is:

        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();
            }
        }

The code above shows the data fetched from Excel for different login credentials. The same functionality can also be extended for XPath, where XPath values ​​can also be extracted from excel. Here, the key points solved by a data-driven approach is to remove hard-coded values ​​from our code, make it variable-oriented, and make it run the same piece of code on multiple sets of inputs.

7. Don't miss a report!

If the automated code isn't reporting results to you, the code won't work. In order to optimize your work as an automation engineer, it is important to know which test codes pass and which fail with screenshots attached. The best ROI you can demonstrate to your stakeholders is through reporting. Sharing these detailed reports provides visibility and reduces the time you spend validating test execution scripts. You can implement reports through various technologies such as TestNG HTML report generation, JUnit report generation, etc., or use extension libraries to implement reports.

The code below shows an example where a screenshot has been taken after completion of the login function as proof of validation, and below is an example of a TestNG report generated after execution:

//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("[email protected]");
            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")); 
        }

8. Don’t forget to cross-browser test!

All web applications these days support multiple browsers and versions. It is important that your tags target multiple browsers, not a specific browser. Running the code on a specific browser loses the cross-browser compatibility of the application. Perform cross-browser testing to ensure your application provides a seamless user experience across all major browsers, and we can extend the scope of automation for this testing. Frameworks like TestNG help to easily perform tests in various browsers.

The code below shows how to run automation code on multiple browsers via 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 code: 

<?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>

The code above shows a method that takes a browser as an argument, where different browser drivers are set. Using the TestNG XML file, we have passed parameters to the different browsers where the code for the login functionality on Firefox and chrome will run. The above content is the entire content of this article. I hope the above content is helpful to you. Friends who have been helped are welcome to like and comment.

END meager strength

Finally, I would like to thank everyone who has read my article carefully. Looking at the fans’ growth and attention all the way, there is always a need for reciprocity. Although it is not a very valuable thing, you can take it away if you need it:

These materials should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse has also accompanied tens of thousands of test engineers through the most difficult journey, and I hope it can help you too!

加入我的软件测试交流群:110685036免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)

Software testing interview applet

The software test question bank maxed out by millions of people! ! ! Who is who knows! ! ! The most comprehensive quiz mini program on the whole network, you can use your mobile phone to do the quizzes, on the subway or on the bus, roll it up!

The following interview question sections are covered:

1. Basic theory of software testing, 2. web, app, interface function testing, 3. network, 4. database, 5. linux

6. web, app, interface automation, 7. performance testing, 8. programming basics, 9. hr interview questions, 10. open test questions, 11. security testing, 12. computer basics

method of obtaining:

 

Guess you like

Origin blog.csdn.net/jiangjunsss/article/details/130683375