<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          微信小程序自動化框架minium實踐

          共 8928字,需瀏覽 18分鐘

           ·

          2021-05-20 04:10

          一、背景需求

          精選小程序發(fā)生了一次線上問題,測試階段的小程序開發(fā)碼測試ok,但是小程序正式碼由于打包問題,"我的訂單"頁面文件打包失敗,導致線上用戶訪問我的頁面白屏。

          當前并不能避免該打包問題,為了規(guī)避異常版本發(fā)布至線上,需要在預發(fā)、體驗碼發(fā)布、正式碼發(fā)布等各階段進行主流程回歸。手動回歸測試非常耗時,在發(fā)布前的各階段,測試人員須重復執(zhí)行大量測試用例,以確保本次上線功能OK且對其他功能無影響。

          一遍又一遍執(zhí)行相同的測試用例,不僅要花費更多的時間,而且還會降低整體測試效率,因此引入微信小程序自動化以解放重復人力。

          二、調研

          1.Jest+小程序SDK

          優(yōu)點:

          • 小程序自動化 SDK 為開發(fā)者提供了一套通過外部腳本操控小程序的方案,從而實現(xiàn)小程序自動化測試的目的,小程序自動化 SDK 本身不提供測試框架。這意味著你可以將它與市面上流行的任意 Node.js 測試框架結合使用;

          • jest 是facebook推出的一款測試框架,集成了 Mocha,chai,jsdom,覆蓋率報告等開發(fā)者所需要的所有測試工具,是一款幾乎零配置的測試框架;

          缺點:

          • 語言僅支持JavaScript 編寫;

          • 使用中遇到問題,網(wǎng)上相關資料比較少;

          2.minium框架

          優(yōu)點:

          • 微信小程序官方推出的小程序自動化框架,是為小程序專門開發(fā)的自動化框架, 提供了 Python 和 JavaScript 版本。

          • 支持一套腳本,iOS & Android & 模擬器,三端運行

          • 提供豐富的頁面跳轉方式,看不到也能去得到

          • 可以獲取和設置小程序頁面數(shù)據(jù),讓測試不止點點點

          • 支持往 AppSerive 注入代碼片段

          • 可以使用 minium 來進行函數(shù)的 mock, 可以直接跳轉到小程序某個頁面并設置頁面數(shù)據(jù), 做針對性的全面測試

          缺點:

          • 暫不支持H5頁面的調試;

          • 暫不支持插件內wx接口調用;

          3.選型

          精選小程序主要是原生頁面,minium和Jest均能滿足需求。minium支持Python 和 JavaScript 版本,而且有專門的團隊定期維護,遇到問題可以在微信開發(fā)者社區(qū)進行提問,因此選擇了minium。

          三、minium介紹

          minium提供一個基于unittest封裝好的測試框架,利用這個簡單的框架對小程序測試可以起到事半功倍的效果。

          測試基類Minitest會根據(jù)測試配置進行測試,minitest向上繼承了unittest.TestCase,并做了以下改動:

          1. 加載讀取測試配置

          2. 在合適的時機初始化minium.Minium、minium.App和minium.Native

          3. 根據(jù)配置打開IDE,拉起小程序項目和或自動打開真機調試

          4. 攔截assert調用,記錄檢驗結果

          5. 記錄運行時數(shù)據(jù)和截圖,用于測試報告生成

          使用MiniTest可以大大降低小程序測試成本。

          Properties:

          名稱類型默認值說明
          appminium.AppNoneApp實例,可直接調用minium.App中的方法
          miniminium.MiniumNoneMinium實例,可直接調用minium.Minium中的方法
          nativeminium.NativeNoneNative實例,可直接調用minium.Native中的方法

          代碼示例:

          #!/usr/bin/env python3
          import minium
          class FirstTest(minium.MiniTest):
          def test_get_system_info(self):
          sys_info = self.mini.get_system_info()
          self.assertIn("SDKVersion", sys_info)

          四、環(huán)境搭建

          • 安裝minium-doc,這個是小程序安裝和使用的文檔介紹,或者不用自己本地安裝直接訪問官方文檔

          • 安裝python 3.8及以上

          • 安裝微信開發(fā)者工具(我本機使用的版本是1.05.2103200),并打開安全模式: 設置 -> 安全設置 -> 服務端口: 打開

          • 在工具欄菜單中點擊設置,選擇項目設置,切換到“本地設置”,將調試基礎庫選擇大于2.7.3的庫; 

          • 下載minium安裝包并安裝,地址參考官網(wǎng)

          安裝命令:pip3 install minium-latest.zip 或者python3 setup.py install
          • 安裝完成后,可執(zhí)行以下命令查看版本:

          minitest -v
          • 開啟微信工具安全設置中的 CLI/HTTP (提供了命令行和HTTP兩種調用方式)調用功能。在開發(fā)者工具的設置 -> 安全設置中開啟服務端口。 

          • 開啟微信工具安全設置中的 CLI/HTTP (提供了命令行和HTTP兩種調用方式)調用功能。在開發(fā)者工具的設置 -> 安全設置中開啟服務端口。

          • 開啟被測試項目的自動化端口號

          "path/to/cli" auto --project "path/to/project" --auto-port 9420

          默認的命令行工具所在位置:

          macOS: <安裝路徑>/Contents/MacOS/cli
          Windows: <安裝路徑>/cli.bat

          五、小程序腳本編寫

          思路:使用Page Object 架構,使系統(tǒng)架構分層,每一個頁面設計為一個Class,包含了頁面需要測試的元素,測試用例只要關心測試的數(shù)據(jù)即可;

          1.目錄結構

          • cases/: 存放測試腳本和用例

          • case/base/:頁面公共方法

          • case/pages/:頁面對象模型

          • outputs/:測試報告

          • test/:測試腳本

          • route.py:小程序頁面操作的路徑

          2.自動化腳本

          BasePage是頁面基類,封裝所有頁面會用到的公用方法

          class BasePage:
          def __init__(self, mini):
          self.mini = mini

          def navigate_to_open(self, route):
          """以導航的方式跳轉到指定頁面,不允許跳轉到 tabbar 頁面,支持相對路徑和絕對路徑, 小程序中頁面棧最多十層"""
          self.mini.app.navigate_to(route)

          def redirect_to_open(self, route):
          """關閉當前頁面,重定向到應用內的某個頁面,不允許跳轉到 tabbar 頁面"""
          self.mini.app.redirect_to(route)

          def switch_tab_open(self, route):
          """跳轉到 tabBar 頁面,會關閉其他所有非 tabBar 頁面"""
          self.mini.app.switch_tab(route)

          @property
          def current_title(self) -> str:
          """獲取當前頁面 head title, 具體項目具體分析,以下代碼僅用于演示"""
          return self.mini.page.get_element("XXXXXX").inner_text

          def current_path(self) -> str:
          """獲取當前頁面route"""
          return self.mini.page.path

          HomePage是要測試的精選首頁頁面

          from case.base.basepage import BasePage
          from case.base import route


          class HomePage(BasePage):
          """小程序首頁公共方法"""

          locators = {
          "BASE_ELEMENT": "view",
          "BASE_BANNER": "首頁banner元素選擇器XXX"
          }
          # 首頁點擊官方補貼的"更多"按鈕
          subsidy_more_button = ("跳轉頁面的元素選擇器XXX", "更多")

          """
          校驗頁面路徑
          """
          def check_homepage_path(self):
          self.mini.assertEqual(self.current_path(), route.homepage_route)
          """
          校驗頁面的基本元素
          """
          def check_homepage_base_element(self):
          # 校驗頁面是否包含view元素
          self.mini.assertTrue(self.mini.page.element_is_exists(HomePage.locators['BASE_ELEMENT']))
          # 校驗頁面banner位置
          self.mini.assertTrue(self.mini.page.element_is_exists(HomePage.locators['BASE_BANNER']))
          """
          獲取官方補貼,點擊"更多"按鈕跳轉
          """
          def get_subsidy_element(self):
          self.mini.page.get_element(str(self.subsidy_more_button[0]),
          inner_text=str(self.subsidy_more_button[1])).click()

          BaseCase是測試用例基類,用于設置用例輸出路徑和清理工作,項目的測試用例都繼承此類

          from pathlib import Path

          import minium


          class BaseCase(minium.MiniTest):
          """測試用例基類"""

          @classmethod
          def setUpClass(cls):
          super(BaseCase, cls).setUpClass()
          output_dir = Path(cls.CONFIG.outputs)
          if not output_dir.is_dir():
          output_dir.mkdir()

          @classmethod
          def tearDownClass(cls):
          super(BaseCase, cls).tearDownClass()
          cls.app.go_home()

          def setUp(self):
          super(BaseCase, self).setUp()

          def tearDown(self):
          super(BaseCase, self).tearDown()

          3.元素定位的方法

          minium 通過 WXSS 選擇器來定位元素的,目前小程序僅支持以下的選擇器:

          參考例子:

          <view id="main" class="page-section page-section-gap" style="text-align: center;"></view>

          假如要查找像上面這一個元素的話,他的選擇器會像是下面這樣:

          tageName + #id + .className

          view#main.page-section.page-section-gap
          • tagName :類型選擇器,標簽名稱,view、checkbox 等等,選擇所有指定類型的最簡單方式。

          • id:ID 選擇器,自定義給元素的唯一 ID,使用時前面跟著 # 號,這是選擇單個元素的最有效的方式。

          • className:類選擇器,由一個點.以及類后面的類名組成,存在多個類的時候可以以點為間隔一直拼接下

          4.編寫精選首頁的測試用例

          被測試的有贊精選小程序首頁如下圖:

           HomePageTest

          # coding=utf-8


          from case.base import loader
          from case.base.basecase import BaseCase
          from case.pages.homepage import HomePage

          """
          小程序首頁測試
          """


          class HomePageTest(BaseCase):
          def __init__(self, methodName='runTest'):
          super(HomePageTest, self).__init__(methodName)
          self.homePage = HomePage(self)

          """
          case1:測試首頁的跳轉路徑是否正確,跳轉路徑要使用絕對路徑,小程序默認進入就是首頁,所以不用再切換進入的路徑
          """

          def test_01_home_page_path(self):
          self.homePage.check_homepage_path()

          """
          case2:頁面的基本元素是否存在
          """

          def test_02_page_base_element(self):
          self.homePage.check_homepage_base_element()


          """
          case3:檢查首頁的"官方補貼"模塊存在
          """

          def test_03_live_sale(self):
          self.assertTexts(["官方補貼"], "view")
          self.assertTexts(["輕松賺回早餐錢"], "view")


          """
          case4:從首頁點擊"更多"跳轉到直播特賣頁面,頁面包含"推薦"模塊
          """

          def test_04_open_live_sale(self):
          # 點擊首頁的"更多"按鈕的元素
          self.homePage.get_subsidy_element()
          self.page.wait_for(2)
          result = self.page.wait_for("頁面元素選擇器xxx") # 等待頁面渲染完成
          if result:
          category = self.page.data['categoryList']
          self.assertEquals("美食", category[0]['title'], "接口返回值包含美食模塊")
          self.assertEquals("美妝", category[1]['title'], "接口返回值包含美妝模塊")
          self.page.wait_for(2)
          self.app.go_home()


          if __name__ == "__main__":
          loader.run(module="case.homepage_test", config="../config.json", generate_report=True)

          5.編輯配置文件config.json

          {
          "project_path": "XXXXX",
          "dev_tool_path": "/Applications/wechatwebdevtools.app/Contents/MacOS/cli",
          "debug_mode": "debug",
          "test_port": 9420,
          "platform": "ide",
          "app": "wx",
          "assert_capture": false,
          "request_timeout":60,
          "remote_connect_timeout": 300,
          "auto_relaunch": true
          }

          6.minitest 命令行

          minium安裝時執(zhí)行的setup.py文件,指定了minitest命令運行的方法入口為:minium.framework.loader:main  loader.py文件解釋了運行的命令行的含義 

          • -h, --help: 使用幫助。

          • -v, --version: 查看 minium 的版本。

          • -p PATH/--path PATH: 用例所在的文件夾,默認當前路徑。

          • -m MODULE_PATH, --module MODULE_PATH: 用例的包名或者文件名

          • --case CASE_NAME: test_開頭的用例名

          • -s SUITE, --suite SUITE:測試計劃文件

          • -c CONFIG, --config CONFIG:配置文件名,配置項目參考配置文件

          • -g, --generate: 生成網(wǎng)頁測試報告

          • --module_search_path [SYS_PATH_LIST [SYS_PATH_LIST ...]]: 添加 module 的搜索路徑

          • -a, --accounts: 查看開發(fā)者工具當前登錄的多賬號, 需要通過 9420 端口,以自動化模式打開開發(fā)者工具

          • --mode RUN_MODE: 選擇以parallel(并行)或者fork(復刻)的方式運行用例

          7.suite測試計劃文件

          {
          "pkg_list": [
          {
          "case_list": [
          "test_*"
          ],
          "pkg": "case.*_test"
          }
          ]
          }

          suite.json的pkglist字段說明要執(zhí)行用例的內容和順序,pkglist 是一個數(shù)組,每個數(shù)組元素是一個匹配規(guī)則,會根據(jù)pkg去匹配包名,找到測試類,然后再根據(jù)case_list里面的規(guī)則去查找測試類的測試用例。可以根據(jù)需要編寫匹配的粒度。注意匹配規(guī)則不是正則表達式,而是通配符。

          8.命令行運行腳本

          minitest -m case.homepage_test --case test_07_open_live_sale -c config.json -g #運行執(zhí)行class文件中的指定用例test_07_open_live_sale

          minitest -s suite.json -c config.json -g #按照suite配置去執(zhí)行用例

          9.生成測試報告

          生成報告之后,在對應的目錄下面有index.html文件,但是我們不能直接用瀏覽器打開這個 文件,需要把這個目錄放到一個靜態(tài)服務器上

          測試結果存儲在outputs下,運行命令python3 -m http.server 12345 -d outputs然后在瀏覽器上訪問http://localhost:12345即可查看報告

          六、遇到的問題

          1.需要開啟被測試小程序應用的自動化測試端口9420  開啟被測試工程的自動化端口

          "path/to/cli" auto --project "path/to/project" --auto-port 9420

          2.打開微信開發(fā)者工具超時  微信開發(fā)者工具:設置-代理設置,關閉ide的代理  3.連接開發(fā)者工具后報錯 

          原因:可能是微信開發(fā)者工具和minium的版本不一致;
          我測試使用ok的匹配版本為:
          Minium版本:1.0.5
          開發(fā)者工具版本:1.05.2102010
          python版本:3.8.8

          4.出現(xiàn)以下報錯,可能是登陸的開發(fā)者工具的賬號,沒有被測試小程序的開發(fā)者權限;  5.運行過程中,發(fā)現(xiàn)調用截圖的方法比較耗時,但是在config文件設置了"assert_capture": false,配置沒生效,仍然會去調用截圖的方法;  ps:猜測是一個bug,然后給微信社區(qū)留言了,最新版本1.0.6修復了這個問題 原因:是框架的minitest.py文件調用setup和TearDown方法的時候,沒有判斷配置文件"assert_capture": false這個條件  可以修改minitest.py文件,增加配置文件的判斷條件,修改如下:

          if self.test_config.assert_capture:

          self.capture("setup")

          6.命令行執(zhí)行的時候加了-p xxx參數(shù),運行時報引入的包不存在  原因:命令行運行時默認是當前路徑,加-p xxx, 這樣會導致腳本運行的PYTHONPATH變了(不是當前目錄了),這樣會導致包不存在  解決方法:

          • 命令行運行的時候,用-m 指定運行的包路徑,不用-p

          • 把-p xxx用到的路徑都加入到PYTHONPATH中

          七、參考資料

          1. 微信官方文檔

          2. 簡書上Rethink的相關文章介紹


          end


          ??
          ?
          瀏覽 100
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰成人一区二区三区 | 亚洲欧美性色图 | 男女动态拍拍片 | 无码无码一区二区三区 | 欧美三级精品网站 |