Padrões e metodologias de automação de IU: exemplos da vida real

O desenvolvimento e o teste de software à primeira vista parecem muito diferentes um do outro, mas existem aspectos que são importantes em ambas as disciplinas.





Neste artigo, veremos alguns dos padrões e metodologias de design de software comuns que podem ser úteis ao trabalhar com automação de IU, especialmente ao construir uma estrutura de teste de IU. Os exemplos e casos de uso fornecidos aqui são para nossa própria estrutura.





Observe que esses não são exemplos de código completos, mas exemplos de código simplificados que ilustram conceitos. Como esta é minha principal linguagem de programação, o código a seguir foi escrito em Java. Tentei torná-lo o mais simples e direto possível.





Padrões úteis para automatizar testes de IU

Um padrão de design é um pedaço de código incompleto que pode ser usado em projetos. Pelo contrário, parece mais um plano de solução.





, . , , , .





(Decorator)

-. , - , A/B- .





, ! «», . : . , - .





Login. «».





- . , «». . , , , .









LoginComponent - Login. , login.





package decorator;

public interface LoginComponent {
   void login(String user, String password);
}
      
      



BasicLoginComponent login. «Basic login» .





package decorator;

public class BasicLoginComponent implements LoginComponent {
   @Override
   public void login(String user, String password) {
       System.out.println("Basic login: " + user + ", " + password);
   }
}
      
      



. LoginDecorator LoginComponent . LoginComponent.





package decorator;

public abstract class LoginDecorator implements LoginComponent {
   private final LoginComponent loginComponent;
   public LoginDecorator(LoginComponent loginComponent) {
       this.loginComponent = loginComponent;
   }
   @Override
   public void login(String user, String password) {
       loginComponent.login(user, password);
   }
}
      
      



MobileLoginDecorator login , . , «Mobile login», .





package decorator;

public class MobileLoginDecorator extends LoginDecorator {
   public MobileLoginDecorator(LoginComponent loginComponent) {
       super(loginComponent);
   }
   @Override
   public void login(String user, String password) {
       System.out.println("Mobile login: " + user + ", " + password);
   }
}
      
      



CancelButtonDecorator cancel Login.





package decorator;

public class CancelButtonDecorator extends LoginDecorator {
   public CancelButtonDecorator(LoginComponent loginComponent) {
       super(loginComponent);
   }
   public void cancel() {
       System.out.println("Click the cancel button");
   }
}
      
      



, !





package decorator;

public class Main {
   public static void main(String[] args) {
   System.out.println("DECORATOR PATTERN");
   System.out.println("=================");

   // This is the basic login component
   LoginComponent loginComponent = new BasicLoginComponent();
   loginComponent.login("User", "PW");

   // Let's turn it into a mobile login component.
   loginComponent = new MobileLoginDecorator(loginComponent);
   loginComponent.login("User", "PW");

   // Finally, we can add a cancel functionality.
   loginComponent = new CancelButtonDecorator(loginComponent);
   ((CancelButtonDecorator) loginComponent).cancel();

   }
}
      
      



:





DECORATOR PATTERN
=================
Basic login: User, PW
Mobile login: User, PW
Click the cancel button
      
      



, , . , . .





Page Object Page Component

, UI, Page Object. , . , .





, , . : Page Component. , , .





Page Object

-, . Page Object, , WebshopPage.





package pageobjects;

public class WebshopPage {
   public void search(final String queryString) {
       System.out.println("Enter " + queryString);
       System.out.println("Click search button");
   }
   public void checkResultHeadline() {
       System.out.println("Check if the headline is correct.");
   }
   public void checkResults() {
       System.out.println("Check if there are search results.");
   }
}

      
      



, , . Main .





package pageobjects;

public class Main {
   public static void main(String[] args) {
   System.out.println("PAGE OBJECTS");
   System.out.println("============");

   WebshopPage webshopPage = new WebshopPage();
   webshopPage.search("T-Shirt");
   webshopPage.checkResultHeadline();
   webshopPage.checkResults();

   }
}

      
      



, :





PAGE OBJECTS
============
Enter T-Shirt
Click search button
Check if the headline is correct.
Check if there are search results.

      
      



. , .





Page Component

Page Component. : .





SearchBar .





package pagecomponents;
public class SearchBar {
   public void search(final String queryString) {
       System.out.println("Enter " + queryString);
       System.out.println("Click search button");
   }
}

      
      



ResultList:





package pagecomponents;
public class ResultList {
   public void checkResultHeadline() {
       System.out.println("Check if the headline is correct.");
   }
   public void checkResults() {
       System.out.println("Check if there are search results.");
   }
}

      
      



WebshopPage, .





package pagecomponents;
public class WebshopPage {
   public SearchBar searchBar() {
       return new SearchBar();
   }
   public ResultList resultList() {
       return new ResultList();
   }
}

      
      



. , .





package pagecomponents;
public class Main {
   public static void main(String[] args) {
   System.out.println("PAGE COMPONENTS");
   System.out.println("===============");

   WebshopPage webshopPage = new WebshopPage();
   webshopPage.searchBar().search("T-Shirt");
   webshopPage.resultList().checkResultHeadline();
   webshopPage.resultList().checkResults();

   }
}

      
      



:





PAGE COMPONENTS
===============
Enter T-Shirt
Click search button
Check if the headline is correct.
Check if there are search results.

      
      



, , . , .





(Factory)

, , , . , .





. . , .





.





-, , , . , . , .





package factory;
public class Component {
   public void initialize() {
       System.out.println("Initializing " + getClass().getName());
   }
}

      
      



Component:





public class ResultList extends Component {
    ...
}
public class SearchBar extends Component {
    ...
}

      
      



- , . , , initialize .





package factory;
public class ComponentFactory {
   public static Component getComponent(final String componentName) throws Exception {
   System.out.println("Creating " + componentName + "...");

   // Create a component instance for the passed in component name.
   Component component;
   switch (componentName){
       case "SearchBar":
           component = new SearchBar();
           break;
       case "ResultList":
           component = new ResultList();
           break;
       default:
           throw new Exception(componentName + " unknown.");
   }
   System.out.println("Component created: " + component);
   component.initialize();
   return component;

   }
}

      
      



Main , WebshopPage - .





package factory;
public class Main {
   public static void main(String[] args) throws Exception {
   System.out.println("FACTORY PATTERN");
   System.out.println("===============");

   WebshopPage webshopPage = new WebshopPage();
   webshopPage.searchBar().search("Berlin");

   }
}

      
      



:





FACTORY PATTERN
===============
Creating SearchBar...
Component created: factory.SearchBar@3d075dc0
Initializing factory.SearchBar
Enter Berlin
Click search button

      
      



, .





, . , , , .





(Dependency Injection)

« ». , , , , . .





, , , - , Spring Guice, . , .





UI -. , , . , , -. Login, . «» - .





LoginData, . .





package dependencyinjection;
public interface LoginData {
   String getUserName();
   String getPassword();
}

      
      



: «», «» .





package dependencyinjection;
public class LoginDataReal implements LoginData {
   @Override
   public String getUserName() {
       return "Real user";
   }
   @Override
   public String getPassword() {
       return "Real password";
   }
}
package dependencyinjection;
public class LoginDataFake implements LoginData {
   @Override
   public String getUserName() {
       return "Fake user";
   }
   @Override
   public String getPassword() {
       return "Fake password";
   }
}

      
      



LoginPage LoginData login. , LoginPage, .





package dependencyinjection;
public class LoginPage {
   private final LoginData loginData;
   public LoginPage(final LoginData loginData) {
       this.loginData = loginData;
   }
   public void login(){
       System.out.println("Logging in with " + loginData.getClass());
       System.out.println("- user: " + loginData.getUserName());
       System.out.println("- password: " + loginData.getPassword());
   }
}

      
      



- , .





package dependencyinjection;
public class Main {
   public static void main(String[] args) {
   System.out.println("DEPENDENCY INJECTION");
   System.out.println("====================");

   LoginPage loginPageReal = new LoginPage(new LoginDataReal());
   loginPageReal.login();

   LoginPage loginPageFake = new LoginPage(new LoginDataFake());
   loginPageFake.login();

   }
}

      
      



, . :





DEPENDENCY INJECTION
====================
Logging in with class dependencyinjection.LoginDataReal

user: Real user
password: Real password
Logging in with class dependencyinjection.LoginDataFake
user: Fake user
password: Fake password

      
      



, , , . , .





, , - . , , .





:

. , - : !





, UI, , . . , .





(Keep It Simple)

. , . , . , - .





(You Aren’t Gonna Need It)

, YAGNI, . « » , , . , , , , , , - .





Se você seguir esse princípio, provavelmente desenvolverá sua estrutura de teste mais rápido, porque não precisa pensar em todas as possibilidades antes de implementá-la. Além disso, você pode fornecer exatamente as ferramentas de que precisa sob demanda, em vez de fornecer uma solução pronta para o uso que pode ser opressiva e difícil de usar.





Traduzido pela equipe QApedia. Você encontrará ainda mais artigos traduzidos em nosso canal de telegramas .








All Articles