技術崗
測試(QA):保證代碼沒有bug
開發(RD):搬磚
運維(OP):
非技術崗
產品經理
注意公司和部門和崗位和工資
測試時需要先搞清楚需求和功能點
姓名_學校專業_崗位.pdf
1、 軟件開發生命周期

2、 單元測試:
# include<cstdio> //實現一個求絕對值的函數 int Abs(int x){ return x>0?x:-x; } //針對Abs函數進行測試:單元測試必須為一個獨立的函數 void TestAbs() { int result=Abs(10); if(result==10){ printf("ok\n"); } else { printf("NO\n"); } int result=Abs(-10); if(result==10){ if(result==10){ printf("ok 1\n"); } else { printf("NO 2\n"); } int result=Abs(0); if(result==0){ printf("ok 2\n"); } else { printf("NO 2\n"); } } int main(){ TestAbs(); return 0; }
3、 gtest:谷歌業界廣泛使用的單元測試框架:gtest只能用於C++
gtest框架提供了gtest方式的單元測試
gtest中有一個默認的main函數,成功會編程原亮色
4、 步驟:
安裝gtest
main.cc # include<gtest/gtest.h> # include<iostream> //TestCase相當於目錄,Test相當於目錄中的文件 //把一組有關聯的Test組織到一個TestCase //TestCaseName和TestName都要結合實際的測試場景決定 //寫一個test宏,進行單元測試的基本單位 Test(HelloTestCase,HelloTest) { //TEST宏里面可以寫任何合法的C++代碼 std::cout<<"hello"<<std::endl; }
Makefile:
hello:hello.cc g++ $^ -o $@ -I ~/third_part/include -L ~/third_part/lib -lgtest -lgtest_main -lpthread .PHONY:clean clean: rm hello
5、學會使用第三方庫
如何將第三方庫引入項目中:
gtest中自定義main函數(添加初始化即可):
# include<gtest/gtest.h> # include<iostream> //TestCase相當於目錄,Test相當於目錄中的文件 //把一組有關聯的Test組織到一個TestCase //TestCaseName和TestName都要結合實際的測試場景決定 //寫一個test宏,進行單元測試的基本單位 Test(HelloTestCase,HelloTest) { //TEST宏里面可以寫任何合法的C++代碼 std::cout<<"hello"<<std::endl; } int main(int argc,char* argv[]) { return RUN_ALL_TESTS();//把返回值作為進程的終止碼 }
此時makefile中去掉main
hello:hello.cc g++ $^ -o $@ -I ~/third_part/include -L ~/third_part/lib -lgtest -lpthread .PHONY:clean clean: rm hello
例題二、對求絕對值進行簡單的單元測試:
.cc
# include<cstdio> //實現一個求絕對值的函數 int Abs(int x){ return x>0?x:-x; } //以下代碼為測試代碼 TEST(TestAbs,Positive) { //用法類似於assert宏:斷言失敗會(1)使程序崩潰,(2)進程異常終止: //(3)會調用abort函數,導致進程異常終止。assert的使用方式比較單一 //ASSERT_TRUE宏的使用方法類似,但是更加靈活,失敗時會導致:由原亮色變為紅色 //通過框架會展示是否通過,通過的有哪些。 ASSERT_TRUE(Abs(10)==10); } TEST(TestAbs,Positive) { ASSERT_TRUE(Abs(-10)==10); } TEST(TestAbs,Positive) { ASSERT_TRUE(Abs(0)==0); }
Makefile:
main:main.cc g++ $^ -o $@ -I ~/third_part/include -L ~/third_part/lib -lgtest -lgtest_main -lpthread .PHONY:clean clean: rm main
增加日志打印失敗的值:ASSERT_TRUE(Abs(10)==10)<<”Abs(10)= “<<Abs(10);使用的運算符為移位運算符;斷言失敗會打印值。
ASSERT_TRUE:判斷是否為真
ASSERT_EQ(值1,值2);判斷兩個值是否相等
ASSERT這樣的致命斷言,一旦失敗,該TEST宏中的代碼就不繼續執行;EXPECT前綴的是非致命的斷言,一旦失敗,該TEST宏中的代碼還能繼續執行。ASSERT應用於:需求是實現一個測試文件的格式,用ASSERT來校驗打開文件失敗(文件打開失敗,不能完成文件內容的驗證);打開成功用EXPECT校驗當前行格式是否正確。
哪個項目中應用到了這個知識點?
C_string :C語言風格的字符串以\0結尾的字符串
3、gtest中的事件機制:gtest在執行之前會有一個回調函數的時間,結束時又會有一定的時間用來銷毀數據。
(1)庫和框架的區別:
庫:C++的標准庫包含了標准模板庫,STL是標准模板庫。許多內容屬於標准庫而不是STL中的內容。庫都是由程序員決定什么時機進行調用的。
框架:對於一些函數的調用時機不是由程序員自己來決定,而是由框架來決定。有些規則需要自己來定制,但是什么時候被調用不受程序員控制。
(2)事件:讓事件得到進一步精簡,使代碼得到進一步重用。
例子:
# include<iostream> # include<gtest/gtest.h> # include<map> void MakeMap(std::map<int,int>& test_map){ test_map.insert(std::make_pair(1,1)); test_map.insert(std::make_pair(2,1)); test_map.insert(std::make_pair(3,1)); test_map.insert(std::make_pair(4,1)); test_map.insert(std::make_pair(5,1)); } //需求是,針對std::map一些典型接口進行單元測試 TEST(TestMap,size){ std::map<int,int>test_map; //插入數據:不允許插入key相同的數據 MakeMap(test_map); //進行測試 ASSERT_EQ(test_map.size(),5); } TEST(TestMap,find){ std::map<int,int>test_map; auto it=test_map.find(2); MakeMap(test_map); ASSERT_NE(it,test_map.end()); } TEST(TestMap,operator){ std::map<int,int>test_map; test_map[2]=100; MakeMap(test_map); ASSERT_EQ(test_map[2],100); }
太繁瑣,我們把共用的代碼放入宏中,要使用時,自動調用:TEST_F搭配事件機制使用,測試函數的第一個參數名字必須相同,才能構成事件機制自動調用。
# include<iostream> # include<gtest/gtest.h> # include<map> //通過虛函數的方式,將這樣的自定制邏輯注冊到框架中,框架自動決定什么時候執行。 class TestMap:public testing::Test{ public: void setup(){ test_map.insert(std::make_pair(1,1)); test_map.insert(std::make_pair(2,1)); test_map.insert(std::make_pair(3,1)); test_map.insert(std::make_pair(4,1)); test_map.insert(std::make_pair(5,1)); } void TearDown(){ test_map.clear(); } std::map<int,int> test_map; }; //需求是,針對std::map一些典型接口進行單元測試 TEST_F(TestMap,size){ std::map<int,int>test_map; //進行測試 ASSERT_EQ(test_map.size(),5); } TEST_F(TestMap,find){ std::map<int,int>test_map; auto it=test_map.find(2); ASSERT_NE(it,test_map.end()); } TEST_F(TestMap,operator){ std::map<int,int>test_map; test_map[2]=100; ASSERT_EQ(test_map[2],100); }
makefile:
main:main.cc g++ $^ -o $@ -I ~/third_part/include -L ~/third_part/lib\ -lgtest -lgtest_main -lpthread -std=c++11 .PHONY:clean clean: rm main
通過多態完成一個框架,向框架中插入數據:
