برنامه‌نویسی/آزمون رابط گرافیکی

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

    این مستندات اولیه برای چارچوب آزمون رابط گرافیکی با تمرکز ویژه بر پایتون است.

    معماری

    تست رابط گرافیکی از دو بخش تشکیل شده است، یک قطعه ++C که رابط کاربری لیبره آفیس را در یک کتابخانه درون‌نگری قرار می‌دهد و یک چارچوب پایتون با کد آزمایش واقعی. ارتباط بین دو بخش از طریق یک رابط UNO ساده و عمدتاً بدون نوع انجام می‌شود.

    کتابخانه درون‌نگری ++C

    کتابخانه درون‌نگری ++C از یک رابط برنامه‌نویسی UNO تشکیل می‌شود که برای ارتباط با بخش پایتون چارچوب و لفافه‌های بسیاری از اشیاء رابط گرافیکی استفاده می‌شود. رابط UNO تنها چند تابع دارد و بیشتر ارتباطات از طریق پارامترهای رشته‌ای انجام می‌شود.

    لفافه برای اشیاء رابط گرافیکی تقریباً همان تابع‌های رابط UNO را به علاوه برخی از تابع‌های کمکی ارائه می‌دهد.

    چارچوب پایتون

    نوشتن آزمون

    ارائه سیسکو فائولی از FOSDEM 2021، LibreOffice QA - نحوه نوشتن اولین آزمون خود، روند ایجاد آزمون‌ها را طی می‌کند.

    ارائه سیسکو از FOSDEM 2022 چیزهایی که می‌توانید در UITest مورد آزمون قرار دهید را نشان می‌دهد.

    بخش Makefile

    یک فایل ساخت ساده برای آزمایش رابط کاربری شبیه به پرونده نمایشی است. بخش مهم این است که از کلاس آزمون رابط گرافیکی gbuild استفاده کنید و اجازه دهید "gb_UITest_add_module" به دایرکتوری‌های دارای پرونده‌های آزمایشی اشاره کند.

    به طور معمول هیچ چیز دیگری مورد نیاز نیست و بیشتر کار در کلاس gbuild UITest مدیریت می‌شود.

    $(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 در نمایه کاربر کپی می‌شود و آزمایش با این تنظیمات اجرا می‌شود.

    نوشتن کد پایتون

    زیرساخت

    دستورات موجود در عناصر رابط کاربری

    عمومی

    مدیریت وضعیت اشیاء رابط کاربری

    این تابع برای به دست آوردن وضعیت شیء رابط گرافیکی توسط تمام عناصر رابط گرافیکی ارائه می‌شود. این تابع، وضعیت را به عنوان دنباله‌ای از PropertyValue ها برمی‌گرداند.

    ui_element.getState()

    چارچوب آزمون رابط گرافیکی تابعی را برای تبدیل دنباله برگردانده شده PropertyValue به dictionary پایتون ارائه می‌دهد.

    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"}))

    کنترل عملیات

    کنترل کد Assert
    دکمه

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

    ---

    TextBox

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

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

    CheckBox

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

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

    Charmap Widget

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

    ---

    TreeList

    # باز کردن یا بستن درخت
    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")

    فهرست (بر اساس موقعیت)

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

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

    فهرست (بر اساس نام)

    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")

    Tabdialog (بر اساس نام)

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

    ---

    Spinfield

    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 ارسال شود و کدام عمل روی یک شی UI فراخوانی شود. خوشبختانه امکان وقایع‌نگاری دستورات UNO وجود دارد.

    1. از این خط‌ها در bashrc. یا cshrc. استفاده کنید:
      export PYTHONPATH=/"<span lang="en" dir="ltr" class="mw-content-ltr">Path of LibreOffice repo</span>"/instdir/program/
      export URE_BOOTSTRAP=file:///"Path of LibreOffice repo"/instdir/program/fundamentalrc
    2. لیبره آفیس را با این اجرا کنید
      LO_COLLECT_UIINFO="test.log" SAL_USE_VCLPLUGIN=gen instdir/program/soffice
      Note: "LO_COLLECT_UIINFO" is a relative path under "instdir/uitest/".
    3. کاری را که می‌خواهید با ماوس انجام دهید شبیه‌سازی کنید
    4. لیبره آفیس را ببندید
    5. پرونده حاصل را از instdir/uitest/test.log باز کنید
    6. پوشه وقایع‌نگاری رابط کاربری را با این دستور وارد کنید:
      cd uitest/ui_logger_dsl/
    7. # مطمئن شوید که پایتون شما textX library را نصب دارد
    8. از دستور زیر استفاده کنید
    9. Use the following command
      python dsl_core.py <path_to_log_file> <path_to_a_new_python_file>
      متن <path_to_log_file> باید با چیزی مانند SourceDirectory/core/instdir/uitest/test.log جایگزین شود و <path_to_a_new_python_file> می‌تواند مکانی به انتخاب شما باشد که می‌خواهید کد تولید شده را ببینید.

    شما می توانید تمام مراحل زیر را در این ویدیوی یوتیوب دنبال کنید:

    Please accept this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.

    YouTube privacy policy


    اجرای آزمون

    قبل از این‌که آزمون را به شاخه master ارسال کنیم، باید به وضوح بررسی کنیم که آزمون کار می‌کند. یک راه ساده این است که تمام آزمون‌های رابط گرافیکی را در ماژول uitest از طریق make uitest.uicheck اجرا کنید. با این وجود، ما می‌خواهیم رابط گرافیکی را در حین انجام آزمایش ببینیم و آزمون‌ها به طور پیش‌فرض به صورت بدون رابط گرافیکی (headless) اجرا شوند. این با اجرای موارد زیر در پوشه اصلی به دست می‌آید:

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

    همچنین می‌توان از یک «اسکریپت پوسته»» برای شروع آزمایش استفاده کرد.

    توجه داشته باشید که باید این اسکریپت را از دایرکتوری منبع هسته لیبره آفیس اجرا کنید.

    همچنین ممکن است برای راه انداختن آن به چند متغیر محیطی نیاز داشته باشید، بنابراین اسکریپت کامل به این صورت خواهد بود:

    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 پایتون است که اجرا را برای مدتی متوقف می‌کند. راه حل دیگری که واقعاً می‌توانید در کد بگذارید (فقط چند مورد مفید را در یک آزمون باقی بگذارید) در مکان های جالب uitest.debug.sleep است. این تابع نادیده گرفته می‌شود مگر این‌که آزمون در حالت اشکال‌زدایی با ارسال پارامتر debug-- به آزمون شروع شود.

    هنگامی که نیاز به اجرای تنها یک آزمون در پرونده اسکریپت آزمون دارید، دستور زیر را اجرا کنید:

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

    برای مثال

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


    اقلام رابط کاربری پشتیبانی نشده

    • پشتیبانی پایه
    • مرتب‌سازی اسلاید در ارائه
    • دوبار کلیک روی فرم‌ها. برای الهام گرفتن به tdf#133641 مراجعه کنید
    • فایل -ساحره‌ها
    • ارائه - حداقل کننده ارائه
    • وقایع‌نگاری (LO_COLLECT_UIINFO) در ویندوز
    • دوبار کلیک
    • وقایع‌نگاری نمودارها
    • نوار ابزار اطلاعات پایین در صفحه گسترده
    • پشتیبانی بهتر از میانبرها (tdf#124931)

    فهرست آزمون‌های رابط کاربری در master

    می‌توانید فهرست آزمون‌های رابط گرافیکی قبلاً پیاده‌سازی شده را بررسی کنید.

    پیدا کردن اشکالات

    ما کلمه کلیدی needUITest را در باگزیلا برای ردیابی همه اشکالاتی داریم که به آزمون رابط گرافیکی برای آزمایش خودکار آن نیاز دارند:

    اطلاعات بیشتر