偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

復(fù)雜系統(tǒng)如何保障代碼質(zhì)量?讓測試先行

開發(fā) 開發(fā)工具
高德在線導(dǎo)航服務(wù)作為有很強業(yè)務(wù)特性和多年歷史積累的存量系統(tǒng),不可避免的存在大量的不合理代碼,而業(yè)務(wù)演進對系統(tǒng)性能、算法、底層架構(gòu)等不斷提出更高要求,存量的各種業(yè)務(wù)代碼和算法、架構(gòu)快速演進的訴求存在嚴重沖突,如何有效保障質(zhì)量地進行快速重構(gòu)式演進,成為業(yè)務(wù)發(fā)展面臨的首要工程難題。

 [[373778]]

一 業(yè)務(wù)背景

高德在線導(dǎo)航服務(wù)作為有很強業(yè)務(wù)特性和多年歷史積累的存量系統(tǒng),不可避免的存在大量的不合理代碼,而業(yè)務(wù)演進對系統(tǒng)性能、算法、底層架構(gòu)等不斷提出更高要求,存量的各種業(yè)務(wù)代碼和算法、架構(gòu)快速演進的訴求存在嚴重沖突,如何有效保障質(zhì)量地進行快速重構(gòu)式演進,成為業(yè)務(wù)發(fā)展面臨的首要工程難題。

二 現(xiàn)有質(zhì)量保障方法問題與分析

1 現(xiàn)有測試方法的問題

常規(guī)方法是對新老服務(wù)批量進行請求比較diff,這種方式簡單有效,是我們一直在用的方法,但存在以下問題:

  • 無效diff問題:以公交規(guī)劃引擎為例,依賴步導(dǎo)引擎、搜索、公交突發(fā)事件、路況等多個下游服務(wù),獲取結(jié)果的差異導(dǎo)致很多無效diff。
  • 運行時間較長:case量較多時運行時間較長,在10分鐘級別。由于這一步成本較高,一般開發(fā)人員跑diff的頻率不會太高,無法進行"每次一小步"的測試。
  • 排查困難:當(dāng)發(fā)現(xiàn)diff后進行排查非常困難,因為是整個請求級別的diff,中間步驟可能都存在問題。

2 業(yè)界主流方法實踐

ThoughtWorks、Google等公司使用TDD方式進行敏捷開發(fā),通過編寫單元測試用例保障開發(fā)、重構(gòu)的質(zhì)量,目前已經(jīng)成為主流最佳實踐。

三 單元測試介紹

1 什么是單元測試?

單元測試是對一個模塊、一個函數(shù)或者一個類進行正確性檢驗的測試工作。

測試的粒度更小更輕量,運行時間在秒級,特別適合漸進式重構(gòu)中的"每次一小步"的質(zhì)量保障。

由于單元測試用例針對的是一個函數(shù)、類更細粒度的目標,所以當(dāng)某個用例不通過時,可以快速鎖定問題點。

2 單元測試框架

常見單元測試框架有 xUnit 系列,多種語言都有對應(yīng)實現(xiàn),如CppUnit、JUnit、NUnit...

GTest是Google開發(fā)的單元測試框架,此框架具有一些高級功能,如death test, mock等。

我們選擇的是GTest框架。

3 單元測試、重構(gòu)、TDD與敏捷

TDD(Test Driven Development)是強調(diào)測試先行的開發(fā)方式,這種方式的好處在于編寫任何函數(shù)、修改任何代碼時可以通過編寫一個單元測試用例代碼來表達要實現(xiàn)的代碼功能,一個測試用例本身就是一個代碼表達的需求。而積累起來的測試用例可以有效保障開發(fā)及后續(xù)重構(gòu)演進的質(zhì)量。

重構(gòu)和TDD是敏捷方法的核心構(gòu)成要素,脫離了TDD的敏捷是危險的,沒有用例保障的重構(gòu)一旦啟動,就像一匹脫韁的野馬。而單元測試和TDD則是縛住野馬的韁繩。

四 公交服務(wù)單元測試實踐

1 GTest框架集成

Git庫地址:https://github.com/google/googletest

GTest框架集成非常簡單,把googletest庫加入到工程中, 增加鏈接 libgtest 即可:

 

通過如下代碼即可驅(qū)動用例執(zhí)行:

  1. int RCUnitTest::Excute() 
  2.   int argc = 2; 
  3.   char* argv[] = {const_cast<char*>(""), const_cast<char*>("--gtest_output=\"xml:./testAll.xml\"")}; 
  4.   ::testing::InitGoogleTest(&argc, argv); 
  5.  
  6.   return RUN_ALL_TESTS(); 

開關(guān)控制:為避免影響到正式版本, 可以考慮通過編譯控制,也可以增加一個配置項開關(guān)。

我們在使用時是在入口處通過一個配置項控制是否觸發(fā)單元測試用例,編譯時默認只鏈接入口文件,需要運行單元測試時添加上單元測試用例文件進行鏈接運行。

2 測試代碼編寫

通過實現(xiàn)一個Test類的派生類,然后使用TEST_F宏添加測試函數(shù)即可,如下示例:

  1. class DateTimeUtilTest : public ::testing::Test 
  2. protected: 
  3.     virtual void SetUp() 
  4.     } 
  5.  
  6. virtual void TearDown() 
  7.     } 
  8. }; 
  9.  
  10. TEST_F(DateTimeUtilTest, TestAddSeconds_leap) 
  11.     //閏年測試 2020-02-28 
  12.     tm tt; 
  13.     tt.tm_year = (2020 - 1900); 
  14.     tt.tm_mon = 1; 
  15.     tt.tm_mday = 28; 
  16.     tt.tm_hour = 23; 
  17.     tt.tm_min = 59; 
  18.     tt.tm_sec = 50; 
  19.  
  20.     DateTimeUtil::AddSeconds(tt, 30); 
  21.     EXPECT_TRUE(tt.tm_sec == 20); 
  22.     EXPECT_TRUE(tt.tm_min == 0); 
  23.     EXPECT_TRUE(tt.tm_hour == 0); 
  24.     EXPECT_TRUE(tt.tm_mday == 29); 
  25.     EXPECT_TRUE(tt.tm_mon == 1); 
  26.  
  27.     //非閏年測試 2019-02-28 
  28.     tm tt1; 
  29.     tt1.tm_year = (2019 - 1900); 
  30.     tt1.tm_mon = 1; 
  31.     tt1.tm_mday = 28; 
  32.     tt1.tm_hour = 23; 
  33.     tt1.tm_min = 59; 
  34.     tt1.tm_sec = 50; 
  35.     DateTimeUtil::AddSeconds(tt1, 30); 
  36.     EXPECT_TRUE(tt1.tm_sec == 20); 
  37.     EXPECT_TRUE(tt1.tm_min == 0); 
  38.     EXPECT_TRUE(tt1.tm_hour == 0); 
  39.     EXPECT_TRUE(tt1.tm_mday == 1); 
  40.     EXPECT_TRUE(tt1.tm_mon == 2); 
  41. }; 

測試用例執(zhí)行效果:

 

目前公交引擎已經(jīng)積累了23個模塊測試用例,基本覆蓋了尋站、尋路、ETA、票價、風(fēng)險停運等核心功能,持續(xù)積累中。通過單元測試保障,每個版本開發(fā)活動中都在進行漸進式重構(gòu)活動,能夠有效保障質(zhì)量,提測迭代次數(shù)和線上新增代碼引入問題數(shù)量持續(xù)較低。

 

3 問題與難點

數(shù)據(jù)依賴問題

在線導(dǎo)航引擎是對數(shù)據(jù)重度依賴的業(yè)務(wù),多組數(shù)據(jù)結(jié)構(gòu)之間互相關(guān)聯(lián),字段繁多,很難脫離數(shù)據(jù)構(gòu)建有效的單元測試。通過mock方式構(gòu)造假數(shù)據(jù)成本很高。而數(shù)據(jù)變化將導(dǎo)致用例不能通過。

我的實踐:

能夠簡單構(gòu)造假數(shù)據(jù)的通過構(gòu)造假數(shù)據(jù)來搞定。

對于很難構(gòu)建假數(shù)據(jù)的情況,直接使用真實數(shù)據(jù)即可。數(shù)據(jù)變化可能導(dǎo)致這部分用例不通過,沒有關(guān)系,只需要保障在每次重構(gòu)前把相關(guān)的用例調(diào)通即可,這樣仍可以確保重構(gòu)過程的質(zhì)量。即:不需要做到用例隨時隨地都能運行通過,而是保證重構(gòu)前后都可以通過。

4 常見錯誤認知

對于沒有真正實踐過單元測試和TDD開發(fā)方式的同學(xué)來說,有一些認知上的常見誤區(qū),比如:

開發(fā)時間都不夠, 哪有時間編寫單元測試?

我的理解:

  • 首先TDD的開發(fā)方式強調(diào)的是測試先行,編寫測試代碼是在前面的,這個過程等于是理解需求的過程。即想清楚你要實現(xiàn)的是什么功能?這個測試代碼是理清需求的產(chǎn)物, 如此而已,不存在更多時間成本。
  • TDD開發(fā)方式屬于典型的一次投入,持續(xù)受益的事情,用例積累越多,越容易在早期發(fā)現(xiàn)問題,重構(gòu)有了質(zhì)量保障,代碼越來越整潔清晰,開發(fā)同學(xué)們再也不用哀嘆歷史代碼。

歷史代碼那么多,怎么補單元測試?

那就從添加第一個用例開始。我的做法是對應(yīng)本次修改涉及到的代碼添加用例,逐步積累。

添加用例的過程是理解現(xiàn)有代碼的過程,對于存量的歷史代碼,各種硬性編碼侵入,各種耦合,全局變量或長生命周期大對象,通過編寫單元測試用例能夠有效理清函數(shù)真正的輸入輸出,也為重構(gòu)增加了有效保障。

五 存量復(fù)雜系統(tǒng)代碼漸進式重構(gòu)

對于我們一線碼農(nóng),每天大部分時間都在和代碼打交道,如果你維護的代碼結(jié)構(gòu)合理、易讀易擴展,那么恭喜你!但大部分情況我們面對的是存在各種歷史"積淀"的存量工程,各種牽一發(fā)而動全身,這種情況下小改動還可以靠多花時間,認真仔細來搞定,但想要做一些大的系統(tǒng)升級就難了。

而對于巨型業(yè)務(wù)系統(tǒng)來說,重寫在成本和質(zhì)量控制方面顯得更不現(xiàn)實。那么設(shè)置幾個大的節(jié)點,通過漸進式重構(gòu)逐漸優(yōu)化,變量變?yōu)橘|(zhì)變,是綜合來看最優(yōu)的方式。

而單元測試和TDD,則是漸進式重構(gòu)有效開展的必選方法。

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2011-08-03 09:18:36

軟件項目管理

2009-06-08 14:54:11

產(chǎn)品綜合布線福祿克

2021-07-09 11:29:22

交易鏈路閑魚阿里云

2020-03-18 16:15:21

億級搜索數(shù)據(jù)

2022-03-25 09:22:42

代碼開發(fā)

2015-04-27 09:41:35

前端質(zhì)量質(zhì)量保障

2020-01-13 15:38:33

Hadoop代碼項目

2019-04-24 13:31:22

2019-10-14 17:00:14

前端代碼圈復(fù)雜度

2013-11-12 09:56:03

系統(tǒng)服務(wù)安全TCP wrapper企業(yè)安全

2023-02-16 11:58:51

契約開發(fā)測試??

2017-08-02 16:01:18

5G通信測試

2016-02-23 11:03:03

代碼質(zhì)量編寫函數(shù)

2023-01-06 18:31:46

準確命名

2022-03-11 10:03:40

分布式鎖并發(fā)

2022-03-07 08:14:27

并發(fā)分布式

2012-11-07 09:48:26

2024-04-22 00:00:00

配置鏈接穩(wěn)定性

2021-04-27 09:20:03

機器學(xué)習(xí)人工智能計算機

2019-09-16 09:05:05

前端開發(fā)技術(shù)
點贊
收藏

51CTO技術(shù)棧公眾號