2 Padrões de design Selenium importantes e práticas recomendadas

Neste tutorial, aprenderemos sobre os padrões de design do Selenium e as práticas recomendadas ao trabalhar com o desenvolvimento da estrutura Selenium Automation (estrutura híbrida em selênio), existem duas variações de design de estrutura ou modelo de estrutura que devemos considerar: 

Precisamos saber e entender por que o padrão de design de linguagem é necessário quando estamos desenvolvendo nosso quadro em um dos Selenium Modelo de quadro. Sugerimos percorrer os segmentos anteriores do Série de tutoriais de desenvolvimento do Selenium Framework para obter todo o entendimento.

Vamos entender isso em detalhes: 

Padrões de design de selênio e práticas recomendadas -estrutura híbrida em selênio

Ao projetar qualquer Framework, precisamos considerar alguma arquitetura de design, ou seja, padrões de design de selênio e melhores práticas, e de acordo com a necessidade do tipo de modelo de framework, precisamos selecionar uma linguagem Padrão de design para resolver o estado do problema do design da estrutura como um todo.

Portanto, apenas para concluir, podemos escolher um modelo de framework Selenium (Híbrido, Modelo de objeto de página, Data Driven, etc.), mas para implementar o modelo, precisamos seguir e implementar algum padrão de design de linguagem (por exemplo, padrões de design java/C# ) 

Por que precisamos do padrão de design de selênio e das melhores práticas ao construir a estrutura do Selenium: 

Quais padrões de design devem ser usados ​​no Selenium Framework: 

Existem alguns padrões de design que você pode usar para implementar diferentes áreas da estrutura, como um exemplo: 

Faremos o template de codificação ao vivo de todo o Framework nos próximos posts aqui.

Singleton Design Pattern para estrutura híbrida no Selenium: 

Singleton Design Pattern é um padrão no qual você pode criar apenas um objeto de uma classe e usar o mesmo objeto para acessar os métodos da classe; poderíamos usar o padrão de design no configurador onde apenas precisamos ler os dados de configuração e podemos carregar em algum armazenamento de dados (qualquer tipo de estrutura de dados que você pode usar como e quando necessário durante a execução de quaisquer classes e métodos) 

Portanto, poderíamos obter o mesmo da maneira abaixo enquanto projetávamos o mesmo com o padrão Singleton Design. 

NOTA: Iremos projetar e desenvolver a estrutura do zero na próxima seção da série de tutoriais, mas este tutorial específico fornecerá uma visão sobre a necessidade do padrão de design.

pacote com.cyborg.core.generic.dataUtils; importar java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; importar java.util.LinkedHashMap; importar java.util.Properties; importar java.util.Set; import org.apache.log4j.PropertyConfigurator; // Esta é a classe SingleTon public class PropertiesDataUtils { private Properties properties = null; LinkedHashMap estático público configDataStore = novo LinkedHashMap (); InputStream é = null; // Esta é a referência estática e privada da classe que você pode usar em qualquer lugar em seu framework private static PropertiesDataUtils propertiesDataUtils = null; boolean centralizeLog = false; // Este é o construtor Private para criar o objeto, mas você não pode acessá-lo de fora da classe para manter o design do padrão SingleTon, ou seja, apenas a criação de um objeto.
 private PropertiesDataUtils(String filePath) { generateDataStore(filePath); centralizeLog = Boolean.parseBoolean(PropertiesDataUtils.configDataStore.get("centralizedLog")); if(centralizeLog) PropertyConfigurator.configure(System.getProperty("user.dir")+"//src//test//resources//config//log4j_central.properties"); else PropertyConfigurator.configure(System.getProperty("user.dir")+"//src//test//resources//config//log4j_local.properties"); } private PropertiesDataUtils() { } // Este método basicamente cria a instância da classe SingleTon public static PropertiesDataUtils getInstance(String filePath) { if (propertiesDataUtils == null) propertiesDataUtils = new PropertiesDataUtils(filePath); retornar propriedadesDataUtils; } // este método basicamente cria o armazenamento de dados onde você deseja armazenar todos os dados de configuração conforme discutido anteriormente private void generateDataStore(String filePath) { try { this.properties = new Properties(); is=new FileInputStream(filePath); propriedades.load(is); overrideFromEnvironment(); Definir chaves = loadAllKeys(); for (Objeto k : chaves) { String chave = (String) k; configDataStore.put(chave, getPropertyValue(chave)); } } catch (FileNotFoundException fileNotFoundException) { String exceptionData = String.valueOf(fileNotFoundException.getCause().getMessage()); } catch (IOException ioException) { String exceptionData = String.valueOf(ioException.getCause().getMessage()); } finalmente { if (null != is) { try { is.close(); } catch (Exception e) { String exceptionData = String.valueOf(e.getCause().getMessage()); } } } } // Este método é usado para carregar todas as chaves do arquivo de propriedades.

Por essa abordagem, poderíamos usar o padrão de design Singleton e em nossa estrutura.

Padrão de projeto de fábrica na estrutura do Selenium: 

No padrão de design de fábrica, criamos uma classe (a chamamos de classe Factory) e, por outro lado, temos uma interface e eventualmente implementado por “n” número de classes.

A classe de fábrica basicamente retorna o objeto das classes acima (dependendo da necessidade), então você não precisa lidar com o acima “N” número de objetos de classes; em vez disso, você pode criar um objeto da classe Factory e chamar o método da classe factory que retorna o objeto de linha de base necessário para as classes necessárias entre as classes “n” do Adobe.

Agora, esse design você pode considerar ao criar as diferentes implementações de Webdriver / navegador. 

Temos vários navegador e a implementação com um tipo diferente de Selenium driver (por exemplo, LocalDriver, RemoteDriver, ThreadDriver, etc.) o driver e o navegador para seu script de automação usar mais. 

Aqui está a base de código para implementar este padrão de design durante a criação de interações driver-navegador: 

Design de interface : 

pacote com.cyborg.core.web.utils.driverUtils; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.remote.RemoteWebDriver; public interface IDriver { public WebDriver init(String browserName); }

Número “N” de implementação de classes de navegação (que estão implementando a interface):

pacote com.cyborg.core.web.utils.driverUtils;
importar org.openqa.selenium.WebDriver;
importar org.openqa.selenium.chrome.ChromeDriver;
importar org.openqa.selenium.edge.EdgeDriver;
importar org.openqa.selenium.firefox.FirefoxDriver;
importar org.openqa.selenium.ie.InternetExplorerDriver;
importar org.openqa.selenium.safari.SafariDriver;
classe pública LocalDriver implementa IDriver {
   public WebDriver init(String nomeDoNavegador) {
       String pathToDriver = getDriverPath(nomedobrowser);
       if (nulo! = nomedonavegador) {
           switch (nomedonavegador) {
               caso "cromo":
                   System.setProperty("webdriver.chrome.driver",
                           caminhoParaDriver);
                   retornar novo ChromeDriver();
               caso "firefox":
                   System.setProperty("webdriver.gecko.driver", pathToDriver);
                   retornar novo FirefoxDriver();
               padrão:
                   System.setProperty("webdriver.chrome.driver", pathToDriver);
                   retornar novo ChromeDriver();
           }
       } outro {
           System.setProperty("webdriver.chrome.driver",
                   caminhoParaDriver);
           retornar novo ChromeDriver();
       }
   }
   private String getDriverPath(String nomeDoNavegador) {
       String osData = System.getProperty("os.name").toLowerCase().split("\\\\s")[0];
       if (nulo! = osDados) {
           if (osData.equalsIgnoreCase("mac")) {
               return "./DriversExe/" + osData + "_" + browserName;
           } else if (osData.contains("nux") || (osData.contains("nix"))) {
               return "./DriversExe/linux_" + nomedonavegador;
           } else if (osData.contains("win")) {
               return "./DriversExe/" + osData + "_" + browserName + ".exe";
           }
       }
       retornar nulo;
   }
}

Aqui está a implementação da classe Remote Driver: 

pacote com.cyborg.core.web.utils.driverUtils; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.remote.DesiredCapabilities; importar org.openqa.selenium.remote.RemoteWebDriver; import com.cyborg.core.generic.dataUtils.PropertiesDataUtils; import java.net.MalformedURLException; importar java.net.URL; classe pública RemoteDriver implementa IDriver { Caps DesiredCapabilities; String remoteHuburl=PropertiesDataUtils.configDataStore.get("WEB_GRID_IP"); @Override public WebDriver init(String browserName) { if (browserName != null) { switch (browserName) { case "firefox": try { return new RemoteWebDriver(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } case "chrome": tente { return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } case "ie": tente { return new RemoteWebDriver(new URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } default: try { return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } } return null; } else { return null; } }

Aqui está a implementação da classe Factory, que fornece o respectivo navegador e objeto de classe de driver: 

pacote com.cyborg.core.web.utils.driverUtils; public class DriverProvider { public IDriver getDriver(String typeOfDriver) { if (typeOfDriver != null) { switch (typeOfDriver) { case "local": return new LocalDriver(); case "remoto": retorna novo RemoteDriver(); padrão: retorna novo LocalDriver(); } } else { return null; } } }

Da mesma forma, você pode implementar o Appium driver junto com o mesmo design, basta fornecer a implementação e declarar um método nas interfaces IDriver. 

Conclusão: Com isso, estamos concluindo aqui como você pode usar padrões de design de linguagem como parte dos padrões de design do Selenium e melhores práticas ao desenvolver a estrutura híbrida no Selenium; nos próximos segmentos do tutorial, construiremos a estrutura do modelo de objeto de página para Automação Selenium.

Para obter o Tutorial geral sobre Selenium, você pode visitar aqui

Deixe um comentário