2 Wichtige Selen-Entwurfsmuster und Best Practices

In diesem Tutorial lernen wir die Selenium-Entwurfsmuster und Best Practices bei der Arbeit mit der Selenium Automation-Framework-Entwicklung (Hybrid-Framework in Selen) kennen. Dabei müssen zwei Varianten des Framework-Designs oder des Framework-Modells berücksichtigt werden: 

Wir müssen wissen und verstehen, warum ein Sprachdesignmuster erforderlich ist, wenn wir unser entwickeln Rahmen in einem der Selenium Rahmenmodell. Wir empfehlen, die vorherigen Segmente des durchzugehen Lernserie zur Selenium Framework-Entwicklung um das ganze Verständnis zu bekommen.

Lassen Sie uns das im Detail verstehen: 

Selen-Designmuster und Best Practices -Hybridgerüst in Selen

Beim Entwerfen eines Frameworks müssen wir einige Designarchitekturen berücksichtigen, dh Selen-Designmuster und Best Practices, und je nach Bedarf des Framework-Modells müssen wir eine Sprache auswählen Entwurfsmuster den Problemzustand des Framework-Designs als Ganzes zu lösen.

Daher können wir nur abschließend ein Selenium-Framework-Modell (Hybrid, Seitenobjektmodell, Data Driven usw.), aber um das Modell zu implementieren, müssen wir einige Sprachdesignmuster befolgen und implementieren (z. B. Java/C#-Designmuster). 

Warum wir beim Erstellen des Selenium Frameworks ein Selen-Design-Muster und Best Practices benötigen: 

Welche Entwurfsmuster sollen in Selenium Framework verwendet werden: 

Es gibt einige Entwurfsmuster, mit denen Sie verschiedene Bereiche des Frameworks implementieren können, z. B. ein Beispiel: 

Wir werden die Live-Codierungsvorlage des gesamten Frameworks in den kommenden Beiträgen hier erstellen.

Singleton-Entwurfsmuster für Hybrid-Framework in Selen: 

Singleton Design Pattern ist ein Muster, in dem Sie nur ein Objekt aus einer Klasse erstellen und dasselbe Objekt verwenden können, um auf die Methoden der Klasse zuzugreifen. Wir könnten das Entwurfsmuster im Konfigurator verwenden, wo wir nur die Konfigurationsdaten lesen müssen und in einen Datenspeicher laden können (jede Art von Datenstruktur, die Sie bei Bedarf während der Ausführung von Klassen und Methoden verwenden können). 

So können wir dasselbe auf die folgende Weise erreichen, während wir dasselbe mit dem Singleton-Entwurfsmuster entwerfen. 

HINWEIS: Wir werden das Framework im nächsten Abschnitt der Lernprogrammreihe von Grund auf neu entwerfen und entwickeln. Dieses spezielle Lernprogramm bietet Ihnen jedoch einen Einblick in die Notwendigkeit des Entwurfsmusters.

Paket com.cyborg.core.generic.dataUtils; java.io.FileInputStream importieren; java.io.FileNotFoundException importieren; java.io.IOException importieren; java.io.InputStream importieren; java.util.LinkedHashMap importieren; java.util.Properties importieren; java.util.Set importieren; import org.apache.log4j.PropertyConfigurator; // Dies ist die SingleTon-Klasse public class PropertiesDataUtils { private Properties properties = null; öffentliche statische LinkedHashMap configDataStore = neue LinkedHashMap (); InputStream ist = null; // Dies ist die statische und private Referenz der Klasse, die Sie überall in Ihrem Framework verwenden können. private static PropertiesDataUtils propertiesDataUtils = null; boolean centralizeLog = falsch; // Dies ist der private Konstruktor zum Erstellen des Objekts, aber Sie können nicht von außerhalb der Klasse darauf zugreifen, um das Design des SingleTon-Musters beizubehalten, dh nur eine Objekterstellung.
 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"); sonst PropertyConfigurator.configure(System.getProperty("user.dir")+"//src//test//resources//config//log4j_local.properties"); } private PropertiesDataUtils() { } // Diese Methode erstellt grundsätzlich die Instanz der SingleTon-Klasse public static PropertiesDataUtils getInstance(String filePath) { if (propertiesDataUtils == null) propertiesDataUtils = new PropertiesDataUtils(filePath); return propertiesDataUtils; } // Diese Methode erstellt grundsätzlich den Datenspeicher, in dem Sie alle Konfigurationsdaten speichern möchten, wie zuvor besprochen. private void generateDataStore(String filePath) { try { this.properties = new Properties(); ist=neuer FileInputStream(filePath); properties.load (ist); overrideFromEnvironment(); Satz Tasten = LoadAllKeys (); for (Object k : keys) {String key = (String) k; configDataStore.put (Schlüssel, getPropertyValue (Schlüssel)); } } catch (FileNotFoundException fileNotFoundException) { String exceptionData = String.valueOf(fileNotFoundException.getCause().getMessage()); } catch (IOException ioException) {String exceptionData = String.valueOf(ioException.getCause().getMessage()); } final { if (null != is) { try { is.close(); } catch (Exception e) { String exceptionData = String.valueOf(e.getCause().getMessage()); } } } } // Diese Methode wird verwendet, um alle Schlüssel aus der Eigenschaftendatei zu laden.

Durch diesen Ansatz könnten wir das Singleton-Entwurfsmuster verwenden und es in unserem Framework verwenden.

Factory Design Pattern im Selenium Framework: 

Im Factory-Design-Muster erstellen wir eine Klasse (wir nennen sie eine Factory-Klasse), und andererseits haben wir eine Schnittstelle und schließlich durch "n" Anzahl von Klassen implementiert.

Die Factory-Klasse gibt grundsätzlich das Objekt der oben genannten Klassen zurück (je nach Bedarf), sodass Sie sich nicht mit den oben genannten befassen müssen "N" Anzahl der Klassenobjekte; Stattdessen können Sie ein Objekt der Factory-Klasse erstellen und die Methode der Factory-Klasse aufrufen, die das erforderliche Basisobjekt für die erforderlichen Klassen unter den Adobe-Klassen „n“ zurückgibt.

Dieses Design können Sie nun beim Erstellen der verschiedenen Webdriver / Browser-Implementierung berücksichtigen. 

Wir haben verschiedene Browser und die Implementierung mit einer anderen Art von Selenium Treiber (z. B. LocalDriver, RemoteDriver, ThreadDriver usw.) und wenn Sie einen bestimmten Treibertyp und einen bestimmten Browsertyp benötigen, können Sie dies in der Konfigurationsdatei angeben, und je nach Bedarf stellt Ihnen die Factory-Klasse die Instanz zur Verfügung den Treiber und Browser für Ihr Automatisierungsskript zur weiteren Verwendung. 

Hier ist die Codebasis zum Implementieren dieses Entwurfsmusters beim Erstellen von Treiber-Browser-Interaktionen: 

Schnittstellen-Design : 

Paket com.cyborg.core.web.utils.driverUtils; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.RemoteWebDriver; öffentliche Schnittstelle IDriver { öffentlicher WebDriver init (String browserName); }

"N" Anzahl der Implementierungen von Suchklassen (die die Schnittstelle implementieren):

Paket com.cyborg.core.web.utils.driverUtils;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.safari.SafariDriver;
Die öffentliche Klasse LocalDriver implementiert IDriver {
   public WebDriver init(String browserName) {
       String pathToDriver = getDriverPath(browserName);
       if (null != browserName) {
           switch (Browsername) {
               Gehäuse „Chrom“:
                   System.setProperty("webdriver.chrome.driver",
                           pathToDriver);
                   return new ChromeDriver();
               Fall „Firefox“:
                   System.setProperty("webdriver.gecko.driver", pathToDriver);
                   return new FirefoxDriver();
               Standard:
                   System.setProperty("webdriver.chrome.driver", pathToDriver);
                   return new ChromeDriver();
           }
       } anders {
           System.setProperty("webdriver.chrome.driver",
                   pathToDriver);
           return new ChromeDriver();
       }
   }
   privater String getDriverPath(String browserName) {
       String osData = System.getProperty("os.name").toLowerCase().split("\\\\s")[0];
       if (null != osData) {
           if (osData.equalsIgnoreCase("mac")) {
               return „./DriversExe/“ + osData + „_“ + browserName;
           } else if (osData.contains("nux") || (osData.contains("nix"))) {
               return „./DriversExe/linux_“ + browserName;
           } else if (osData.contains("win")) {
               return „./DriversExe/“ + osData + „_“ + browserName + „.exe“;
           }
       }
       null zurückgeben;
   }
}

Hier ist die Implementierung der Remote Driver-Klasse: 

Paket com.cyborg.core.web.utils.driverUtils; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import com.cyborg.core.generic.dataUtils.PropertiesDataUtils; java.net.MalformedURLException importieren; java.net.URL importieren; öffentliche Klasse RemoteDriver implementiert 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(new URL(remoteHuburl), caps.firefox()); } catch (MalformedURLException malformedUrlEx) {malformedUrlEx.getCause().getMessage(); fehlerhafteUrlEx.printStackTrace(); } case "chrome": try {return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) {malformedUrlEx.getCause().getMessage(); fehlerhafteUrlEx.printStackTrace(); } case "ie": try {return new RemoteWebDriver(new URL(remoteHuburl), caps.internetExplorer()); } catch (MalformedURLException malformedUrlEx) {malformedUrlEx.getCause().getMessage(); fehlerhafteUrlEx.printStackTrace(); } default: try {return new RemoteWebDriver(new URL(remoteHuburl), caps.chrome()); } catch (MalformedURLException malformedUrlEx) {malformedUrlEx.getCause().getMessage(); fehlerhafteUrlEx.printStackTrace(); } } Null zurückgeben; } Sonst {Null zurückgeben; } }

Hier ist die Implementierung der Factory-Klasse, die das jeweilige Browser- und Treiberklassenobjekt bereitstellt: 

Paket 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 "remote": return new RemoteDriver(); Standard: neuer LocalDriver(); zurückgeben; } } Else {Rückgabe null; } } }

Ebenso können Sie die implementieren Appium Treiber zusammen mit dem gleichen Design, stellen Sie einfach die Implementierung bereit und deklarieren Sie eine Methode in den IDriver-Schnittstellen. 

Fazit: Damit schließen wir hier, wie Sie Sprachdesignmuster als Teil der Selenium-Designmuster und Best Practices verwenden können, während Sie das Hybrid-Framework in Selenium entwickeln. In den nächsten Abschnitten des Tutorials werden wir das Seitenobjektmodell-Framework für Selenium Automation erstellen.

Um die Das gesamte Tutorial zu Selen können Sie hier besuchen

Hinterlasse einen Kommentar