פיתוח/בדיקות מנשק משתמש

    From The Document Foundation Wiki
    This page is a translated version of the page Development/UITests and the translation is 94% complete.
    Outdated translations are marked like this.
    Other languages:

    זה התיעוד הראשוני לתשתית בדיקות מנשק משתמש עם התמקדות מיוחדת בצד של ה־Python.

    מבנה

    בדיקות מנשק המשתמש מורכבות משני חלקים, חלק ב־C++‎ שעוטף את מנשק המשתמש של LibreOffice בספריה שבוחנת את המערכת פנימה ותשתית Python עם קוד בדיקה ממשי. החיבור בין שני החלקים נעשה דרך מנשק UNO פשוט שטרם הוקלד.

    ספריית הבחינה פנימה ב־C++‎

    ספריית הבחינה הפנימית ב־C++‎ מורכבת מ־UNO API שמשמש לתקשורת עם החלק של ה־Python של התשתית והחלקים העוטפים למגוון פריטי מנשק משתמש. למנשק UNO יש מגוון מצומצם של שיטות ורוב התקשורת מתרחשת דרך משתני מחרוזות.

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

    תשתית Python

    כתיבת בדיקות

    המצגת של שיסקו פאולי מ־FOSDEM 2021, אבטחת איכות של LibreOffice - איך לכתוב את הבדיקה הראשונה שלך, עוברת על תהליך יצירת בדיקות.

    Xisco's presentation from FOSDEM 2022 shows Things you can test in a UITest.

    החלק של ה־Makefile

    קובץ makefile פשוט לבדיקות מנשק משתמש נראה כמו ה־makefile לדוגמה. החלק החשוב הוא להשתמש במחלקה UITest של gbuild ולאפשר ל־„gb_UITest_add_module” להצביע לתיקיות עם קובצי הבדיקות.

    בדרך כלל לא צריך לעשות שום דבר מעבר לזה והרוב מטופל במסגרת מחלקת ה־UITest של gbuild.

    $(eval $(call gb_UITest_UITest,range_name))
    
    $(eval $(call gb_UITest_add_modules,range_name,$(SRCDIR)/sc/qa/uitest,\
        test_dir1/ \
        test_dir2/ \
    ))

    המשתנה range_name (שם טווח) הוא שם יעד הבדיקה. ‎$(SRCDIR/sc/qa/uitest היא תיקיית הבסיס והמשתנים בחלק הזה מציגים את התיקיות בהן יתבצע החיפוש אחר הבדיקות.

    ניתן להריץ את הבדיקה עם קובץ registrymodifications.xcu מסוים כדי לתמוך בהרצה עם הגדרות תצורה מסוימות. לכל בדיקה יש פרופיל משתמש משלה תחת workdir/UITest/test_name/user/‎. עם מקטע הקוד הבא כ־Makefile ניתן להעתיק קובץ לתיקייה הזאת.

    $(eval $(call gb_UITest_use_configuration,range_name,$(SRCDIR)/sc/qa/uitest/range_name/registrymodifications.xcu))

    פעולה זו תעתיק את הקובץ sc/qa/uitest/range_name/registrymodifications.xcu לפרופיל המשתמש והבדיקה תרוץ עם ההגדרות האלו.

    כתיבת הקוד ב־Python

    תשתית

    פקודות שזמינות מול רכיבי מנשק משתמש

    כללי

    טיפול במצב רכיבי מנשק משתמש

    השיטה לקבלת מצב פריט מנשק המשתמש מסופקת על ידי כלל רכיבי מנשק המשתמש. השיטה מחזירה את המצב כרצף של PropertyValue.

    ui_element.getState()

    תשתית בדיקת מנשק המשתמש מספקת שיטה להמרת הרצף שמוחזק של PropertyValue למילון (dict) ב־Python.

    from uitest.uihelper.common import get_state_as_dict
    
    get_state_as_dict(ui_element)

    שליחת קלט מקלדת לרכיב

    from uitest.uihelper.common import type_text
    
    xWriterDoc = self.xUITest.getTopFocusWindow()
    xWriterEdit = xWriterDoc.getChild("writer_edit")
    type_text(xWriterEdit, "Test")

    בחירת טקסט

    from uitest.uihelper.common import select_text
    
    xEdit = xAddNameDlg.getChild("edit")
    select_text(xEdit, from_pos="2", to="12")

    הגדרת תקריב

    xWriterEdit = xWriterDoc.getChild("writer_edit")
    xWriterEdit.executeAction("SET", mkPropertyValues({"ZOOM": "200"}))

    קפיצה אל עמוד

    xWriterEdit = xWriterDoc.getChild("writer_edit")
    xWriterEdit.executeAction("GOTO", mkPropertyValues({"PAGE": "1"}))

    פעולות בקרה

    בקרה קוד הנחה
    כפתור

    xControl.executeAction("CLICK", tuple())

    ---

    תיבת טקסט

    from uitest.uihelper.common import type_pos
    
    type_text(xControl, "Text")

    self.assertEqual(get_state_as_dict(xTitleText)["Text"], "Text")

    תיבת סימון

    xControl.executeAction("CLICK", tuple())

    self.assertEqual(get_state_as_dict(xControl)["Selected"], "true")

    וידג׳ט מפת תווים

    from libreoffice.uno.propertyvalue import mkPropertyValues
    
    xControl.executeAction("SELECT", mkPropertyValues({"COLUMN": "2", "ROW": "2"}))

    ---

    רשימת עץ

    # פריסת/קיפול העץ
    xTreelist = xExDBDlg.getChild("availablelb")         
    xTreeEntry = xTreelist.getChild('0')
    xTreeEntry.executeAction("EXPAND", tuple())  #Available Databases
    xTreeEntry.executeAction("COLLAPSE", tuple()) #Click on the Bibliography
    
    xTreeEntry2 = xTreeEntry.getChild('0')
    xTreeEntry2.executeAction("SELECT", tuple())

    ---

    תיבת בחירה

    from uitest.uihelper.common import select_pos
    
    select_pos(xCombobox, "1")

    self.assertEqual(get_state_as_dict(xNumbering)["SelectEntryText"], "List 1")

    לשוניות

    from uitest.uihelper.common import select_pos
    
    xTabs = xDialog.getChild("tabcontrol")
    select_pos(xTabs, "0")

    self.assertEqual(get_state_as_dict(xTabs)["CurrPagePos"], "0")

    ListBox (תיבת רשימה - לפי מיקום)

    from uitest.uihelper.common import select_pos
    
    select_pos(xListBox, "1")

    self.assertEqual(get_state_as_dict(xListBox)["SelectEntryText"], "List 1")

    ListBox (תיבת רשימה - לפי שם)

    from uitest.uihelper.common import select_pos
    
    categoryLB = xCellsDlg.getChild("categorylb")
            props = {"TEXT": "Time"}
    
    actionProps = mkPropertyValues(props)
            categoryLB.executeAction("SELECT", actionProps)

    self.assertEqual(get_state_as_dict(categoryLB)["SelectEntryText"], "Time")

    חלונית לשונית (לפי שם)

    props = {"NAME": "Borders"}
            propsUNO = mkPropertyValues(props)
            xCellsDlg.executeAction("SELECT", propsUNO)

    ---

    שדה נגלל

    xDecimalPlaces.executeAction("UP", tuple())
    xDecimalPlaces.executeAction("DOWN", tuple())

    self.assertEqual(get_state_as_dict(xDecimalPlaces)["Text"], "Title text")

    כפתור בחירה

    xSuperscript.executeAction("CLICK", tuple())

    self.assertEqual(get_state_as_dict(xSuperscript)["Checked"], "true")

    ColorListBox

    xWidget.executeAction("OPENLIST", tuple())
    xFloatWindow = self.xUITest.getFloatWindow()
    xPaletteSelector = xFloatWindow.getChild("palette_listbox")
    select_by_text(xPaletteSelector, "chart-palettes")  # or some other name
    xColorSet = xFloatWindow.getChild("colorset")
    xColorSet.executeAction("CHOOSE", mkPropertyValues({"POS": "2"}))  # or some other position

    ---

    MenuButton

    xWidget.executeAction("OPENFROMLIST", mkPropertyValues({"POS": "0"}))

    ---


    פעולות מילות מפתח

    דוגמה:

    from libreoffice.uno.propertyvalue import mkPropertyValues
    
    ui_object.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))

    קודים של מקשים:

    • ESC
    • TAB
    • DOWN
    • UP
    • LEFT
    • RIGHT
    • DELETE
    • INSERT
    • BACKSPACE
    • RETURN
    • HOME
    • END
    • PAGEUP
    • PAGEDOWN
    • CTRL
    • ALT
    • SHIFT

    איך להרחיב את ספריית הבחינה הפנימית

    רכיבי מנשק משתמש שמרחיבים את vcl::Window

    רכיבי מנשק משתמש אחרים

    כלים לכתיבת בדיקות

    החלק המסובך בכתיבת בדיקה היא להבין אילו פקודות UNO לשלוח ולאיזו פעולה לקרוא מול רכיב מנשק משתמש. למרבה המזל, אפשר לשמור תיעוד של פקודות UNO.

    1. יש להשתמש בפקודות האלו ב־‎.bashrc או ב־‎.cshrc:
      export PYTHONPATH=/"Path of LibreOffice repo"/instdir/program/
      export URE_BOOTSTRAP=file:///"Path of LibreOffice repo"/instdir/program/fundamentalrc
    2. להפעיל את LibreOffice עם
      LO_COLLECT_UIINFO="test.log" SAL_USE_VCLPLUGIN=gen instdir/program/soffice
    3. לדמות מה מעניין אותך לעשות עם העכבר
    4. לסגור את LibreOffice
    5. לפתוח את הקובץ שמתקבל תחת instdir/uitest/test.log
    6. להיכנס לתיקיית מתעד מנשק המשתמש עם הפקודה הבאה:
      cd uitest/ui_logger_dsl/
    7. לוודא של־python יש את ספריית textX מותקנת
    8. להשתמש בפקודה הבאה
      python dsl_core.py <נתיב_לקובץ_תיעוד> <נתיב_לקובץ_python_חדש>
      את <נתיב_לקובץ_תיעוד> יש להחליף במשהו כמו SourceDirectory/core/instdir/uitest/test.log ואילו <נתיב_לקובץ_python_חדש> יכול להיות המיקום לבחירתך בו עדיף לך לצפות בקוד שנוצר.

    ניתן לעקוב אחר כל השלבים האלו בסרטון ה־YouTube הבא:

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

    מדיניות הפרטיות של YouTube


    הרצת הבדיקה

    לפני דחיפת (push) הבדיקה ל־master כדאי לבדוק שהבדיקה עובדת. הדרך הפשוטה היא להפעיל את כל בדיקות מנשק המשתמש במודול uitest דרך make uitest.uicheck. עם זאת, עדיף לראות את מנשק המשתמש בזמן הפעלת הבדיקה והבדיקות רצות ללא תצוגה כבררת מחדל. אפשר לעשות זאת על ידי הרצת הרצף הבא בתיקיית הליבה:

    (cd sc && make -srj1 UITest_sort UITEST_TEST_NAME="sorting.CalcSorting.test_Sortingbuttons_detect_columnheaders" SAL_USE_VCLPLUGIN=gen)

    אפשר גם להשתמש בסקריפט shell להתחלת בדיקה.

    Note that you have to run this script from the source directory of LibreOffice core.

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

    export SRCDIR=$PWD
    export PYTHONPATH=$SRCDIR/instdir/program:unotest/source/python
    export URE_BOOTSTRAP=file://$SRCDIR/instdir/program/fundamentalrc
    export TestUserDir=file:///tmp
    export TDOC=$SRCDIR/sw/qa/uitest/data
    export SAL_USE_VCLPLUGIN=gen
    export LC_ALL=C
    
    rm -rf /tmp/libreoffice/4
    
    python3 "$SRCDIR"/uitest/test_main.py --soffice=path:"$SRCDIR"/instdir/program/soffice --userdir=file:///tmp/libreoffice/4 --file="$SRCDIR"/sc/qa/uitest/sort/sorting.py

    במקרה שהבדיקה קוראת ל־‚get_url_for_data_file’ (קבלת כתובת עבור קובץ נתונים) כדי לפתוח קובץ, יש לשנות את המשתנה TDOC בהתאם כך שיצביע לתיקייה בה נמצא הקובץ. בעת הפעלת הבדיקה עם מנשק המשתמש הגלוי ניתן לראות שהבדיקה מהירה מדי ואי אפשר לראות מה קורה. פתרון מהיר ומלוכלך לכך הוא להוסיף את הפונקציה time.sleep ב־Python שעוצרת את הפעולה לזמן קצר. המקומות האחרים הם uitest.debug.sleep. השיטה הזאת לא חלה אלמלא הבדיקה הופעלה במצב ניפוי שגיאות (debug) על ידי העברת המשתנה ‎--debug לבדיקה.

    כשעליך להריץ בדיקה אחת בקובץ סקריפט בדיקות, יש להפעיל את הפקודה הבאה:

    UITEST_TEST_NAME="FILENAME.CLASS_NAME.TEST_NAME" ./execute.sh

    למשל

    UITEST_TEST_NAME="sorting.CalcSorting.test_Sortingbuttons_detect_columnheaders" ./execute.sh


    פריטי מנשק משתמש שאינם נתמכים

    • תמיכה ב־Base
    • מסדר השקופיות ב־Impress
    • לחיצה כפולה בטפסים. לפרטים: https://bugs.documentfoundation.org/show_bug.cgi?id=133641
    • אשפי קבצים
    • Impress - ממזער המצגות
    • תיעוד ( LO_COLLECT_UIINFO) תחת Windows
    • לחיצה כפולה
    • תיעוד תרשימים
    • סרגל המידע התחתון ב־Calc
    • תמיכה טובה יותר בקיצורי דרך (tdf124931)

    רשימה של בדיקות מנשק משתמש ב־master

    ניתן לעיין ברשימת בדיקות מנשק המשתמש שכבר הוטמעו.

    איתור תקלות

    מילת המפתח needUITest בבאגזילה קיימת כדי לעקוב אחר כל התקלות שדורשות בדיקה אוטומטית עם UITest:

    מידע נוסף