立博APP

<code id="choey"><ol id="choey"><span id="choey"></span></ol></code>
    1. <var id="choey"></var>

        <code id="choey"></code>
      1. <output id="choey"><legend id="choey"></legend></output>

          <label id="choey"><legend id="choey"></legend></label>
        1. <code id="choey"></code>
          <var id="choey"><ol id="choey"><big id="choey"></big></ol></var>
          全國免費咨詢電話: 010-59418061
          關注尚腦
          項目自動化測試體系
           
             從事測試行業的同志們對自動化測試都抱有一個美好的幻想,那該怎么實現自動化測試呢?
            首先要了解自動化測試金字塔
            說起自動化測試不得不提及測試金字塔,這種三角形的結構主要為我們展示了一個健康的自動化測試體系應該是什么樣子的。如圖所示,金字塔的從上往下依次是UI測試,接口測試,單元測試, 越在高層影響就越大,花費的時間和精力就越多。圖示的測試金字塔只是一種形態示例,不同項目的金字塔的實現內容可能略有區別。
           軟件測試培訓
            其次分層實現
            如何實現UI層的自動化測試
            在測試金字塔中可以看到,UI層面的自動化影響大、變化多、可維護成本高,所占比例也最少。所以在我們看來,UI層面的自動化應該是一些從高層次上驗證一些happy pass,確保我們的核心功能可用。
            Scenario: test office filter in China region
            Given I login to GoHire website
            When I select "China" region
            And I select "Chengdu" option
            Then I can only see all the application cards in chengdu office
            UI層自動化的小經驗
            UI層自動化的適用場景是做核心功能的回歸測試和冒煙測試,所以在實施過程中,要注意不要把所有的用例都堆砌在UI層,而是盡可能放到接口測試和單元測試中去做。
            在代碼層面,我們可以遵循page object的設計模式,避免在測試代碼中直接操作html元素。這樣就可以減少重復的代碼并提高代碼的可維護性。
            如何實現接口層的自動化測試
            在案例項目中,接口測試主要分為兩個部分。
            在開發過程中,測試人員會和開發合作去寫接口的功能測試。
            在整個功能大概完成,API已經基本確定后,測試和開發一起結對寫性能測試。
            接口功能測試
            在寫功能測試的過程中,我們可能會和一些其他的模塊或第三方API有依賴,在這種情況下,通??梢酝ㄟ^Mock的方法去解決。
            如案例項目中有一個測試場景是:調用一個第三方的API,當這個API出錯時,需要接受到API返回的錯誤碼并對錯誤碼進行處理。在實現測試的時候,我們沒有辦法讓第三方API真正的掛掉并返回錯誤碼,所以我們只需要模擬這個請求出錯,驗證我們代碼已經對這種錯誤進行過處理。
            def should_return_error_message_when_request_failed(self):
            event = {
            "body": {
            "action": "update_candidate",
            "payload": {
            "candidate": {
            "id": 101
            }
            }
            }
            }
            with requests_mock.mock() as request_mock:
            request_mock.get("http://api.gh.test/v1/candidates/101", text='', status_code=500)
            with self.assertRaises(Exception) as context:
            webhook.handle(event)
            self.assertTrue(
            '[request error][update_candidate] get candidate 101 from Harvest API failed' in context.exception)
            接口性能測試
            在功能大致完成后,我們開始做API的性能測試。性能測試在這里的作用主要是獲取我們API現有的性能指標,形成一個對比的基線。在便于進行后期的優化的同時也有可能幫助我們發現一些潛在的bug。
            小故事:我們在手工測試API的響應速度時,測試結果一切正常。當引入性能測試后就發現,這些接口在前期的響應時間確實很快,可是在請求了一定次數后會突然變得很慢。經過調查我們發現,這是因為我們依賴了一個AWS的服務,這個服務有訪問頻率的限制,在最初的代碼中,每次訪問都會請求這些服務并讀取這些服務的配置,這也就導致了測試發現的問題。后來我們更改了方案,把讀取配置這個操作放在系統初始化的時候去做,順利的解決了這個問題。
            性能測試我們主要選用了Locust這個框架。如我們的一個接口功能是:查詢某個國家下的所有的候選人。 下面代碼用例的意思就是, 同時配置50個客戶端去訪問API,每次隨機請求某個國家的所有候選人信息,一共請求1000次,規定每次請求的時間最大不超過5s。
           def get_applications_in_country(l):
            text = """Australia Brasil Canada China Chile Ecuador Germany India Italy Singapore Spain Turkey UK USA Uganda Thailand"""
            countries = text.strip().split()
            country = random.choice(countries)
            params = {
            "country": country,
            "status": "active"
            }
            with l.client.get("/getCandidates", params=params, headers={"x-api-key": API_KEY}, catch_response=True) as response:
            if "errorMessage" in response.text:
            response.failure("Error occurs in response: %s" % response.text)
            class UserBehavior(TaskSet):
            tasks = {
            get_applications_in_country: 1
            }
            
          function runLocustDataStoreService {
            validateEnvironment "HOST" "API_KEY"
            setupEnv
            CLIENTS=${CLIENTS:-"50"}
            HATCH_RATE=${HATCH_RATE:-"2"}
            NUM_REQUEST=${NUM_REQUEST:-"1000"}
            locust -f DataStoreService/locustfile.py --host ${HOST} --clients=${CLIENTS} --hatch-rate=${HATCH_RATE} --num-request=${NUM_REQUEST} --no-web --only-summary
            }
            通過Locust跑完用例,我們可以看到在console生成的report:
          軟件測試培訓
            圖片展示的是report的一部分,reqs代表對這個API的請求數目,fails記錄了失敗的次數,Avg、Min、Max、Mediam分別是每次請求響應時間的平均值、最小值、最大值和中位數。
            如何實施單元測試級別的自動化
            單元測試是對軟件中最小的測試單元進行驗證,在這一層上發現問題時解決成本最低,測試用例的維護成本也不高,具有很好的投入產出比。一般情況下,我們是需要開發人員在開發過程中寫單元測試。而作為一個QA,我們更多的是一個單元測試的引導者:
            和團隊一起制定單元測試覆蓋率的標準。
            如果這是一個全新的項目,我們可以把覆蓋率設的相對高一點,如85%,這有利于我們在前期就對代碼質量做出保證。如果這是一個已經相對成熟的項目,由于前期根本沒有單元測試,我們可以先把要求設置的低一點,然后一步步的提升我們的代碼覆蓋率。
            為開發人員提供單元測試的用例。
            我們需要提前把需要驗證的用例列在開發的任務卡片里面,這樣能幫助開發更有效率的去完成我們期望測試的用例 。
            定期回顧開發人員寫的單元測試。
            這里并不是要檢查代碼和具體實現,而是和開發一起去回顧看看單元測試的寫法和角度是不是在同一認知上面。這樣有助于整個團隊建立一種質量保證的意識。
            在具體實現上,我們選擇nose test這個工具去做單元測試,通過nose test的插件,我們可以拿到單元測試覆蓋率的報表,在第二個圖中,我們可以看到,沒有被測試覆蓋的代碼會有紅色的標記,這樣就有利于我們找到測試的遺漏點。
          軟件測試培訓
            在寫單元測試時,為了解決對數據庫的依賴,我們可以建立一個內存數據庫去模擬真實數據庫,便于我們的測試用例能快速的運行。如在我們的真實項目中,我們的數據庫選用的是亞馬遜的RDS+Postgres,但是在做單元測試的時候我們使用的sqlite+python綁定來模擬真實的數據庫。
            三、做完自動化測試之后還可以做什么
            只讓這些自動化測試運行在本地IDE上是不夠的,在我們的項目中,我們建立了一套持續集成部署的體系:
            推送到代碼到遠端后會自動開始運行自動化測試和代碼審查。
            當單元測試通過后會自動部署到測試環境。
            在部署完成后會自動生成測試報告。
            小組所有成員會收到部署成功或失敗的郵件提醒。
          軟件測試培訓
            enter image description here
            在工具的選擇上,我們的持續集成平臺是ThoughtWorks的GoCD,其他類似的工具還有 jenkins,可以靈活的選用這些工具。
            四、總結
            在實際的項目實施過程中,我們其實是按照下面的步驟依次逐步實施我們的持續集成自動化體系的:
            在項目開始之前首先搭建持續集成的框架,第一次的時候先寫一個最簡單的單元測試,如1+1=2,確??梢栽贑I上運行測試,為后續的開發奠定基礎。
            開發在項目實現過程中進行單元測試,每次開發推送代碼時都可以自動運行單元測試和代碼風格審查,當單元測試覆蓋低于85%或代碼風格檢查不通過時,構建就會失敗。
            測試和開發在項目實現過程中合作寫接口層的功能測試。
            功能開發大體完成后,測試和開發合作寫接口的性能測試。
            當項目發布之后,測試開始根據核心功能編寫UI層面的自動化測試,也相當于是寫項目的回歸測試。
            最后談一點心得體會吧:
            項目只有UI自動化測試是不夠的,越低層的自動化測試反而越有意義。
            自動化測試的目的是減少重復的手動測試的成本,使測試人員可以做更多有意義的事情,在實現自動化的過程中,我們花費的精力甚至更多。
            測試并不是越多越好,除了用例數量還要考慮維護代價。我們希望測試代碼能夠盡量穩定,因為代碼需要不斷的被重構,如果發現重構一次代碼就修改很多測試,那么這種測試可能會成為負擔,也是一種壞味道。
            測試人員在自動化測試落地的實踐中,更多的是一個推動者而不是實現者,我們需要幫助團隊建立起一種質量保證的意識,然后共同實現自動化測試的落地。
          ?
          尚腦教育隸屬于(北京尚腦互聯科技有限公司)    版權所有       京ICP備15029150號-2
          友情鏈接: 北京APP開發 | xp純凈版系統下載 | 廣州網站建設 | 廣州拓展訓練 | 數字圖書館系統 | 醫廢監管系統平臺 | 北京網站建設 | 騰訊企業郵箱 | 微信刷粉絲 | 信陽網站建設 | VR外包 | 展會互動 | 深圳網絡營銷 | 微信恢復 |
          岳普湖| 济源| 平远| 大悟| 定边| 泸溪| 迁安| 龙游| 吉林| 鱼台| 鹤峰| 十堰| 崇庆| 鄱阳| 自贡| 颍上| 潜江| 万全| 林甸| 遂川| 河南| 龙门| 博山| 桑植| 秦皇岛| 武义| 寻甸| 佛冈| 迁安| 敦煌| 兰州| 沛县| 富阳| 察隅| 乾县| 根河| 临朐| 太原古交区| 三门| 野牛沟| 富裕| 宁德| 普兰店| 中卫| 曹妃甸| 塔城| 三门| 盐都| 睢县| 海晏| 临夏| 颍上| 封丘| 灵邱| 汕尾| 彭阳| 伊金霍洛旗| 阜阳| 白日乌拉| 武川| 山南| 贵定| 太华山| 普格| 斋堂| 衡阳县| 淮北| 潜山| 铁干里克| 惠农| 澄城| 靖西| 寻乌| 达尔罕茂明安联合旗| 永登| 永川| 广宗| 黎城| 香河| 千里岩| 科尔沁左翼中旗| 河曲| 苏尼特右旗| 察哈尔右翼中旗| 扎鲁特旗| 青冈| 连云港| 德昌| 灵邱| 亳州| 大佘太| 正定| 朝城| 德令哈| 夏津| 和田| 呼图壁| 柳河| 双城| 龙南| 惠农| 安康| 郫县| 拉萨| 鄂温克旗| 沽源| 阳江| 卢龙| 靖江| 龙陵| 东丽| 运城| 霸州| 开原| 宽城| 丹东| 晋宁| 西连岛| 新城子| 乌什| 秀山| 黄冈| 引水船| 保德| 株洲县| 平潭| 澄海| 元阳| 番禺| 弋阳| 稻城| 贵溪| 舟曲| 南和| 丹巴| 一八五团| 五莲| 上海| 桐柏| 新林| 吐鲁番东坎| 康山| 围场| 昌邑| 武威| 南乐| 永兴| 恩平| 华宁| 黎川| 昆山| 宣化| 顺德| 杭州| 横山| 屏山| 安塞| 石首| 青龙山| 旅顺| 郯城| 一八五团| 安图| 西丰| 肥乡| 固安| 雄县| 南汇| 册亨| 鹤壁| 策勒| 土默特左旗| 沅江| 滨州| 沙县| 霍林郭勒| 涪陵| 旬邑| 黄山市| 邓州| 安义| 叙永| 达川| 庐江| 高邮| 临朐| 藁城| 澳门| 横峰| 鄂伦春旗| 宝清| 上虞| 澜沧| 左贡| 泸西| 呼兰| 万全| 济宁| 石泉| 炮台| 莒县| 昌黎| 隆尧| 科尔沁左翼后旗| 龙井| 湛江| 临潭| 阿木尔| 乐亭| 来安| 察哈尔右翼前旗| 平湖| 大兴| 饶阳| 布尔津| 白水| 日喀则| 金山| 梅河口| 陇西| 阿克苏| 武胜| 丰县| 霍州| 潮州| 张掖| 锡林高勒| 克东| 天门| 富川| 西安| 邵阳县| 惠农| 兴义| 上林| 绥芬河| 福清| 修文| 九仙山| 伊通| 华宁| 浦江| 北道区| 星子| 阿合奇| 海晏| 香港| 海安| 满城| 丰县| 博白| 沈阳| 莱州| 瓜州| 内黄| 南通| 茫崖| 洛川| 彬县| 徐家汇| 三原| 房山| 沛县| 赵县| 仙游| 头道湖| 迁安| 桐庐| 荣县| 通州| 大连| 黑山| 烟筒山| 安丘| 曲麻莱| 东乡| 张掖| 阿荣旗| 黑山头| 齐河| 金州| 寿县| 交口| 衡东| 呼和浩特| 金山| 肃宁| 威海| 康乐| 铅山| 巴塘| 沙坪坝| 托里| 朝城| 交口| 宁安| 昭觉| 建德| 旬阳| 陇川| 荣成| 云浮| 甘谷| 象州| 永济| 长垣| 安福| 普宁| 北碚| 呼和浩特市郊区| 卓资| 汉沽| 若尔盖| 牙克石| 高陵| 梅河口| 嘉荫| 舟山| 昔阳| 松桃| 翁牛特旗| 斋堂| 淇县| 六盘水| 鹿邑| 桐梓| 新化| 达州| 南涧| 通道| 北川| 长泰| 民勤| 苏尼特左旗| 湟源| 滨州| 化州| 惠民| 苍梧| 阳谷| 万源| 绛县| 黄泛区| 呼伦贝尔| 固镇| 石阡| 正定| 文水| 新巴尔虎左旗| 庆元| 庆城| 延长| 弥渡| 小渠子| 深州| 桐城| 新会| 任县| 濮阳| 瑞安| 平和| 丹棱| 香格里拉| 麦积| 六安| 登封| 张北| 朝阳| 吉安县| 桐城| 长武| 四会| 章丘| 漳平| 巴林左旗| 鹤山| 文安| 和政| 建宁| 双牌| 云县| 铜锣湾| 喀喇沁旗| 彭阳| 久治| 平阴| 青龙山| 桓仁| 上饶| 乌审旗| 云龙| 江夏| 姚安| 三河| 嘉兴| 珙县| 灵川| 田东| 遂溪| 永修