הקדמה
במאמר זה, אסקור את השימוש בתבנית עיצוב הנקראת תבנית המתאם (Adapter pattern). לפי baeldung:
תבנית מתאם פועלת כמחבר בין שני ממשקים לא תואמים שאחרת לא ניתן לחבר ישירות. מתאם עוטף מחלקה קיימת בממשק חדש כך שהיא הופכת תואמת לממשק של הלקוח.
המניע העיקרי מאחורי השימוש בתבנית זו הוא להמיר ממשק קיים לממשק אחר שהלקוח מצפה לו. היא מיושמת בדרך כלל לאחר שהיישום כבר תוכנן.
הבעיה
בבדיקות האוטומציה שלי, הייתי צריך לכתוב כמה מקרי בדיקה המבצעים הגשות טפסים שונות מדפים שונים, כאשר כל טופס דרש גם שליחת נתונים ייחודיים משלו. האוטומציה מבצעת את הגשת הטופס ומאמתת שהודעת הצלחה מופיעה.
בהתחלה, יצרתי מחלקות בדיקה שונות עבור כל טופס. היישום היה:
מחלקת הבדיקה של הטופס הראשון:
@Description("First Form Submission Test")
@Test
public void sendingFirstFormInputTest() {
formPage.selectForm(FormList.FIRST_FORM);
formPage
.clearInputFields()
.sendFirstFormData(firstFormObject)
.confirmChanges();
assertThat(wait.until(
ExpectedConditions.visibilityOf(formPage.getAlertSuccess())).isDisplayed())
.as("alert success message is displayed")
.isTrue();
}
מחלקת הבדיקה של הטופס השני:
@Description("Second Form Submission Test")
@Test
public void sendingSecondFormInputTest() {
formPage.selectForm(FormList.SECOND_FORM);
formPage
.clearInputFields()
.sendFirstFormData(secondFormObject)
.confirmChanges();
assertThat(wait.until(
ExpectedConditions.visibilityOf(formPage.getAlertSuccess())).isDisplayed())
.as("alert success message is displayed")
.isTrue();
}
ביישום זה - כל טופס חדש שפותח יגרום להגדלת מספר מחלקות הבדיקה. בדיקות אלו מבצעות כמעט בדיוק את אותו הדבר.
הייתי זקוק לפתרון גנרי שיעזור לי לצמצם את מספר מחלקות הבדיקה עבור טפסים אלה.
הפתרון - שימוש בתבנית המתאם
יצירת הממשק
יצרתי ממשק טופס (form interface) שיתפקד כמתאם גנרי של יצירת הטופס.
מתודת ה-configure של הממשק מקבלת את הפרמטרים הבאים:
- מופע ה-wait שנמצא כעת בשימוש.
- רשימה של שדות הקלט של הטופס שצריך למפות כאשר אנו שולחים את נתוני הטופס הרלוונטיים.
היישום הוא:
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
public interface Form {
public void configure(WebDriverWait wait, List<WebElement> fields);
}
כל טופס חייב לממש את ממשק הטופס ולהגדיר את הטופס. אני משתמש ב-Lombok ובתבנית הבנאי (builder pattern) כדי לבנות את אובייקט הטופס. תוכלו לקרוא על כך בהרחבה כאן. מחלקת הטופס הראשון נראית כעת כך:
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class FirstForm implements Form {
private String email;
private String phone;
@Override
public void configure(WebDriverWait wait, List<WebElement> fields) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector(".loading")));
fields.get(1).sendKeys(this.getEmail());
fields.get(2).sendKeys(this.getPhone());
}
}
מחלקת הטופס השני נראית כעת כך:
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class SecondForm implements Form {
private String city;
private String country;
private String region;
@Override
public void configure(WebDriverWait wait, List<WebElement> fields) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector(".loading")));
fields.get(1).sendKeys(this.getCity());
fields.get(2).sendKeys(this.getCountry());
fields.get(3).sendKeys(this.getRegion());
}
}
יישום הבדיקה באמצעות TestNG DataProvider - בדיקות מונחות נתונים
במחלקת הבדיקה, אנו משתמשים ב-TestNG וב-DataProvider, שהיא מתודה ש-TestNG מספקת לביצוע בדיקות מונחות נתונים. מתודת ה-DataProvider שיצרתי במחלקת הבדיקה מספקת לבדיקות את הנתונים הבאים:
- לאיזה טופס לנווט.
- אובייקט טופס הנדרש לתצורת הטופס.
היישום של מחלקת הבדיקה הוא:
public class FormTest extends BaseTest {
protected FormPage formPage;
@DataProvider(name = "Form data")
public static Object[][] formData() {
return new Object[][] {
{
FormList.FIRST_FORM,
FirstForm.builder().email(data.getEmail())
.phone(data.getPhone())
.build()
},
{
FormList.SECOND_FORM,
SecondForm.builder()
.city(data.getCity())
.country(data.getCountry())
.region(data.getRegion())
.build()
}
};
}
@Description("Submit Form")
@Test(dataProvider = "Form data")
public void submitForm(FormList formName, Form form) {
formPage.selectForm(formName).clearInputFields();
form.configure(wait, formPage.getFields());
formPage.confirmChanges();
assertThat(wait.until(ExpectedConditions.visibilityOf(formPage.getAlertSuccess())).isDisplayed())
.as("alert success message is displayed")
.isTrue();
}
}
עם פתרון זה - כל בדיקות הגשת הטפסים יבוצעו באותה מחלקת בדיקה. עבור כל טופס חדש, השינוי היחיד הנדרש הוא הוספת אובייקט נתונים חדש במתודת ה-dataProvider.
קריאה נוספת על TestNG dataProvider ניתן למצוא בתיעוד של TestNG.
לסיכום
במאמר זה, סקרנו את תבנית העיצוב ‘מתאם’ ואת יתרונותיה - צמצום מחלקות הבדיקה והיכולת ליצור ממשק גנרי המשפר את קריאות הקוד.
קריאה נוספת על תבניות עיצוב ב-Java ניתן למצוא בקישור זה.
בדיקות מהנות!