2 Patrones de diseño importantes y mejores prácticas de Selenium

En este tutorial aprenderemos sobre los patrones de diseño de Selenium y las mejores prácticas mientras trabajamos con el desarrollo del marco de automatización de Selenium (marco híbrido en selenium), hay dos variaciones de Diseño de marco o modelo de marco que tenemos que considerar, que son: 

Necesitamos saber y entender por qué se requiere un patrón de diseño de lenguaje cuando estamos desarrollando nuestro marco en uno de los Selenium Modelo marco. Sugerimos revisar los segmentos anteriores del Serie de tutoriales de desarrollo de Selenium Framework para obtener toda la comprensión.

Entendamos eso en detalle: 

patrones de diseño de selenio y mejores prácticasmarco híbrido en selenio

Al diseñar cualquier marco, debemos considerar alguna arquitectura de diseño, es decir, patrones de diseño de selenio y mejores prácticas, y según la necesidad del tipo de modelo del marco, debemos seleccionar un idioma. Patrón de diseño para resolver el estado del problema del diseño del marco en su conjunto.

Por lo tanto, solo para concluir, podemos elegir un modelo de marco Selenium (Híbrido, Modelo de objeto de página, Data Driven, etc.), pero para implementar el modelo, necesitamos seguir e implementar algún patrón de diseño de lenguaje (por ejemplo, patrones de diseño java/C#) 

Por qué necesitamos el patrón de diseño de selenio y las mejores prácticas al crear Selenium Framework: 

Qué patrones de diseño se utilizarán en Selenium Framework: 

Hay algunos patrones de diseño que puede usar para implementar diferentes áreas del marco, como un ejemplo: 

Haremos la plantilla de codificación en vivo de todo el Framework en las próximas publicaciones aquí.

Patrón de diseño Singleton para marco híbrido en Selenium: 

Singleton Design Pattern es un patrón en el que puede crear solo un objeto de una clase y usar el mismo objeto para acceder a los métodos de la clase; Podríamos usar el patrón de diseño en el configurador donde solo necesitamos leer los datos de configuración y podemos cargar en algún almacén de datos (cualquier tipo de estructura de datos que pueda usar cuando sea necesario mientras se ejecuta desde cualquier clase y método) 

Entonces podríamos lograr lo mismo de la siguiente manera mientras diseñamos lo mismo con el patrón de diseño Singleton. 

NOTA: Diseñaremos y desarrollaremos el marco desde cero en la próxima sección de la serie de tutoriales, pero este tutorial específico le proporcionará información sobre la necesidad del patrón de diseño.

paquete com.cyborg.core.generic.dataUtils; importar java.io.FileInputStream; importar java.io.FileNotFoundException; importar java.io.IOException; importar java.io.InputStream; importar java.util.LinkedHashMap; importar java.util.Properties; importar java.util.Set; importar org.apache.log4j.PropertyConfigurator; // Esta es la clase SingleTon public class PropertiesDataUtils { private Properties properties = null; LinkedHashMap estático público configDataStore = nuevo LinkedHashMap (); InputStream es = nulo; // Esta es la referencia estática y privada de la clase que podría usar en cualquier parte de su marco de trabajo privado static PropertiesDataUtils propertiesDataUtils = null; booleano centralizeLog = falso; // Este es el constructor privado para crear el objeto, pero no puede acceder a él desde fuera de la clase para mantener el diseño del patrón SingleTon, es decir, solo la creación de un objeto.
 Private PropertiesDataUtils(String filePath) { generarDataStore(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 básicamente crea la instancia de la clase SingleTon public static PropertiesDataUtils getInstance(String filePath) { if (propertiesDataUtils == null) propertiesDataUtils = new PropertiesDataUtils(filePath); devolver propiedadesDataUtils; } // este método básicamente crea el almacén de datos donde desea almacenar todos los datos de configuración como se discutió anteriormente. private void generateDataStore(String filePath) { try { this.properties = new Properties(); es=nuevo FileInputStream(filePath); propiedades.load(es); anularDesdeEntorno(); Establecer claves = cargarTodasLasClaves(); for (Objeto k : claves) { Cadena clave = (Cadena) k; configDataStore.put(clave, getPropertyValue(clave)); } } catch (FileNotFoundException fileNotFoundException) { StringExceptionData = String.valueOf(fileNotFoundException.getCause().getMessage()); } catch (IOException ioException) { StringExceptionData = String.valueOf(ioException.getCause().getMessage()); } finalmente { if (null != is) { try { is.close(); } catch (Exception e) { StringExceptionData = String.valueOf(e.getCause().getMessage()); } } } } // Este método se utiliza para cargar todas las claves del archivo de propiedades.

Con este enfoque, podríamos usar el patrón de diseño Singleton y usarlo en nuestro marco.

Patrón de diseño de fábrica en el marco de selenio: 

En el patrón de diseño de fábrica, creamos una clase (la llamamos clase de fábrica) y, por otro lado, tenemos una interfaz y eventualmente implementado por “n” número de clases.

La clase de fábrica básicamente devuelve el objeto de las clases anteriores (según la necesidad), por lo que no tiene que lidiar con lo anterior “N” número de objetos de clases; más bien, puede crear un objeto de la clase Factory y llamar al método de la clase Factory que devuelve el Objeto de línea de base necesario para las clases requeridas entre las clases “n” de adobe.

Ahora, este diseño puede considerarlo mientras crea la implementación diferente de Webdriver / navegador. 

Tenemos varios browser y la implementación con un tipo diferente de Selenium controlador (por ejemplo, LocalDriver, RemoteDriver, ThreadDriver, etc.) y cuando necesite un tipo específico de controlador y un tipo específico de navegador que puede mencionar en el archivo de configuración y, según la necesidad, la clase de fábrica le proporcionará la instancia de el controlador y el navegador para su secuencia de comandos de automatización para usar más. 

Aquí está la base del código para implementar este patrón de diseño mientras se crean interacciones entre el controlador y el navegador: 

Diseño de interfaz : 

paquete com.cyborg.core.web.utils.driverUtils; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.remote.RemoteWebDriver; interfaz pública IDriver { public WebDriver init(String browserName); }

Número "N" de implementación de clases de navegación (que están implementando la interfaz):

paquete 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;
clase pública LocalDriver implementa IDriver {
   init público WebDriver (cadena nombre del navegador) {
       String pathToDriver = getDriverPath(nombredelnavegador);
       if (nulo! = Nombre del navegador) {
           cambiar (nombre del navegador) {
               caso "cromo":
                   System.setProperty("webdriver.chrome.driver",
                           rutaAlConductor);
                   devolver nuevo ChromeDriver();
               caso "firefox":
                   System.setProperty("webdriver.gecko.driver", rutaADriver);
                   devolver nuevo FirefoxDriver();
               por defecto:
                   System.setProperty("webdriver.chrome.driver", rutaADriver);
                   devolver nuevo ChromeDriver();
           }
       } demás {
           System.setProperty("webdriver.chrome.driver",
                   rutaAlConductor);
           devolver nuevo ChromeDriver();
       }
   }
   cadena privada getDriverPath (cadena nombre del navegador) {
       String osData = System.getProperty("os.name").toLowerCase().split("\\\\s")[0];
       si (nulo! = datosos) {
           si (osData.equalsIgnoreCase("mac")) {
               devolver "./DriversExe/" + osData + "_" + nombre del navegador;
           } else if (osData.contains("nux") || (osData.contains("nix"))) {
               return "./DriversExe/linux_" + nombre del navegador;
           } más si (osData.contains("win")) {
               devolver "./DriversExe/" + osData + "_" + nombre del navegador + ".exe";
           }
       }
       devolver nulo;
   }
}

Aquí está la implementación de la clase Remote Driver: 

paquete com.cyborg.core.web.utils.driverUtils; importar org.openqa.selenium.WebDriver; importar org.openqa.selenium.remote.DesiredCapabilities; importar org.openqa.selenium.remote.RemoteWebDriver; importar com.cyborg.core.generic.dataUtils.PropertiesDataUtils; importar java.net.MalformedURLException; importar java.net.URL; clase pública RemoteDriver implementa IDriver { DesiredCapabilities caps; 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(nueva URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } case "chrome": pruebe { return new RemoteWebDriver(nueva URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } caso "es decir": intente { devuelva nuevo RemoteWebDriver (nueva URL (remoteHuburl), caps.internetExplorer ()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } predeterminado: pruebe { devuelva el nuevo RemoteWebDriver(nueva URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) { malformedUrlEx.getCause().getMessage(); malformedUrlEx.printStackTrace(); } } devuelve nulo; } más { devuelve nulo; } }

Aquí está la implementación de la clase Factory, que proporciona el navegador y el objeto de clase de controlador respectivos: 

paquete 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": devuelve nuevo RemoteDriver(); predeterminado: devuelve nuevo LocalDriver(); } } más { devuelve nulo; } } }

Asimismo, puede implementar la Appium driver junto con el mismo diseño, solo proporcione la implementación y declare un método en las interfaces IDriver. 

Conclusión: Con esto, estamos concluyendo aquí cómo puede usar patrones de diseño de lenguaje como parte de los patrones de diseño de Selenium y las mejores prácticas mientras desarrolla el marco híbrido en Selenium; En los próximos segmentos del tutorial, crearemos el marco del modelo de objeto de página para Selenium Automation.

Para obtener el Tutorial general sobre selenio, puede visitar aquí

Deja un comentario