אני הולך להמשיך גם הפעם את הקו שאליו חתרתי בפוסטים האחרונים שלי והוא כיצד ניתן לכתוב תשתית אוטומציה נכונה, הפעם הפוסט מדבר על הפשטה של הדפים אותם אנו מאטמטים.

בואו קודם כל נכיר את המושג הזה: "הפשטה", או באנגלית Abstraction , מה הוא ? ולמה הוא נועד ?

הפשטה (אבסטרקציה) היא טכניקה בעיצוב תוכנה שנועדה לארגן מורכבות של לוגיקה דרך הקוד. כשמשתמשים באבסטרקציה , משתמשים בכדיי להסתיר את המורכבות הזאת , להסתיר מימושים שונים של פעולות. אנחנו נרצה לעבוד וליצור שכבות אבסטרקטיות בכדיי להציג רק את הפרטים הרלוונטיים עבור אותו מתכנת על ידי הקטנת כמות הפרטים ו"הוצאה החוצה" של הטיפול בהם.

כשאנו כותבים פרוייקט אוטומציה (שהוא כאמור פרוייקט תוכנה לכל דבר) , יש לנו את היכולת גם כאן להשתמש בטכניקה זו של הפשטה. במקרה שלנו נוכל לבצע את הסתרת מורכבות ומימוש הפעולות על גבי הדפים שאנו עובדים עליהם (דוגמא נוספת לעבודה עם דפים ניתן לראות ב- Page Objects)

למעשה ניתן להגדיר את הפרוייקט שלנו כארכיטקטורה רב-שכבתית בכדיי שבסופו של דבר אותו מיישם אוטומציה – זה שכותב את הטסטים העיסקיים מעל המוצר יוכל לעשות זאת במינימום מאמץ או במינימום חשיפה למורכבות התשתית.

 

השכבה הראשונה תהיה זו של Selenium או Appium – אותם מימושים של מתודות ולוגיקות בהן אנחנו בד"כ לא נוגעים

שכבה שניה יכולה להיות ספריות קוד שיושבות מעל אותן ספריות גנריות של Selenium או Appium , ראו דוגמת Selenide או Robot Framework – שכבות אלו באו להסתיר את הממימושים של פעולות מורכבות יותר כדוגמת המתנה + וידוא קיום אלמנט על הדף.

שכבה שלישית יכולה להיות מימוש שלנו (של אותם מפתחי אוטומציה) לפעולות מורכבות שיכולות לבוא מעל השכבה הראשונה או מעל השכבה השנייה , לדוגמא לאחר שהשתמשנו בפעולת ההמתנה + וידוא מהשכבה השנייה , נוכל להוסיף גם פעולות נוספות כגון קריאות לספריות חיצוניות או יצירת אובייקטים לשכבה שתוא מעל (מה שנקרא – "הכנה למזגן")

בשכבה הרביעית נוכל בפשטות לקרוא לפעולות שמימשנו בשכבה השלישית (שהן קראו לפעולות מהשכבה השנייה שהן קראו לפעולות הגנריות של שכבת הבסיס) – זוהי תהיה שכבת הטסטים שלנו.

אני רוצה להראות איזושהי דוגמא לאבסטרקציה בסיסית שניתן לבצע מעל המתודות של סלניום ומעל המתודות שקוראות למתודות של סלניום באותה מחלקה (נכתב ב-#C)

 

page_pobjects

 

ניצור תחילה מחלקה (נקרא לה Page) ונממש לה בנאי שמקבל את ה- driver כמובן ופרק זמן שיהוה את החסם העליון לכל ה-Wait-ים למיניהם)

public class Page
{
    private IWebDriver driver;
    private TimeSpan defaultTimeSpan;

    public Page(IWebDriver driver, TimeSpan defaultTimeSpan)
    {
        this.driver = driver;
        this.defaultTimeSpan = defaultTimeSpan;
    }
}

 

כעת נממש את ה-Locators , אותו אובייקט שדרכו Selenium יודע לזהות אלמנטים , למעשה יש לנו 8 סוגים שונים של Locators (מתודות לזיהוי):

 

By.Id
By.Name
By.ClassName
By.TagName
By.LinkText
By.PartialLinkText
By.CssSelector
By.XPath

[ה-By הוא האובייקט שנקרא גם Locator]

אז המימוש יתבצע כך:

private By ByLocator(string element, Locator locator)
{
     switch (locator)
     {
          case Locator.Id:
              return By.Id(element);
           case Locator.Name:
               return By.Name(element);
           case Locator.TagName:
               return By.TagName(element);
           case Locator.ClassName:
                return By.ClassName(element);
            case Locator.LinkText:
                return By.LinkText(element);
            case Locator.PartialLinkText:
                return By.TagName(element);
            case Locator.XPath:
                return By.XPath(element);
            case Locator.CssSelector:
                return By.CssSelector(element);
            default:
                throw new Exception("No Locator Found");
       }
}

 

נממש את מתודת ה-Find – עליה נתבסס אח"כ בכמה מקומות (תוך שימוש במתודת ה-ByLocator שיצרנו):

public IWebElement Find(string element, Locator locator)
{
     return driver.FindElement(ByLocator(element, locator));
}

 

ונמשיך לממש את שאר המתודות (תוך שימוש במתודת ה-Find):

public Page Fill(string element, string value, Locator locator)
{
      Find(element, locator).Clear();
      Find(element, locator).SendKeys(value);
      return this;
}

 

public Page WaitUntil(Func<IWebDriver, TResult> condiction)
{
      new WebDriverWait(driver, this.defaultTimeSpan).Until(condiction);
      return this;
}

 

public Page NavigateTo(string url, string proofElement, Locator locator)
{
driver.Navigate().GoToUrl(url);
new WebDriverWait(driver, this.defaultTimeSpan)
.Until(d => d.FindElement(ByLocator(proofElement, locator)));

return this;
}

 

מכאן ניתן להמשיך עוד ועוד …

בשכבה שמעל , אנחנו פשוט נקרא למתודות הללו כמו ה-Fill תוך שליחת הארגומנטים הרצויים (ארגומנטים אלו מגיעים מאותו בודק כחלק בבמקרה הבדיקה) , זה אומר שאותו בודק, כשהוא מרכיב את מקרה הבדיקה שלו, הוא כלל אינו יודע או מכיר את המורכבות של מתודת Fill (שמשתמשת כאמור במתודות אחרות).

 

שימו לב – הדוגמא המובאת כאן אינה מייצגת Abstract Class קלאסי בו אנו מצהירים על המתודות ודואגים לממש אותן במחלקות היורשות, זוהי פשוט דרך נוספת להראות שימוש באבסטרקציה מעל גביי הדפים (Pages)

השאר הערה\הודעה