Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÖÐ̨¼¼Êõ½âÎö֮΢·þÎñ¼Ü¹¹ÏµIJâÊÔʵ¼ù
 
×÷ÕߣºÍõÀöÊç
  2010  次浏览      32
 2021-1-28 
   
 
±à¼­ÍƼö:
ÎÄÕÂÊ×ÏȽéÉÜÁ˼ܹ¹Ñݽø´øÀ´µÄ²âÊÔÌôÕ½£¬È»ºó½øÐÐÁËÒ»¸ö²âÊԵĸÅÊö£¬×îºó½²½âFreeWheel ºËÐÄÒµÎñÍŶӲâÊÔʵ¼ù¡£
±¾ÎÄÀ´×ÔÓÚinfoq£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­¡¢ÍƼö¡£

ÒýÑÔ

Ëæ×ż¼ÊõµÄ·¢Õ¹£¬Èí¼þ¿ª·¢·½·¨²»¶ÏÑݽø£¬²âÊÔÒ»Ö±¶¼ÊDz»¿É»òȱµÄÒ»²½¡£×÷ΪÌáÉýÓû§ÌåÑé¡¢±£ÕÏÈí¼þÖÊÁ¿µÄ¹Ø¼ü»·½Ú£¬Èí¼þ²âÊÔÖÁ¹ØÖØÒª¡£ÌرðÊÇÃæ¶Ô¶àÑù»¯µÄ²âÊÔÐèÇó¡¢²»¶Ï¼Ó¿ìµÄ°æ±¾µü´úËÙ¶È£¬ÈçºÎÎ§ÈÆÒµÎñ¹¦ÄÜÐèÇó´î½¨ÊÊºÏÆäÌØµãÇÒ¿ìËÙ¡¢¸ßЧµÄÈí¼þ²âÊÔÌåϵ¡¢¿ò¼ÜºÍÁ÷³Ì£¬FreeWheel ºËÐÄÒµÎñÍŶӶԴ˽øÐÐÁËÉîÈëµÄ̽Ë÷ºÍʵ¼ù¡£ÍŶӽ«²âÊÔÖоßÓй²ÐÔµÄÄ£¿é½øÐгéÏóºÍÌáÈ¡£¬ÐγÉÁË×Ô¼ºµÄ¡°²âÊÔÖ®µÀ¡±£¬Îª²úÆ·ÖÊÁ¿ÌṩǿÓÐÁ¦µÄ±£ÕÏ¡£

¼Ü¹¹Ñݽø´øÀ´µÄ²âÊÔÌôÕ½

ÔÚÏîÄ¿³õÆÚ£¬ºËÐÄÒµÎñÍŶӲÉÈ¡µÄÊÇ»ùÓÚ Ruby-Rails µÄµ¥Ìå¼Ü¹¹£¬ÈçÉÏͼ×ó²àËùʾ£¬Ö÷Òª°üÀ¨Ç°¶Ë¡¢ÖмäÒµÎñÂß¼­²ãºÍÊý¾Ý¿â²ãÈý²ã½á¹¹¡£Ëæ×ÅÏîÄ¿¹æÄ£µÄÀ©´ó£¬Ô½À´Ô½¶àµÄÈ˼ÓÈëÁË¿ª·¢ÍŶӣ¬´úÂëÁ¿Ò²ÔÚÓëÈÕ¾ãÔö£¬µ¥Ìå¼Ü¹¹µÄȱµãÒ²ËæÖ®¿ªÊ¼ÏÔÏÖ£º¸´ÔÓÐԸߣ¬Ä£¿éÖ®¼äÏ໥ÒÀÀµ£»ÏîÄ¿²¿ÊðËٶȱäÂý£¬»¨·ÑµÄʱ¼ä²»¶ÏÔö³¤£»×è°­Á˼¼Êõ´´Ð£¬ÏµÍ³À©Õ¹ÄÜÁ¦ÊÜÏÞ¡£

»ùÓÚÒÔÉÏÔ­Òò£¬ºËÐÄÒµÎñÍŶӾö¶¨¸Ä±ä¼¼Êõ¼Ü¹¹£¬Öð²½Åׯú¹¹½¨µ¥Ò»¡¢ÅÓ´óµÄµ¥ÌåʽӦÓã¬×ª¶ø²ÉÓÃ΢·þÎñ¼Ü¹¹£¬ÈçÉÏͼËùʾ¡£Î¢·þÎñ¼Ü¹¹½«µ¥Ìå¼Ü¹¹µÄÖмä²ã·Ö½â£¬²ð·Ö³É¶à¸ö¿É¶ÀÁ¢Éè¼Æ¡¢¿ª·¢¡¢ÔËÐеÄСӦÓ㬸÷¸öСӦÓÃÖ®¼äЭ×÷ͨÐÅ£¬ÎªÓû§Ìṩ×îÖÕ·þÎñ¡£´ËÍ⣬½«·þÎñ²¿ÊðÔÚ AWS ÉÏ£¬ÕâЩµ÷Õû¶¼ÓÐЧµØÏû³ýÁËÍ´µã¡£

Óë´Ëͬʱ£¬Î¢·þÎñ¼Ü¹¹µÄʹÓÃÒ²¸øÎÒÃǵIJâÊÔ´øÀ´ÁËеÄÌôÕ½£¬³ýÁËÒªÑéÖ¤¸÷¸ö΢·þÎñµÄ¹¦ÄÜÊÇ·ñÕý³£Ö®Í⣬»¹ÐèÒª¿¼ÂÇÈçÏÂÎÊÌ⣺

1. ÈçºÎ²âÊÔ΢·þÎñÖ®¼äµÄÒÀÀµÊÇ·ñÕý³££»

2. ÔÚ΢·þÎñ¼Ü¹¹ÏÂÈçºÎÑéÖ¤Õû¸öϵͳµÄ¹¦ÄÜÊÇ·ñ·ûºÏÔ¤ÆÚ£»

3. ÈçºÎÓÐЧµÄ½øÐжà¸ö΢·þÎñµÄ²¿ÊðºÍ²âÊÔ¡£

еIJâÊÔÐèÇóÐèҪеIJâÊÔ²ßÂÔÀ´Âú×㣬ÏÂÎÄÊ×ÏÈ»á¶ÔÈí¼þ²âÊÔ½øÐмòµ¥µÄ½éÉÜ£¬È»ºó»á½éÉܺËÐÄÒµÎñÍŶӶÔÕâЩÐèÇóµÄÓ¦¶ÔÁ¼²ß¡£

Èí¼þ²âÊÔ¸ÅÊö

Èí¼þ²âÊÔÊÇʹÓÃÈ˹¤»òÕß×Ô¶¯»¯ÊÖ¶ÎÀ´¼ø¶¨Èí¼þµÄ¹¦ÄÜ»òÐÔÄÜÊÇ·ñÂú×㿪·¢Ö®Ç°Ìá³öµÄÐèÇóµÄÒ»¸ö¹ý³Ì¡£Í¨¹ýÈí¼þ²âÊÔ¿ÉÒÔ¼°Ê±·¢ÏÖÎÊÌâ¡¢½â¾öÎÊÌ⣬Ìá¸ßÈí¼þÖÊÁ¿£¬½µµÍÒòÈí¼þÎÊÌâ´øÀ´µÄÉÌÒµ·çÏÕ£¬ÌáÉýÓû§ÌåÑé¡£

°´ÕÕ²»Í¬·ÖÀà±ê×¼£¬Èí¼þ²âÊÔ¿É»®·ÖΪ²»Í¬µÄÀàÐÍ£¬ÏÂͼÁоÙÁËһЩ³£¼ûµÄÈí¼þ²âÊÔ·ÖÀà¡£

ϱí¶Ô¼¸ÖÖ³£¼ûµÄ²âÊÔ×öÁ˽ÏΪÏêϸµÄ±È½Ï¡£

»ùÓÚ´Ë£¬ºËÐÄÒµÎñÍŶӰ´ÕÕ²úÆ·µÄÑз¢½×¶Î·Ö±ð¶Ôµ¥Ôª²âÊÔ¡¢¼¯³É²âÊÔ¡¢¶Ëµ½¶Ë²âÊÔºÍÐÔÄܲâÊÔ½øÐÐÁËʵ¼ù²¢×ܽáÁË·½·¨£¬ÏÂÎĽ«½øÐÐÏêϸ½éÉÜ¡£

FreeWheel ºËÐÄÒµÎñÍŶӲâÊÔʵ¼ù

²âÊÔ¿ò¼Ü

µ¥Ìå¼Ü¹¹Ê±£¬ÍŶӵIJâÊÔÖ÷ÒªÒÀÀµ»ùÓÚ Selenium µÄ¼¯³É²âÊԺͺó¼ì²é²âÊÔ£¬»ùÓÚ Rails µÄµ¥Ôª²âÊÔÂÔÓÐǷȱ¡£×ªµ½Î¢·þÎñ¼Ü¹¹ºó£¬ÎªÁËÂú×ãеÄÐèÇ󣬲âÊÔ¿ò¼ÜÒ²½øÐÐÁËÏàÓ¦µ÷Õû¡£ÉÏͼÊÇĿǰºËÐÄÒµÎñÍŶӵIJâÊÔ½ð×ÖËþ£¬Ëü¿ÉÒԺܺõذïÖúÎÒÃÇÇø·Ö²»Í¬²ã´Î²âÊԵĹØ×¢µã¡£½ð×ÖËþ´Óϲ㵽¶¥²ãÒÀ´ÎΪµ¥Ôª²âÊÔ¡¢¼¯³É²âÊÔ¡¢¶Ëµ½¶Ë²âÊÔºÍÐÔÄܲâÊÔ¡£ÆäÖУ¬Ô½¿¿½ü½ð×ÖËþµÄµ×¶Ë£¬Ò»°ã¶øÑÔ²âÊÔËÙ¶ÈÔ½¿ì£¬·´À¡ÖÜÆÚÒ²Ô½¶Ì£¬²âÊÔ·¢ÏÖÎÊÌâºó¸üÈÝÒ×¶¨Î»ÊÜÓ°ÏìµÄ¹¦ÄÜ£»Ô½ÊÇ¿¿½ü½ð×ÖËþµÄ¶¥¶Ë£¬²âÊÔ¸²¸ÇµÄ·¶Î§Ô½´ó£¬µ«ÐèÒª»¨·Ñ¸ü³¤Ê±¼äÍê³É²âÊÔ£¬¾­¹ý²âÊÔºó¹¦ÄܵÄÕýÈ·ÐÔÒ²¸üÓб£Ö¤¡£ÏÂÃæ£¬·Ö±ð½éÉÜ FreeWheel ºËÐÄÒµÎñÍŶÓÔÚÿһÀà²âÊÔÉϵľßÌåʵ¼ù¡£

µ¥Ôª²âÊÔ

¡°µ¥Ôª¡±ÊÇÈí¼þµÄ×îС¿É²âÊÔ²¿¼þ¡£µ¥Ôª²âÊÔ¾ÍÊÇÈí¼þ¿ª·¢ÖжÔ×îСµ¥Ôª½øÐÐÕýÈ·ÐÔ¼ìÑéµÄ²âÊÔ£¬ËüÊÇËùÓвâÊÔÖÐ×îµ×²ãµÄÒ»Àà²âÊÔ£¬ÓÉ¿ª·¢ÈËÔ±ÔÚ¿ª·¢´úÂëʱͬ²½±àд£¬ÊǵÚÒ»¸öÒ²ÊÇ×îÖØÒªµÄÒ»¸ö»·½Ú¡£

ÍŶӺó¶Ë¿ª·¢Ê¹ÓõÄÓïÑÔÊÇ Go£¬Go ÓïÑÔ×Ô´øÓÐÒ»¸öÇáÁ¿¼¶µÄ²âÊÔ¿ò¼Ü testing£¬¿ÉʹÓÃ×Ô´øµÄ go test ÃüÁî½øÐе¥Ôª²âÊÔ¡£Í¬Ê±£¬ÎÒÃÇʹÓÃÁË TDD£¬¼´ÔÚ¿ª·¢¹¦ÄÜ´úÂë֮ǰ£¬Ïȱàдµ¥Ôª²âÊÔÓÃÀý£¬ÒÔ²âÊÔ´úÂëÀ´È·¶¨ÐèÒª±àдµÄ²úÆ·´úÂ룬Ìá¸ß´úÂëÖÊÁ¿¡£

Mock ʵ¼ù

µ¥Ôª²âÊԵıàдÍùÍùÓжÀÁ¢ÐÔµÄÒªÇ󣬺ܶàʱºòÒòΪҵÎñÂß¼­¸´ÔÓ£¬´úÂëÂß¼­Ò²ËæÖ®±äµÄ¸´ÔÓ£¬²ôÔÓÁ˺ܶàÆäËû×é¼þ£¬µ¼ÖÂÔÚ±àдµ¥Ôª²âÊÔÓÃÀýʱ´æÔڱȽϸ´ÔÓµÄÒÀÀµÏÈçÊý¾Ý¿â»·¾³¡¢ÍøÂç»·¾³µÈ£¬ÕâЩÔö¼ÓÁ˵¥Ôª²âÊԵĸ´ÔӶȺ͹¤×÷Á¿¡£

Mock ¶ÔÏó¾ÍÊÇΪ½â¾öÉÏÊöÎÊÌâ¶øµ®ÉúµÄ£¬mock ¶ÔÏóÄܹ»Ä£Äâʵ¼ÊÒÀÀµ¶ÔÏóµÄ¹¦ÄÜ£¬Í¬Ê±ÓÖʡȥÁ˸´ÔÓµÄÒÀÀµ×¼±¸¹¤×÷¡£µ±Ç°£¬ÔÚºËÐÄÒµÎñÍÅ¶Ó Go ´úÂë¿âÖУ¬´æÔÚ 2 ÖÖ mock ʵ¼ù¡£Ò»ÖÖÊÇºÍ mockery ½áºÏʹÓÃµÄ Testify/mock£¬ÁíÒ»ÖÖÊÇºÍ mockgen ½áºÏʹÓÃµÄ Go/gomock¡£

Testify/Mock

Testify °üÖÐÒ»¸öÓÅÐãµÄ¹¦ÄܾÍÊÇËüµÄ mock ¹¦ÄÜ£¬ÔÚ½øÐе¥Ôª²âÊÔʱ£¬´úÂëÖÐÍùÍùÓдóÁ¿µÄ·½·¨ºÍº¯ÊýÐèҪģÄ⣬´Ëʱ vertra/mockery ¾Í³ÉΪÁËÎÒÃǵĵÃÁ¦ÖúÊÖ£¬mockery µÄ¶þ½øÖÆÎļþ¿ÉÒÔÕÒµ½ÈκÎÔÚ Go Öж¨ÒåµÄ interfaces µÄÃû×Ö£¬È»ºó×Ô¶¯Éú³ÉÄ£Äâ¶ÔÏóµ½ mocks Îļþ¼Ð϶ÔÓ¦µÄÎļþÖС£

Golang/mock

Gomock ÊÇ Google ¿ªÔ´µÄ golang ²âÊÔ¿ò¼Ü£¬gomock ͨ¹ý mockgen ÃüÁîÉú³É°üº¬ mock ¶ÔÏóµÄ .go Îļþ£¬Ëü¿ÉÒÔ¸ù¾Ý¸ø¶¨µÄ½Ó¿Ú×Ô¶¯Éú³É´úÂë¡£ÕâÀï¸ø¶¨µÄ½Ó¿ÚÓÐÁ½ÖÖ·½Ê½£º½Ó¿ÚÎļþºÍʵÏÖÎļþ¡£

Èç¹û´æÔÚ½Ó¿ÚÎļþ£¬¿Éͨ¹ý -source ²ÎÊýÖ¸¶¨½Ó¿ÚÎļþ£¬-source Ö¸¶¨Éú³ÉµÄÎļþÃû£¬-package Ö¸¶¨Éú³ÉÎļþµÄ°üÃû¡£ÀýÈ磺

mockgen -destination foo/mock_foo.go -package foo -source foo/foo.go

Èç¹ûûÓÐʹÓÃ-source Ö¸¶¨½Ó¿ÚÎļþ£¬mockgen Ò²Ö§³Öͨ¹ý·´É䷽ʽÕÒµ½¶ÔÓ¦µÄ½Ó¿Ú£¬Ëüͨ¹ýÁ½¸ö·Ç±êÖ¾²ÎÊýÉúЧ£ºµ¼Èë·¾¶ºÍÓöººÅ·Ö¸ôµÄ·ûºÅÁÐ±í¡£ÀýÈ磺

mockgen database/sql/driver Conn,Driver

´ËÍ⣬Èç¹û´æÔÚ·ÖÉ¢ÔÚ²»Í¬Î»ÖõĶà¸öÎļþ£¬Îª±ÜÃâÖ´Ðжà´Î mockgen ÃüÁîÉú³É mock Îļþ£¬mockgen ÌṩÁËÒ»ÖÖͨ¹ý×¢ÊÍÉú³É mock ÎļþµÄ·½Ê½£¬ÕâÐèÒª½èÖú go µÄ¡°go generate¡±¹¤¾ßÀ´ÊµÏÖ¡£ÀýÈ磬ÔÚ½Ó¿ÚÎļþÖÐÌí¼ÓÈçÏÂ×¢ÊÍ£º

//go:generate mockgen -source=foo.go -destination=./gomocks/foo.go -package=gomocks

²âÊÔÓÃÀý

ÏÂÃæ¾ÙÀý½éÉÜ mock ¶ÔÏóÔÚµ¥Ôª²âÊÔÓÃÀýµÄʹÓãº

Éú³ÉµÄ mock Îļþ

type NetworkDao struct {
mock.Mock
}
// GetNetworkById provides a mock function with given fields: networkId
func (_m *NetworkDao) GetNetworkById(networkId int64) (*business.Network, error) {
ret := _m.Called(networkId)
// ... some mock code ...
return r0, r1
}

±»²âÊÔÎļþ

type dataRightDomain struct {
networkDao NetworkDao // use NetworkDomain in the mock code instead NetworkDomain interface
}
func (domain *dataRightDomain) GetDataRightWhitelist(all bool, searchQuery *types.SearchQuery) ([]*business.WhitelistItem, int32, error) {
// ... some code ...
partner, err := domain.networkDao.GetNetworkById (item.Id) // get return values from ExpectedCalls array in mock when using mock
// ... some code ...
}

²âÊÔÎļþ

func TestGetDataRightWhitelist(t *testing.T) {
// ... some code ...
networkDaoMock:= &mock. NetworkDao {}
networkDaoMock.On ("GetNetworkById", mock2.Anything).Return(nwRet, nil) // set up ExpectedCalls array in mock
wItems, number, err : = dataRightDomain.GetDataRightWhitelist(true, searchQuery) // call GetDataRightWhitelist where networkDao is replaced by mocked one
// ... some code ...
}

ͨ¹ýµ¥Ôª²âÊÔ£¬ºËÐÄÒµÎñÍŶӴﵽÁËÒÔÏÂÄ¿±ê£º

1. È·±£Ã¿¸ö¹¦Äܺ¯Êý¿ÉÔËÐУ¬²¢±£Ö¤½á¹ûÕýÈ·£»

2. È·±£´úÂëÐÔÄÜ×î¼Ñ£»

3. ¼°Ê±·¢ÏÖ³ÌÐòÉè¼Æ»òʵÏÖµÄÂß¼­´íÎó£¬Ê¹ÎÊÌâ¼°Ô籩¶£¬±ãÓÚ¶¨Î»ºÍ½â¾ö¡£

¼¯³É²âÊÔ

¼¯³É²âÊÔÔÚµ¥Ôª²âÊÔÍê³Éºó½øÐУ¬Ëü½«¶à¸ö´úÂëµ¥ÔªÒÔ¼°ËùÓм¯³É·þÎñ£¨ÈçÊý¾Ý¿âµÈ£©×éºÏÔÚÒ»Æð£¬²âÊÔËüÃÇÖ®¼äµÄ½Ó¿ÚÕýÈ·ÐÔ¡£Ëæ×źËÐÄÒµÎñÍŶÓתÏò΢·þÎñ¼Ü¹¹µÄ²½·¥¼Ó¿ì£¬¹¹½¨µÄ Go ·þÎñÔ½À´Ô½¶à£¬Îª´ËÎÒÃÇÉè¼ÆÁËÊÊÓÃÓÚ²»Í¬·þÎñµÄ¼¯³É²âÊÔÓÃÀý£¬ÔÚ¹¹½¨Ð·þÎñʱ¿ÉÒÔ×î´óÏ޶ȵؼõÉÙѧϰºÍ²âÊԳɱ¾¡£ÏÂͼÃè»æÁËÎÒÃǵɲâÊÔÁ÷³Ì£¬Ö÷Òª°üÀ¨Ëĸö½×¶Î£º×¼±¸²âÊÔÊý¾Ý¡¢×¼±¸²âÊÔ»·¾³¡¢Ö´ÐвâÊÔÓÃÀý¡¢Éú³É²âÊÔ±¨¸æ¡£

²âÊÔÊý¾Ý×¼±¸

ÔÚ²âÊÔÊý¾Ý×¼±¸½×¶Î£¬¾ßÌå²ßÂÔÈçÏ£º

ʹÓÃÒ»¸öÖ÷Êý¾Ý¿â×÷ΪÔËÐзþÎñµÄ»ù´¡Êý¾Ý£¬ÔÚËùÓвâÊÔÓÃÀý¿ªÊ¼Ö´ÐÐǰ£¬´ÓÖ÷Êý¾Ý¿âÖÐÏÂÔØ²âÊÔËùÐèÒªµÄÊý¾Ý±í£¬±£´æ³ÉÁÙʱ SQL Îļþ¡£Èç¹ûijЩ²âÊÔÓÃÀýÐèÒª½«Êý¾Ý»Ö¸´µ½³õʼ״̬£¬¿ÉʹÓÃÁÙʱ SQL ÎļþË¢ÐÂÊý¾Ý¿â¡£ÔÚËùÓвâÊÔÓÃÀýÖ´ÐÐÍê³Éºó£¬ÔÙ½«ËùÓÐÊý¾ÝË¢»Ø³õʼ״̬¡£ÕâÖÖ×ö·¨ºÍ¹²Ïí²âÊÔÊý¾Ý¿âÏà±È£¬¾ßÓÐÈçÏÂÓÅÊÆ£º

1. ÿ¸ö²âÊÔÓÃÀý¶¼½«ÓµÓжÀÏíµÄÊý¾Ý£¬±ÜÃâÁËÓÉÓÚ¹²ÏíÊý¾Ý¿âÖÐÊý¾Ý¸ü¸Ä¶ø³öÏֵĴíÎó¡£

2. Êý¾ÝˢРSQL µÄÁ¿ºÜС£¬ÒòΪ½öÐèË¢ÐÂÓë²âÊÔÓÃÀý¾ßÌåÏà¹ØµÄÊý¾Ý±í¡£

3. ¹«ÓÃÊý¾Ý½«µÃµ½¸üÑϸñµÄ¹ÜÀí¡£Ëü½«Ìṩһ¸ö¾ßÓиüºÃÊý¾Ý¶àÑùÐÔµÄÊý¾Ý´æ´¢£¬ÒÔÂú×ã²âÊÔÐèÇó¡£

Ö÷Á÷ Go ²âÊÔ¿ò¼ÜÓÐ 3 ¸ö£ºGinkgo£¬GoConvey£¬Godog£¬ÆäÖУ¬GoDog Ö§³Ö Gherkin Óï·¨£¬ÈÝÒ×ÉÏÊÖ, ËùÒÔÎÒÃÇÑ¡ÔñʹÓà GoDog ±àд¼¯³É²âÊÔÓÃÀý¡£´ËÍ⣬ÏÖÓеIJâÊÔÓÃÀý¼¯Ò²¿ÉÒÔÈ·±£´úÂëµÄÐÞ¸ÄûÓÐÒýÈëеĴíÎó»òµ¼ÖÂÆäËû´úÂë²úÉú´íÎ󣬯ðµ½Á˻عé²âÊԵŦÄÜ¡£

¶Ëµ½¶Ë²âÊÔ

¶Ëµ½¶Ë²âÊÔÊÇÕ¾ÔÚÓû§Ê¹ÓÃÊӽǽøÐеIJâÊÔ£¬Ëü½«Òª²âÊÔµÄÈí¼þÊÓΪºÚºÐ£¬ÎÞÐèÁ˽âÆäÄÚ²¿¾ßÌåʵÏÖϸ½Ú£¬Ö»Ðè¹Ø×¢Êä³ö½á¹ûÊÇ·ñ·ûºÏÔ¤ÆÚ¡£

ÔÚºËÐÄÒµÎñÍŶӵÄ΢·þÎñ¼Ü¹¹ÖУ¬¶Ëµ½¶Ë²âÊÔ»·½Ú¾ßÓиü¹ãµÄ·¶Î§ºÍ¸ü¸ßµÄµØÎ»£¬ÊÇÈ·±£Õû¸ö²úÆ·ÏßÖÊÁ¿µÄ×îºóÒ»µÀ·ÀÏß¡£ÔÚÒÔǰµÄµ¥Ìå¼Ü¹¹ÖУ¬ÎÒÃDzÉÓÃÁË Cucumber ºÍ Selenium µÄ×éºÏ½øÐж˵½¶Ë²âÊÔ£¬µ«ÕâÖÖ²âÊÔ¿ò¼ÜÖð½¥±©Â¶³öÐí¶àÎÊÌ⣬²¢ÇÒ²»ÊÊÓÃÓÚ΢·þÎñ¼Ü¹¹¡£ÎªÁ˸üºÃµØÔÚµ±Ç°µÄ΢·þÎñ¼Ü¹¹ÏÂʵʩ¶Ëµ½¶Ë²âÊÔ£¬ÎÒÃÇ¶Ô Cypress ºÍ Selenium ½øÐÐÁ˱ȽϷÖÎö¡£

 

ºËÐÄÒµÎñÍŶӻùÓÚÒÔÉÏ·ÖÎö½á¹û²¢½áºÏÒµÎñÐèÒª£¬ÊµÏÖÁËÒ»¸öеĻùÓÚ Cypress µÄ¶Ëµ½¶Ë²âÊÔ¿ò¼Ü£¬¿ÉÒÔͬʱ֧³Ö Web UI ºÍ API µÄ×Ô¶¯»¯²âÊÔ¡£

Cypress-fixtures

ÓÉÉÏͼ¿ÉÒÔ¿´³ö£¬ÔÚºËÐÄÒµÎñÍŶӱê×¼µÄ¿ª·¢²âÊÔÁ÷³ÌÖУ¬ÖÁÉÙÓÐÈý¸ö½×¶ÎÐèÒª½øÐж˵½¶Ë²âÊÔ£º

±¾µØ²âÊÔ£ºµ±´úÂëλÓÚ×Ô¶¨Òå·ÖÖ§ÖÐÉÐδºÏ²¢µ½Ö÷·Ö֧ʱ£¬Ðè½øÐж˵½¶Ë±¾µØ²âÊÔ£¬¿ª·¢ÈËÔ±Ìí¼ÓеĶ˵½¶Ë²âÊÔÓÃÀýÀ´Íê³É¹¦Äܼì²â¡£

»Ø¹é²âÊÔ£º¹¦ÄÜ´úÂëºÏ²¢µ½Ö÷·ÖÖ§ºó£¬Ðè½øÐж˵½¶Ë»Ø¹é²âÊÔ¡£¸Ã²âÊÔ CI ͨ³£ÔÚÒ¹¼äÔËÐУ¬²¢´¥·¢·¶Î§¸ü´óµÄ¶Ëµ½¶Ë²âÊÔÓÃÀý£¬ÒÔ°ïÖú¿ª·¢ÈËÔ±²éÕÒй¦ÄܵÄDZÔÚÓ°Ïì¡£

ºó¼ì²é²âÊÔ£º¸Ã¹¦ÄÜ·¢²¼µ½ÏßÉÏ»·¾³Ö®ºó£¬Ðè½øÐж˵½¶Ëºó¼ì²é²âÊÔ£¬ÒÔÈ·±£¸Ã¹¦ÄÜÔÚÏßÉÏ»·¾³ÈÔÄܰ´Ô¤ÆÚ¹¤×÷¡£

»ùÓÚÉÏÊöÇé¿ö£¬ÎªÁË×î´ó»¯¶Ëµ½¶Ë²âÊÔÓÃÀýµÄ¿ÉÖØÓÃÐÔ£¬²¢¿¼Âǵ½¹¹½¨±¾µØ E2E »·¾³µÄ¸´ÔÓÐÔ£¬ÎÒÃǽ« fixtures Ìí¼Óµ½ÎÒÃǵIJâÊÔÁ÷³ÌÖС£Fixtures ÊÇÔÚÈí¼þ²âÊÔ¹ý³ÌÖУ¬Îª²âÊÔÓÃÀý´´½¨ÆäËùÒÀÀµµÄǰÖÃÌõ¼þµÄ²Ù×÷»ò½Å±¾£¬ÕâЩǰÖÃÌõ¼þͨ³£»á¸ù¾Ý²»Í¬µÄ¶Ëµ½¶Ë²âÊÔ»·¾³¶ø±ä»¯¡£

ÀýÈ磬¼ÙÉèÏÖÓÐÒ»²âÊÔ³¡¾°£º¼ì²éÒ»¸öÌØ¶¨¶©µ¥µÄ״̬£¬¶ø¶©µ¥±àºÅÔÚÏßÉÏ»·¾³ºÍ¿ª·¢»·¾³ÖпÉÄÜÓÐËù²»Í¬£¬¶øÇÒ³ýÁ˶©µ¥±àºÅ£¬ºÍ¶©µ¥Ïà¹ØµÄһЩÆäËüÐÅÏ¢Ò²²»Í¬£¬´Ëʱ¾Í¿ÉÒÔʹÓà fixtures¡£

Cypress-tag

ÔÚ½« fixtures ÓÃÓÚÿ¸ö²âÊÔÁ÷³ÌÖ®ºó£¬»¹Ð迼ÂÇÒ»ÖÖÇéÐΣ¬¼´²»Í¬µÄ»·¾³ÏÂÐèÒªÔËÐеIJâÊÔÓÃÀý¿ÉÄܲ»Í¬¡£¶ÔÓÚÏßÉÏ»·¾³µÄºó¼ì²é²âÊÔ£¬ÐèÒªÔËÐÐ×î¸ß¼¶±ðµÄ P1 ²âÊÔÓÃÀý£»¶ÔÓÚÈÕ³£¶Ëµ½¶Ë»Ø¹é²âÊÔ£¬ÐèÒªÔËÐÐһЩ¸ü´ó·¶Î§µÄ²âÊÔÓÃÀý¡£ÎªÂú×ã´ËÒªÇ󣬺ËÐÄÒµÎñÍŶÓΪ Cypress Ìí¼ÓÁ˱êÇ©¹¦ÄÜ£¬ÒÔ¶Ô²âÊÔÓÃÀý½øÐзÖÀà¡£

Cypress ²âÊÔÓÃÀý

ÏÂÃæÍ¨¹ýÀý×Ó¼òµ¥ËµÃ÷ fixtures ºÍ tag ÔÚ cypress ²âÊÔÓÃÀýÖеÄʹÓá£

//fixtureÓÃÀ´±íÃ÷ÊÇÔÚʲô»·¾³ÏÂÖ´ÐвâÊÔÓÃÀý
const fixture = {
prd: {
networkInfo: Cypress.env('prdTestNetWorkInfo'),
campaignId: 26341381
},
stg: {
networkInfo: Cypress.env('stgTestNetWorkInfo'),
campaignId: 26341381
},
dev: {
networkInfo: Cypress.env('localNetWorkInfo'),
campaignId: 133469319
}
};
const { networkInfo, campaignId, brandId } = fixture[Cypress.env('TEST_ENV')];
let insertionOrderId;
//tagÓÃÀ´±íÃ÷ÕâÊÇÒ»¸öP1µÄ²âÊÔÓÃÀý
Cypress.withTags(describe, [io, create', 'p1'])(
'Create IO', function() {
before(function() {
cy
.loginByUI(networkInfo, `/campaigns/${campaignId}/edit `)
.waitUntilLoaded();
});

it('Create an empty insertion Order', function() {
cy.createEmptyIO()
.get('{insertion_order_id}:eq(0)')
.invoke('text')
.then(ioId => {
insertionOrderId = ioId;
});
});
¡­
after(function() {
cy.deleteInsertionOrder({ insertionOrderId });
});

afterEach(function() {
cy.saveResult(this.currentTest, testOwner);
if (this.currentTest.state === 'failed') {
Cypress.runner.stop();
}
});
});

ͨ¹ýʹÓà Cypress ½øÐж˵½¶Ë²âÊÔ£¬ÎÒÃÇʵÏÖÁËÒÔÏÂÄ¿±ê£º

Ìæ»»ÏûºÄÐÔµÚÈý·½¹¤¾ß£¨Èç Selenium£©£¬´ó´ó¼õÉÙÁË×¼±¸ºÍÔËÐж˵½¶Ë²âÊÔÓÃÀýËùÐèµÄʱ¼ä£»

Ò»´Î±àд²âÊÔÓÃÀý£¬Í¨¹ýʹÓà fixture ¿ÉʵÏÖÔÚ²»Í¬µÄ»·¾³£¨ÏßÉÏ/±¾µØ¿ª·¢£©ÖÐÔËÐУ»

¿ÉÖØÓõÄ×Ô¶¨ÒåÃüÁîʹ¿ª·¢ÈËÔ±¿ÉÒÔ¿ìËÙÍê³É²âÊÔÓÃÀý£»

¼ò¶ÌÒ×ÓõIJâÊÔ±¨¸æ°üÀ¨ÊÓÆµ±¨¸æ£¬¿É¿ìËÙµ÷ÊÔʧ°ÜµÄ²âÊÔÓÃÀý£»

ÉèÖöÀÁ¢µÄ²âÊԹܵÀºÍ²âÊÔ±êÇ©£¬ÒÔÈ·±£Ã¿¸ö×é¼þ½ö¿¼ÂÇ×Ô¼ºµÄÇé¿ö¡£

ÐÔÄܲâÊÔ

ÐÔÄܲâÊÔÊÇָͨ¹ý×Ô¶¯»¯µÄ²âÊÔ¹¤¾ßÄ£Äâ¶àÖÖÕý³£¡¢·åÖµÒÔ¼°Òì³£¸ºÔØÌõ¼þÀ´¶ÔϵͳµÄ¸÷ÏîÐÔÄÜÖ¸±ê½øÐвâÊÔ£¬Ö÷ҪʹÓà Loadrunner¡¢JMeter µÈ¹¤¾ß¶ÔÈí¼þ½øÐÐѹÁ¦²âÊÔ¡¢¸ºÔزâÊÔ¡¢Ç¿¶È²âÊԵȣ¬ÒòΪÕâЩ²âÊÔ¹ý³ÌÄÑÒÔÓÃÊÖ¹¤´úÌæ£¬ËùÒÔ±ØÐë×Ô¶¯»¯¡£ºËÐÄÒµÎñÍŶÓÑ¡ÔñÁË JMeter ×÷Ϊ²âÊÔ¹¤¾ß£¬²¢Ê¹Óà Taurus À´ÔËÐÐ JMeter¡£Taurus Äܹ»Ö±½Ó½âÎöÔ­Éú½Å±¾£¬Èç JMeter JMX Îļþ£¬Í¬Ê±»¹Ö§³ÖʹÓüòµ¥ÅäÖÃÓï·¨½«²âÊÔ³¡¾°Ê¹Óà YAML »ò JSON À´ÃèÊö JMeter ½Å±¾¡£

Taurus Yaml ½Å±¾Àý×Ó£º

execution:
- concurrency: 1 //²¢·¢Ïß³ÌÊý
iterations: 1 //Ö´ÐдÎÊýÏÞÖÆ
ramp-up: 5s //Æô¶¯Ê±¼ä
hold-for: 30s //³ÖÐøÊ±¼ä
scenario: get-rfps //²âÊÔ³¡¾°

modules:
jmeter:
properties:
host: docker.for.mac.localhost
port: 3070

scenarios: //²âÊÔcaseÃèÊö
get-rfps:
headers:
¡­//some code¡­
variables:
¡­//some code¡­
requests:
- url: http://${__P(host)}:${__P(port)}/.../rfps
method: GET

reporting:
- module: console
- module: final-stats
percentiles: true //ÏÔʾƽ¾ùʱ¼äºÍ°Ù·Ö±È
test-duration: true //²âÊÔʱ¼ä
dump-csv: perf_result_csv.csv
- module: junit-xml
filename: junit-result.xml

settings:
artifacts-dir: TaurusResult

ͬʱÎÒÃÇ´´½¨ Jenkins pipeline ²¢¶¨ÆÚ½øÐвâÊÔ£¬Éú³É performance trend ±¨¸æ£¬ÈçÏÂͼËùʾ£º

ͨ¹ýÐÔÄܲâÊÔ£¬ºËÐÄÒµÎñÍŶӴﵽÁËÒÔÏÂÄ¿±ê£º

¹Ø×¢¸ºÔزâÊÔ£¬¼ì²éÓ¦ÓóÌÐòÔÚÔ¤ÆÚÓû§¸ºÔØÏÂÔËÐеÄÄÜÁ¦£¬ÒÔÔÚÓ¦ÓóÌÐòͶÈëʹÓÃǰȷ¶¨ÆäÐÔÄÜÆ¿¾±£»

ÌṩһÖÖ¹Û²ìÓ¦ÓóÌÐòÐÔÄÜÇ÷ÊÆµÄ·½·¨£»

ͳһ²¢¼ò»¯ÐÔÄܲâÊÔµÄʵÏÖºÍÔËÐС£

²âÊÔ×Ô¶¯»¯

ΪÁËÌá¸ß¿ª·¢Ð§ÂÊ£¬¼°Ôç·¢ÏÖÎÊÌ⣬¼õÉÙÖØ¸´ÐÔÀͶ¯£¬ÊµÏÖ²âÊÔ×Ô¶¯»¯£¬ºËÐÄÒµÎñÍŶӼ¯³ÉÁË Jenkins£¬²ÉÓà Jenkins Pipeline µÄ·½Ê½½øÐÐ CI/CD¡£

CI ½×¶Î²âÊÔ

CI ²âÊԵĴ¥·¢µãÒ»°ãÓÐÁ½¸ö£º

´úÂëºÏ²¢µ½Ö÷¸Éǰ£¬´¥·¢ CI ²âÊÔ£¬¸÷ÖÖ¼ì²éºÍ²âÊÔͨ¹ýÖ®ºó£¬´úÂë²ÅÔÊÐí±»ºÏ²¢µ½Ö÷¸É·ÖÖ§£»

´úÂëºÏ²¢µ½Ö÷¸Éºó£¬´¥·¢ CI ²âÊÔ£¬Ä¿µÄÊÇΪÁ˼ìÑéÖ÷¸É·ÖÖ§ÊÇ·ñ·ûºÏÖÊÁ¿Ô¤ÆÚ¡£

ÉÏͼÊÇÓÉ pipeline groovy ½Å±¾¶¨ÒåµÄ Jenkins Á÷Ë®Ïß blue ocean Ч¹ûͼ£¬ÏÂÃæ½«½áºÏÀý×Ó¶Ô²âÊÔÏà¹ØµÄ¼¸¸öÖØÒª½×¶Î½øÐзÖÎö¡£

UT& Coverage

Ôڴ˽׶ÎÎÒÃÇ¿ÉÒÔ»ñÈ¡µ¥Ôª²âÊÔ¸²¸ÇÂʱ¨¸æ¡£²âÊÔ¸²¸ÇÂʵı¨¸æ»ñÈ¡ºÜ¼òµ¥£¬Ö»ÐèÔÚ steps ÖÐÖ¸¶¨Åܵ¥Ôª²âÊÔʹÓõĽű¾£¬²¢Ôڽű¾ÖаÑÉú³É¸²¸ÇÂʵĿª¹Ø´ò¿ª£¬½«Éú³ÉµÄ½á¹ûÊä³öµ½ÎļþÖС£

stage('UT & Coverage'){
¡­//some code¡­
environment {
core_common = get_core_common(serviceFullName)
//»ñÈ¡ut²âÊÔ¸²¸ÇÂʱ¨¸æ
ut_cobertura_report_file = get_ut_cobertura_report_file(serviceFullName)
}
steps {
//specify shell script to execute ut cases
sh(returnStdout: true, script: "sh ${WORKSPACE}/shell_scripts/unit_coverage.sh")
}
post {
success {
//Èç¹û³É¹¦£¬Éú³Éut²âÊÔ¸²¸ÇÂÊHTML¸ñʽµÄ±¨¸æ
archiveArtifacts allowEmptyArchive: true, artifacts: ut_cobertura_report_file, fingerprint: true
sh 'echo "ci.ut.result=PASS" >> ${WORKSPACE}/env.props'
}
}
}

Regression

Ôڴ˽׶ÎÎÒÃÇ¿ÉÒÔ»ñÈ¡ regression ²âÊÔ¸²¸ÇÂʱ¨¸æ¡£²âÊÔ¸²¸ÇÂʵı¨¸æ»ñÈ¡ºÜ¼òµ¥£¬Ö»ÐèÔÚ steps ÖÐÖ¸¶¨ÅÜ regression ʹÓõĽű¾£¬½«Éú³ÉµÄ½á¹ûÊä³öµ½ÎļþÖС£

stage('Regression'){
environment {
¡­//some code¡­
html_report_dir = get_report_dir(serviceFullName)
//»ñÈ¡regression²âÊÔ¸²¸ÇÂʱ¨¸æ
regression_cobertura_report_file = get_regression_cobertura_report_file(serviceFullName)
diff_files = "${WORKSPACE}/diff/*"
}
steps {
sh '''
mysql -uroot -proot -h127.0.0.1 -e "source ${WORKSPACE} /sql/ui_permission_sql.sql"
//regression ²âÊÔÊý¾Ý×¼±¸
${WORKSPACE} /integration_test_data/bin/initDB.sh
//regression ²âÊÔ»·¾³×¼±¸
${WORKSPACE} /shell_scripts/regression_init.sh
if [[ ! -d ${html_report_dir} ]]; then
mkdir ${html_report_dir}
fi
'''
//Ö¸¶¨regression ²âÊÔÓÃÀýµÄÖ´Ðнű¾
sh "${WORKSPACE} /regression_scripts/$ {serviceFullName}_regression.sh"
}
post {
success {
¡­//some code¡­
}
}
}

Coverage& Analyze

ΪÁ˱£Ö¤²âÊԵĸßÖÊÁ¿ºÍ¸ß¸²¸ÇÂÊ£¬ÎÒÃÇͨ¹ý Groovy ½Å±¾ÉèÖÃÁ˲âÊÔ¸²¸ÇÂʵÄÄ¿±ê£¬²âÊÔ½á¹ûʧ°Ü»òÕ߸²¸ÇÂÊûÓдï±êµÄºÏ²¢´úÂëÇëÇó¾ù²»ÄÜͨ¹ý£¬²¢ÇÒ»áͨ¹ý slack ֪ͨÏà¹ØÈËÔ±¡£

stage('Coverage & Analyze'){
¡­//some code¡­
post {
success {
//ÅжÏÊÇ·ñ´ïµ½²âÊÔ¸²¸ÇÂÊÄ¿±ê
cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: combined_cobertura_report_file, conditionalCoverageTargets: '70, 0, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '80, 0, 0', maxNumberOfBuilds: 0, methodCoverageTargets: '80, 0, 0', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false
archiveArtifacts allowEmptyArchive: true, artifacts: "${html_report_dir}/*.json", fingerprint: true
}
}
}
post {
failure {
//Èç¹ûûÓдﵽ£¬Ôòͨ¹ýslack·¢ËÍÐÅϢ֪ͨÏà¹ØÈËÔ±
slackSend channel: "#${slack_channel}",color: "danger", message: "AWS Build FAIL! :bomb: ${serviceFullName} <${BUILD_URL}|${BUILD_DISPLAY_NAME}> ${currentBuild.description}"
}
}

ͬʱ£¬ÎÒÃÇÒ²»áÊÕ¼¯µ¥Ôª²âÊԺͼ¯³É²âÊԵIJâÊÔ¸²¸ÇÂʲ¢Í¨¹ýÓʼþ·¢ËÍ֪ͨ£¬Ò²Æðµ½¶½´ÙºÍ¾¯Ê¾×÷Óá£

CD ½×¶Î²âÊÔ

²úÆ·±»²¿Êðµ½ÏßÉÏÖ®ºó£¬Í¨¹ý Pipeline ¹ØÁª´¥·¢¹¦ÄÜ´¥·¢¶Ëµ½¶Ë²âÊ﵀ Jenkins job£¬½øÐвúÆ·ÉÏÏßÖ®ºóµÄÏà¹Ø²âÊÔ¡£

¶Ëµ½¶Ë²âÊÔ

Cypress Ö§³ÖºÍ Jenkins ½øÐм¯³É£¬ÎÒÃÇÉèÖÃÁ˲»Í¬µÄ Jenkins job£¬ÓеÄÓÃÀ´½øÐÐÈÕ³£µÄ¶Ëµ½¶Ë»Ø¹é²âÊÔ£¬ÓеÄÓÃÀ´½øÐÐÏßÉÏ»·¾³µÄ¶Ëµ½¶Ë²âÊÔ£¬²¢Í¨¹ý groovy ½Å±¾ÉèÖý«²âÊÔ½á¹ûͬʱͨ¹ýÓʼþºÍ slack ·¢³ö£¬¼«´óµÄ½µµÍÁ˳ö´í²âÊÔÓÃÀýµÄÏìӦʱ¼ä£¬Ìá¸ßÁ˲úÆ·ÖÊÁ¿¡£

pipeline {
¡­//some code¡­
post {
success {
publishReport()
notifySuccess()
sendMail()
}
//Èç¹û¶Ëµ½¶Ë²âÊÔÓÃÀýʧ°Ü£¬Ôò·¢ËÍÓʼþºÍslackÐÅϢ֪ͨÏà¹ØÈËÔ±
failure {
publishReport()
archiveArtifacts artifacts: 'screenshots/**, videos/**'
notifyFail()
sendMail()
}
}
}

ÆäËûÖÊÁ¿±£Ö¤´ëÊ©

Bug Bash

ºËÐÄÒµÎñÍŶÓÓÐÒ»¸öºÜÓÐȤµÄÌØÉ«´«Í³»î¶¯£ºÔÚ²úÆ·ÉÏÏßǰµÄij¸öÌØ¶¨Ê±¼äµã£¬»á×éÖ¯¿ç team µÄ´óÐÍÕÒ bug »î¶¯£¬ÑûÇë´ó¼ÒÒ»Æð¶Ô²úÆ·½øÐвâÊÔ£¬²¢ÒÀ¾ÝÕÒ³ö Bug ÊýÁ¿µÄ¶àÉÙ½øÐÐÆÀ±ÈºÍ½±Àø¡£Ò»·½Ãæ¿ÉÒÔÔö¼Ó´ó¼ÒµÄÒµÎñ֪ʶ£¬ÔÚ²âÊÔʱѧϰ×ÔÉí¹¤×÷·¶³ëÖ®ÍâµÄÆäËü¹¦ÄÜÄ£¿é£¬ÁíÒ»·½ÃæÒ²¿ÉÒÔÌáǰ·¢ÏÖÒþ²ØµÄ bug£¬½øÒ»²½Ìá¸ß²úÆ·ÖÊÁ¿¡£

Bug Bash Tool

Bug bash tool רÃÅ·þÎñÓÚÎÒÃÇµÄ Bug Bash »î¶¯£¬ÓÃÀ´Í³¼ÆÃ¿¸öÈË·¢ÏÖµÄ bug ÊýÁ¿¡£ÈçͼËùʾ£¬¸ù¾Ý²»Í¬µÄÖ¸±ê¶Ô·¢ÏÖµÄ bug ½øÐÐͳ¼Æ£¬²¢Í¨¹ý¶ÔÕâЩÊý¾ÝµÄ·ÖÎöÌáÁ¶³öһЩÓÐÖúÓÚÌá¸ß²úÆ·ÖÊÁ¿µÄ·½·¨¡£¶ÔÓÚÃûÁÐǰéµÄ bug finder£¬ÍÅ¶Ó»á¸øÓè·áºñµÄ½±Àø£¬Ìá¸ß´ó¼ÒÕÒ bug µÄ»ý¼«ÐÔ¡£

δÀ´Õ¹Íû

Ëæ×Å FreeWheel ÒµÎñ·¶Î§µÄ²»¶ÏÀ©´óºÍÒµÎñ¸´ÔӶȵijÖÐøÌáÉý£¬Èí¼þ²âÊÔÒ²ÐèÒª²»¶ÏÍêÉÆÒÔ±£Ö¤²úÆ·µÄ¸ßÖÊÁ¿¡£ÀýÈ磬½øÒ»²½ÌáÉýµ¥Ôª²âÊԺͼ¯³É²âÊԵĴúÂ븲¸ÇÂÊ£¬Íƹã»ùÓÚ Cypress µÄ¶Ëµ½¶Ë²âÊԺͻùÓÚ Jmeter µÄÐÔÄܲâÊÔ¡£´ËÍ⣬ÍŶӻ¹½«¸ù¾ÝÒµÎñ·¢Õ¹ÐèÇ󣬳ÖÐø¿ªÕ¹Ç°Ñص÷Ñкͼ¼Êõ´´Ð£¬ÒÔ¸ü¸ßЧ¡¢È«Ãæ¡¢ÏȽøµÄÈí¼þ²âÊÔÊÖ¶ÎΪ²úÆ·ÖÊÁ¿±£¼Ý»¤º½¡£

 
   
2010 ´Îä¯ÀÀ       32
Ïà¹ØÎÄÕÂ

ÆóÒµ¼Ü¹¹¡¢TOGAFÓëArchiMate¸ÅÀÀ
¼Ü¹¹Ê¦Ö®Â·-ÈçºÎ×öºÃÒµÎñ½¨Ä££¿
´óÐÍÍøÕ¾µçÉÌÍøÕ¾¼Ü¹¹°¸ÀýºÍ¼¼Êõ¼Ü¹¹µÄʾÀý
ÍêÕûµÄArchimateÊÓµãÖ¸ÄÏ£¨°üÀ¨Ê¾Àý£©
Ïà¹ØÎĵµ

Êý¾ÝÖÐ̨¼¼Êõ¼Ü¹¹·½·¨ÂÛÓëʵ¼ù
ÊÊÓÃArchiMate¡¢EA ºÍ iSpace½øÐÐÆóÒµ¼Ü¹¹½¨Ä£
ZachmanÆóÒµ¼Ü¹¹¿ò¼Ü¼ò½é
ÆóÒµ¼Ü¹¹ÈÃSOAÂ䵨
Ïà¹Ø¿Î³Ì

ÔÆÆ½Ì¨Óë΢·þÎñ¼Ü¹¹Éè¼Æ
ÖÐ̨սÂÔ¡¢ÖÐ̨½¨ÉèÓëÊý×ÖÉÌÒµ
ÒÚ¼¶Óû§¸ß²¢·¢¡¢¸ß¿ÉÓÃϵͳ¼Ü¹¹
¸ß¿ÉÓ÷ֲ¼Ê½¼Ü¹¹Éè¼ÆÓëʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
 
×îÐÂÎÄÕÂ
´óÊý¾Ýƽ̨ϵÄÊý¾ÝÖÎÀí
ÈçºÎÉè¼ÆÊµÊ±Êý¾Ýƽ̨£¨¼¼Êõƪ£©
´óÊý¾Ý×ʲú¹ÜÀí×ÜÌå¿ò¼Ü¸ÅÊö
Kafka¼Ü¹¹ºÍÔ­Àí
ELK¶àÖּܹ¹¼°ÓÅÁÓ
×îпγÌ
´óÊý¾Ýƽ̨´î½¨Óë¸ßÐÔÄܼÆËã
´óÊý¾Ýƽ̨¼Ü¹¹ÓëÓ¦ÓÃʵս
´óÊý¾ÝϵͳÔËά
´óÊý¾Ý·ÖÎöÓë¹ÜÀí
Python¼°Êý¾Ý·ÖÎö
³É¹¦°¸Àý
ijͨÐÅÉ豸ÆóÒµ PythonÊý¾Ý·ÖÎöÓëÍÚ¾ò
Ä³ÒøÐÐ È˹¤ÖÇÄÜ+Python+´óÊý¾Ý
±±¾© Python¼°Êý¾Ý·ÖÎö
ÉñÁúÆû³µ ´óÊý¾Ý¼¼Êõƽ̨-Hadoop
ÖйúµçÐÅ ´óÊý¾Ýʱ´úÓëÏÖ´úÆóÒµµÄÊý¾Ý»¯ÔËӪʵ¼ù