Web UI自動化的設計和實踐

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"背景","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UI 自動化測試,即通過自動化的手段來控制機器模擬人進行手工操作。隨着 GrowingIO 業務的不斷髮展,新需求的不斷增加,迴歸測試的任務越來越重,現有測試的資源已經不足以應對繁重的迴歸測試任務,亟需 UI 自動化來代替人手工進行迴歸測試,解放回歸測試的人力去做更精準的測試。因此,引出下文在 GrowingIO 的Web UI 自動化的建設,本文主要就以下兩個方面展開介紹:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"框架搭建","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"集成質量平臺","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"框架搭建","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"PageObject","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"衆所周知,UI 自動化測試,是位於測試金字塔塔尖的位置,ROI 低。其痛點主要體現在:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.測試用例維護成本高,頁面元素定位方式或者佈局有一些細微的變動,之前寫好的代碼可能就有很大的改動;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.代碼冗餘,複用性低,可讀性不好。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"針對以上痛點,同時也通過大量調研,決定使用 PageObject 設計模式,其核心思想爲六大原則:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公共方法代表頁面提供的服務","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不要暴露頁面細節","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不要把斷言和操作細節混用","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方法可以 Return 到新的頁面","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不要把整頁內容都放到 PageObject 中","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相同的行爲產生不同的結果,可以封裝不同結果","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"依據以上六大原則,並結合 GrowingIO 具體業務的情況,目錄層級設計如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"BasePage 層","attrs":{}},{"type":"text","text":":封裝對網頁的一些基礎操作的方法,比如打開瀏覽器、查找元素、截屏等","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Component 層","attrs":{}},{"type":"text","text":":繼承 BasePage 層,封裝了對頁面中公共組件的操作方法,比如時間組件","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Page 層","attrs":{}},{"type":"text","text":":繼承Component層,該層中的每個方法都對應當前頁面的一個功能,方法裏可以調用Component 層中的方法或調用 BasePage 層中封裝的方法","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"TestCase 層","attrs":{}},{"type":"text","text":":調用業務 Page 層中封裝的方法,編寫業務 Case,並做斷言","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際項目的目錄分層如下:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n├── basepage\n│   └── base_page.py\n├── component\n│   └── element_design.py\n├── conf\n│   ├── conf.py\n├── datas\n├── log\n│   └── all.log\n├── log.py\n├── page\n│   ├── home_page.py\n│   ├── login_page.py\n│   ├── main_page.py\n│\n├── pytest.ini\n├── report\n│  \n├── requirements.txt\n├── run_all_cases.py\n├── testcase\n│   ├── conftest.py\n│   ├── testcase.py\n│\n└── util\n └── util.py","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Selenium + Python","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"語言選擇 Python,對於新人友好且組內人員比較熟悉,可以迅速上手;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前市場上的 Web UI 自動化測試方案百花齊放,基於底層技術的不同大體上分爲以下幾類:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.WebDriver Protocol 類:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如 Selenium 3,WebdriverIO,Protractor,Nightwatchjs","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.Proxy JS 注入類:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如 Selenium RC,TestCafe,Cypress","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3.DevTool Protocol 類:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如 Puppeteer, Playwright t","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們選擇使用 Selenium 3,優勢如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開源、免費","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多瀏覽器支持:Firefox、Chrome、IE、Opera、Edge","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多平臺支持:Linux、Windows、Mac","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多語言支持:Java、Python、Ruby、C#、JavaScript、C++","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對 Web 頁面有良好的支持","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"簡單(API 簡單,API:在類裏面封裝好的方法,即暴露給別人的一個可用的接口)、靈活(用開發語言驅動)、足夠穩定","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最主要的是 Selenium 的 Grid 方案即分佈式方案非常成熟,而所謂的分佈式就是由一個 Hub 節點和若干個 Node 代理節點組成。Hub 用來管理各個代理節點的註冊信息和狀態信息,並且接受遠程客戶端代碼的請求調用,然後把請求的命令轉發給代理節點來執行,最後再彙總各個代理節點的執行結果返回給遠程客戶端。無論是與 Jenkins 集成,還是對用例執行時間的要求,分佈式執行纔是 UI 自動化的最終態,這裏使用 docker-compose 來創建 Hub 和 Node 節點","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"docker-compose.yml 文件內容如下:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"version: '3'\n\nservices:\n hub:\n container_name: selenium-hub\n image: selenium/hub\n restart: always\n ports:\n - 4445:4444\n environment:\n HUB_HOST: hub\n health-timeout: 30\n SE_NODE_SESSION_TIMEOUT: 30000\n JAVA_OPTS: -Xmx1024m\n chrome:\n image: selenium/node-chrome-debug:3.141.59-20210311\n container_name: chrome_test\n restart: always\n depends_on:\n - hub\n ports:\n - 4446:5900\n volumes:\n - /etc/hosts:/etc/hosts\n - /dev/shm:/dev/shm\n environment:\n JAVA_OPTS: -Xmx512m\n HUB_HOST: hub\n NODE_MAX_SESSION: 5\n NODE_MAX_INSTANCES: 5\n firefox:\n image: selenium/node-firefox-debug:3.141.59-20210311\n container_name: firefox_test\n restart: always\n ports:\n - 4447:5900\n volumes:\n - /etc/hosts:/etc/hosts\n - /dev/shm:/dev/shm\n depends_on:\n - hub\n environment:\n - JAVA_OPTS=-Xmx512m\n - HUB_HOST=hub\n - NODE_MAX_SESSION=4\n - NODE_MAX_INSTANCES=4","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Grid 模式執行用例的流程圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/39/393634384fd5e691f856dfda11792f2e.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Pytest","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"管理和組織測試用例的框架選用 Pytest 框架,其優點如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"簡單靈活,容易上手,文檔豐富","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持參數化,可以細粒度地控制要測試的測試用例","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具有很多第三方插件,並且可以自定義擴展,比較好用的如allure-pytest(完美測試報告)、pytest-rerunfailures(失敗case重複執行)、pytest-xdist(多CPU分發)等","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以很好的和Jenkins結合","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"說到 Pytest 就不得不提其精髓:Fixture,Fixture 與傳統的測試框架的(Setup/Teardown)相比更加靈活:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有獨立的命名,並通過聲明它們從測試函數、模塊、類或整個項目中的使用來激活","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按模塊化的方式實現,每個 Fixture 都可以互相調用","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Fixture 的作用範圍靈活可配置,可以scope參數,指定Fixture的作用域:函數(Function),模塊(Module),類(Class),或整個項目(Session),執行順序爲:Session > Module > Class > Function","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本項目中大量使用了@pytest.fixtrue裝飾器來裝飾方法,被裝飾的方法名作爲一個參數傳入測試方法中,可以使用這種方式來完成測試之前的初始化,也可以返回數據庫給測試函數,尤其是跟conftest文件和yield搭配使用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"conftest.py","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"import pytest\nfrom selenium import webdriver\nfrom selenium.webdriver import DesiredCapabilities\n\[email protected](scope='session')\ndef init_driver():\n if browser == \"chrome\":\n driver = webdriver.Chrome()\n elif browser == 'firefox':\n driver = webdriver.Firefox()\n elif browser == 'safari':\n driver = webdriver.Safari()\n elif browser == 'remote':\n capabilities = DesiredCapabilities.CHROME\n driver = webdriver.Remote(command_executor='http://localhost:4445/wd/hub', desired_capabilities=capabilities)\n else:\n driver = ''\n print('瀏覽器類型暫不支持!!')\n driver_obj = OpBasePage(driver)\n yield init_driver.open_op_url().login_op_by_gui(username, password)\n # 關閉瀏覽器\n driver_obj.close_browser()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"test_dashboard.py","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\nclass TestDataBoard:\n @pytest.fixture()\n def board(self, init_driver):\n yield init_driver.jump_to_board_by_url()\n\n def test_board_sort(self, board):\n board.click_button_go_to_board_manage().check_board_sort()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從以上2個文件中可以看到,conftest.py 文件中方法名init_driver傳入了,test_dashboard.py 文件中的board方法中,board方法被@pytest.fixtrue裝飾器裝飾後,又傳入了test_board_sort測試方法,所以當運行測試方法test_board_sort時,程序執行順序爲","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/10/10e11cabeb4a6255afaa7c690e654c55.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Allure","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Allure 是一款輕量級並且非常靈活的開源測試報告框架。 它支持絕大多數測試框架, 例如 TestNG、Pytest、JUint 等。它簡單易用,易於與 Jenkins 集成,展示多次測試用例的趨勢情況。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Allure 裝飾器:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7c/7ca28ea1306dfd9a3532a73e70654593.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"測試用例中使用","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"import allure\nimport pytest\n\[email protected](\"distribute-analysis\")\nclass TestDistributionAnalysis:\n @pytest.fixture()\n def distribution_analysis(self, init_driver):\n yield init_driver.jump_to_distribution_analysis_by_url()\n\n @allure.story(\"check distribute analysis\")\n def test_analysis_success(self, distribution_analysis):\n with allure.step(\"create chart\"):\n distribution_name, save_toast, distribute_detail_analysis = distribution_analysis.click_button_to_create_distribute_analysis().create_distribution_analysis()\n distribution_list_name, distribute_analysis = distribute_detail_analysis.click_crumb_to_distribution_analysis().get_first_distribution_chart_name()\n assert distribution_name == distribution_list_name, '新建分佈分析單圖後未展示在列表頁'\n with allure.step(\"delete chart\"):\n distribute_analysis.delete_first_distribution_chart()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"測試報告樣例","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6f/6f919b67ba9b5ae0bfc492ecf6ea54b2.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"嵌入截圖的失敗用例樣例","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/93/9369221f74cf46f1468e8ae960ec31f2.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至此,Web UI 自動化框架(PageObject + Selenium + Pytest + Allure)搭建完成,框架整體的執行流程如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c7/c78bd5b182397432655a08f4efd7616b.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"集成質量平臺","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自動化框架搭建完成,但這僅僅是第一步,爲了便於跟蹤和驗證自動化發現的問題,又將自動化框架與自研的質量平臺進行集成,並與飛書和 Jira 打通,形成一個完整可追蹤的閉環流程,具體流程如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.在質量平臺的頁面上,選擇測試環境地址和項目 ID,然後點擊【啓動 Web UI 測試】按鈕,即在選定的測試環境和項目下,執行自動化用例","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.自動化用例執行完成,會發送飛書通知,並且自動爬取每一條失敗用例的數據,展示在質量平臺上","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3.測試人員檢查,剔除掉非bug的用例,勾選剩餘數據,點擊【提交 BUG 】按鈕,即自動在 Jira 上,批量創建 sub-bug 並指派給對應的開發人員","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4.當開發人員修改完成後,重複步驟1~3,直到測試用例全部通過","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"集成質量平臺後的流程圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/80/80a3041185d802b1f11d1d75d598e76e.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要介紹了 Web UI 自動化在 GrowingIO 的框架搭建和集成質量平臺兩大部分,整體的一個思路就是:首先,選擇合適的框架並落地,其次就是,自動化發現的問題,要及時跟蹤和驗證,讓整個流程形成一個完整的閉環。當然上文提到的 Web UI 自動化的搭建和集成質量平臺的整個流程,一定還存在諸多需要打磨的地方,希望大家不吝賜教。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8b/8b2c03af9069d21ab641c1a963844ee9.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章