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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
×Ô¶¯»¯µ¥Ôª²âÊÔʵ¼ù֮·
 
×÷Õß ÀîÀÖ£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-07-28
  4602  次浏览      29
 

×Ô¶¯»¯µ¥Ôª²âÊÔ²¢²»ÊÇʲôÐÂÏÊÊÂÎËüÓ¦¸ÃÊÇÍŶӳÖÖ®ÒÔºãµÄÊÂÇ飬¿ÉÄÜÓкܶàÍŶÓÖªµÀÈçºÎÈ¥×ö£¬µ«ÊÇ»¹×öµÃ²»¹»ºÃ£»»¹Óв»ÉÙÍŶӲ»ÖªµÀÈçºÎÈ¥×ö£¬ÉõÖÁÓÐһЩ¾Éϵͳ»¹²»¸ÒÈ¥ÖØ¹¹£¬»¹ÔÚ¼á³Ö×ÅJavaÖеÄmain·½·¨µ÷Óõķ½Ê½À´Ö´ÐУ¬ÔÚÂþ³¤µÈ´ý¹¹½¨½á¹û¡£

±¾ÎÄÖ÷Òª½²»ùÓÚJavaÏîÄ¿ÈçºÎ×ö×Ô¶¯»¯µ¥Ôª²âÊÔµÄʵ¼ù¡£

1 ÊÇ·ñÖµµÃ

TestPyramid£¬ÈçÏÂͼËùʾ£º

ͼ-1-1-TestPyramid

UnitÊÇÕû¸ö½ð×ÖËþµÄ»ùʯ£¨ÔÚ½¨ÖþÐÐÒµ£¬»ùʯÊÇ×ö½¨ÖþÎï»ù´¡µÄʯͷ£©£¬Èç¹û»ùʯ²»ÎÈ£¬ServiceºÍUIºÎ̸Óй¹½¨ÒâÒåÄØ£¿Ö»ÓлùʯÎÈÈçÅÍʯ£¬Éϲ㽨Öþ²Å¹»¼á¹Ì¡£

±¾À´ÏëÄÃÈðÊ¿×öÖÓ±íµÄÀý×ÓÀ´ËµÃ÷Ï£¬µ«Í¬ÊÂ˵µÄÆû³µÀý×Ó¸üºÃ¡£Ò»Á¾Æû³µÓÉÐí¶àÅä¼þ×é³É£¬Èç¹ûÓÐÒÔÏÂÁ½ÖÖÑ¡Ôñ£¬Äã»áÑ¡ÔñÄĸöÄØ£¿

ËùÓе¥ÔªÅä¼þûÓвâÊÔ¹ý£¬ÔÚ4Sµê£¬ÏúÊÛÈËÔ±¸æËßÄ㣺¸Õ×é×°ºÃ£¬ÒѾ­¿ªÁËÒ»Ì죬ÄÜÅÜÆðÀ´£¬Äã¿ÉÒÔÊÔÊÔ£»
ËùÓе¥ÔªÅä¼þÔÚÉú²ú¹ý³ÌÒѾ­¾­¹ýÑϸñ²âÊÔ£¬ÔÚ4Sµã£¬ÏúÊÛÈËÔ±¸æËßÄ㣬ÒѾ­Í¨¹ý¹ú¼ÒÈÏÖ¤£¬³ö³§ºÏ¸ñ£¬ÓÐÖÊÁ¿±£Ö¤£¬Äã¿ÉÒÔÊÔÊÔ£»
´ð°¸²»ÑÔ¶øÓ÷ÁË¡£

ʵʩµ¥Ôª²âÊÔ£¬²¢²»´ú±íÄãµÄÉú²úЧÂÊÄÜÌá¸ßѸÃÍ£¬·´¶øÓÐʱºò×è°­ÁË˲¼äµÄÉú²úЧÂÊ£¨´«Í³µÄ¿ª·¢Ò»¸ö¹¦ÄÜ£¬¿´ËƾÍËãÍê³ÉµÄ¶¯×÷£¬Ôö¼Óµ¥Ôª²âÊÔ¿´ÆðÀ´ÎÞ·¨ÊÇÀË·Ñʱ¼ä£©£¬µ«ÊÇ£¬Ëü×îÖ±½ÓµÄÊÇÌáÉý²úÆ·ÖÊÁ¿£¬´Ó¶øÌáÉýÊг¡µÄÐÎÏ󣬼ä½Ó²Å»áÌáÉýÉú²úЧÂÊ¡£

×ö²úÆ·£¬µ½µ×ÊÇÒªÊýÁ¿£¬»¹ÊÇÖÊÁ¿ÄØ£¿Õâ¸öÓ¦¸ÃÁô¸øÀϰåÃÇÈ¥»Ø´ð£¬¿´ÆóÒµÊÇ·ñÐèÒª³¤Ô¶Á¢×ã¡£

2 ¹Ø¼ü²¿·Ö

×Ô¶¯»¯µ¥Ôª²âÊÔÓÐËĸö¹Ø¼ü×é³É²¿·ÖÒª×öµ½Í³Ò»£¬ÈçͼËùʾ£º

ͼ-2-1-¹Ø¼ü×é³É²¿·Ö

ÅäÖùÜÀí£ºÊ¹Óð汾¿ØÖÆ

°æ±¾¿ØÖÆÏµÍ³£¨Ô´´úÂë¿ØÖÆ¹ÜÀíϵͳ£©ÊDZ£´æÎļþ¶à¸ö°æ±¾µÄÒ»ÖÖ»úÖÆ¡£Ò»°ãÀ´Ëµ£¬°üÀ¨Subversion¡¢GitÔÚÄڵĿªÔ´¹¤¾ß¾Í¿ÉÒÔÂú×ã¾ø´ó¶àÊýÍŶӵÄÐèÇó¡£ËùÓеİ汾¿ØÖÆÏµÍ³¶¼ÐèÒª½â¾öÕâÑùÒ»¸ö»ù´¡ÎÊÌâ: ÔõÑùÈÃϵͳÔÊÐíÓû§¹²ÏíÐÅÏ¢£¬¶ø²»»áÈÃËûÃÇÒòÒâÍâ¶ø»¥Ïà¸ÉÈÅ£¿

Èç¹ûûÓа汾¿ØÖƹ¤¾ßµÄЭÖú£¬ÔÚ¿ª·¢ÖÐÎÒÃǾ­³£»áÓöµ½ÏÂÃæµÄһЩÎÊÌ⣺

Ò»¡¢ ´úÂë¹ÜÀí»ìÂÒ¡£

¶þ¡¢ ½â¾ö´úÂë³åÍ»À§ÄÑ¡£

Èý¡¢ ÔÚ´úÂëÕûºÏÆÚ¼äÒýÈëÉî²ãBUG¡£

ËÄ¡¢ ÎÞ·¨¶Ô´úÂëµÄÓµÓÐÕß½øÐÐȨÏÞ¿ØÖÆ¡£

Îå¡¢ ÏîÄ¿²»Í¬°æ±¾·¢²¼À§ÄÑ¡£

¶ÔËùÓÐÄÚÈݶ¼½øÐа汾¿ØÖÆ

°æ±¾¿ØÖƲ»½ö½öÕë¶ÔÔ´´úÂ룬ÿ¸öÓëËù¿ª·¢µÄÈí¼þÏà¹ØµÄ²úÎï¶¼Ó¦¸Ã±»ÖÃÓÚ°æ±¾¿ØÖÆÏ£¬Ó¦µ±°üÀ¨£ºÔ´´úÂë¡¢²âÊÔ´úÂë¡¢Êý¾Ý¿â½Å±¾¡¢¹¹½¨ºÍ²¿Êð½Å±¾¡¢Îĵµ¡¢webÈÝÆ÷£¨tomcatµÄÅäÖã©ËùÓõÄÅäÖÃÎļþµÈ¡£

±£Ö¤Æµ·±Ìá½»¿É¿¿´úÂëµ½Ö÷¸É

Ƶ·±Ìá½»¿É¿¿¡¢ÓÐÖÊÁ¿±£Ö¤µÄ´úÂ루±àÒëͨ¹ýÊÇ×î»ù±¾ÒªÇ󣩣¬Äܹ»ÇáËɻعöµ½×î½ü¿É¿¿µÄ°æ±¾£¬´úÂëÌá½»Ö®ºóÄܹ»´¥·¢³ÖÐø¼¯³É¹¹½¨£¬¼°Ê±µÃµ½·´À¡¡£

Ìá½»ÓÐÒâÒåµÄ×¢ÊÍ

Ç¿ÖÆÒªÇóÍŶӳÉԱʹÓÃÓÐÒâÒå×¢ÊÍ£¬ÉõÖÁ¿ÉÒÔ¹ØÁªÏà¹Ø¿ª·¢ÈÎÎñµÄÔ­ÒòÊÇ£ºµ±¹¹½¨Ê§°Üºó£¬ÄãÖªµÀÊÇË­ÆÆ»µÁ˹¹½¨£¬ÕÒµ½¿ÉÄܵÄÔ­Òò¼°¶¨Î»È±ÏÝλÖá£ÕâЩ¸½¼ÓÐÅÏ¢£¬¿ÉÒÔËõ¶ÌÎÒÃÇÐÞ¸´È±ÏݵÄʱ¼ä¡£Ê¾Àý£ºÍŶÓʹÓÃÁËsvnºÍredmine£¬×¢ÊÍÊÇ£º

refs #ÈÎÎñid Ìύ˵Ã÷

ÿ¸öÈÎÎñÏ¿ÉÒÔ¿´µ½¶à´ÎÌá½»¼Ç¼£º

ͼ-2-2-Ïà¹ØÐÞ¶©°æ±¾

1.ËùÓеĴúÂëÎļþ±àÂë¸ñʽͳһʹÓÃUTF-8

2.Éϰàǰ¸üдúÂ룬ϰàǰÌá½»´úÂë

ǰһÌ죬ÍŶӯäËû³ÉÔ±¿ÉÄÜÌá½»ÁËÐí¶à´úÂëµ½svn£¬¿ªÊ¼ÐµÄÒ»Ì칤×÷ÊÇ£¬Îñ±Ø¸üе½×îа汾£¬¼°Ê±·¢ÏÖÎÊÌ⣨ÀýÈç´úÂë³åÍ»£©²¢½â¾ö£»

µ±ÈÕÊ£¬µ±Èձϣ¬Ï°à±ð°Ñµ±ÌìµÄ±àÂë³É¹û½ö±£´æÔÚ±¾µØ£¬Ó¦µ±Ìá½»µ½svn£¬´ÎÈÕÍŶӸüоͿÉÒÔ»ñÈ¡µ½×îа汾£¬ÐγÉÁ¼ÐÔÑ­»·¡£

¹¹½¨¹ÜÀí£ºÊ¹ÓÃMaven¹¹½¨¹¤¾ß

MavenÊÇ»ùÓÚÏîÄ¿¶ÔÏóÄ£ÐÍ(POM)£¬Í¨¹ýΪJavaÏîÄ¿µÄ´úÂë×éÖ¯½á¹¹¶¨ÒåÃèÊöÐÅÏ¢À´¹ÜÀíÏîÄ¿µÄ¹¹½¨¡¢±¨¸æºÍÎĵµµÄÈí¼þÏîÄ¿¹ÜÀí¹¤¾ß¡£Ê¹Óá°¹ßÀýʤÓÚÅäÖá±£¨convention over configuration£©µÄÔ­Ôò£¬Ö»ÒªÏîÄ¿°´ÕÕMavenÖÆ¶¨µÄ·½Ê½½øÐÐ×éÖ¯£¬Ëü¾Í¼¸ºõÄÜÓÃÒ»ÌõÃüÁîÖ´ÐÐËùÓеĹ¹½¨¡¢²¿Êð¡¢²âÊÔµÈÈÎÎñ£¬È´²»ÓÃдºÜ¶àÐеÄXML£¨Ïû³ýAntÎļþÖдóÁ¿µÄÑù°åÎļþ£©¡£

»òÐí£¬Ê¹ÓÃAntÀ´¹¹½¨µÄÍŶÓÒªÎÊ£¬ÎªÊ²Ã´ÓÃMavenÄØ£¿¼òµ¥À´ËµÁ½µã

1¡¢¶ÔµÚÈý·½ÒÀÀµ¿â½øÐÐͳһµÄ°æ±¾¹ÜÀí

˵ʵ»°£¬ant´¦ÀíÒÀÀµ°üÖ®¼äµÄ³åÍ»ÎÊÌ⣬»¹Êǵÿ¿È˹¤½â¾ö£¬Õâ¸ö¶ÔÓÚÑз¢À´ËµÊÇÏûºÄʱ¼äµÄ£¬µ¹²»Èç°Ñ½ÚÊ¡µÄʱ¼äͶÈëµ½ÒµÎñÖÐÈ¥¡£ÁíÍâÔÙÒ²²»ÓÃÿ¸öÏîÄ¿·±Ëö¸´ÖÆspring.jarÁË£¬Í¨¹ýmaven×Ô¶¯¹ÜÀíJava¿âºÍÏîÄ¿¼äµÄÒÀÀµ£¬´ò°üµÄʱºò»á½«ËùÓÐjar¸´ÖƵ½WEB- INF/lib/Ŀ¼Ï¡£

2¡¢Í³Ò»ÏîÄ¿µÄĿ¼½á¹¹¡£

¹Ù·½µÄÔ¼¶¨£ºhttp://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

±£Ö¤ËùÓÐÏîÄ¿µÄĿ¼½á¹¹ÔÚÈκηþÎñÆ÷É϶¼ÊÇÒ»ÑùµÄ£¬Ã¿¸öĿ¼Æðʲô×÷Óö¼ºÜÇå³þÃ÷ÁË¡£

3¡¢Í³Ò»Èí¼þ¹¹½¨½×¶Î

http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

Maven2°ÑÈí¼þ¿ª·¢µÄ¹ý³Ì»®·Ö³ÉÁ˼¸¸ö¾­µä½×¶Î£¬±ÈÈçÄãÏÈÒªÉú³ÉһЩjava´úÂ룬ÔÙ°ÑÕâЩ´úÂë¸´ÖÆµ½Ìض¨Î»Öã¬È»ºó±àÒë´úÂ룬¸´ÖÆÐèÒª·Åµ½classpathϵÄ×ÊÔ´£¬ÔÙ½øÐе¥Ôª²âÊÔ£¬µ¥Ôª²âÊÔ¶¼Í¨¹ýÁ˲ÅÄܽøÐдò°ü£¬·¢²¼¡£

²âÊÔ¿ò¼Ü£ºJUnit&Mockito

1¡¢JUnit

JUnitÊÇÒ»¸öJavaÓïÑԵĵ¥Ôª²âÊÔ¿ò¼Ü¡£

2013Äê¼û¹ýÒ»¸ö¾ÉÏîÄ¿£¬²âÊÔ´úÂ뻹ÊÇÒÔmain×÷ΪÈë¿Ú£¬ÎªÊ²Ã´ÒªÊ¹ÓÃJUnit£¿

JUnit µÄÓŵãÊÇÕû¸ö²âÊÔ¹ý³ÌÎÞÈËÖµÊØ£¬¿ª·¢ÎÞÐëÔÚÏß²ÎÓëºÍÅжÏ×îÖÕ½á¹ûÊÇ·ñÕýÈ·£¬¿ÉÒÔºÜÈÝÒ×µØÒ»´ÎÐÔÔËÐжà¸ö²âÊÔ£¬Ê¹µÃ¿ª·¢¸ü¼Ó¹Ø×¢²âÊÔÂß¼­µÄ±àд£¬¶ø²»ÊÇÔö¼Ó¹¹½¨Î¬»¤Ê±¼ä¡£

ÍŶÓʾÀý´úÂ룺

// ¹¦ÄÜ´úÂë
package com.chinacache.portal.service;
public class ReportService {
public boolean validateParams() {
}
public String sendReport(Long id) {
}
public String sendReport(Long id, Date time) {
}
}
// µ¥Ôª²âÊÔ´úÂë
package com.chinacache.portal.service; // ±ØÐëÓ빦ÄÜ´úÂëʹÓÃÏàͬ package
public class ReportServiceUnitTest { // ²âÊÔÀàÃûÒÔ UnitTest (µ¥Ôª²âÊÔ) »ò InteTest (¼¯³É²âÊÔ) ½áβ
// ²âÊÔ·½·¨ÃûÒÔ test ¿ªÍ·£¬È»ºó½Ó¶ÔÓ¦µÄ¹¦ÄÜ·½·¨Ãû³Æ
@Test
public void testValidateParams() {
}
// Èç¹û¹¦ÄÜ·½·¨´æÔÚÖØÔØ£¬ÔòÔÙ½ÓÉϲÎÊýÀàÐÍ
@Test
public void testSendReportLong() {
}
// Èç¹ûÒ»¸ö¹¦ÄÜ·½·¨¶ÔÓ¦¶à¸ö²âÊÔ·½·¨£¬²»Í¬²âÊÔ·½·¨¿ÉʹÓüò½à¶øÓÖÓк¬ÒåµÄµ¥´Ê½á⣬ÀýÈç success¡¢fail µÈ
@Test
public void testSendReportLongDateSuccess() {
}
// ÕâÑùͨ¹ý²âÊÔ·½·¨Ãû¼´¿ÉÖªµÀ£º²âµÄÊÇÄĸö¹¦ÄÜ·½·¨£¬ÄÄÖÖÇé¿ö
@Test
public void testSendReportLongDateFail() {
}
}

2¡¢Mockito

MockitoÊÇÒ»¸öÕë¶ÔJavaµÄmocking¿ò¼Ü¡£Ê¹ÓÃËü¿ÉÒÔд³ö¸É¾»Æ¯ÁÁµÄ²âÊÔÓÃÀýºÍ¼òµ¥µÄAPI¡£ËüÓëEasyMockºÍjMockºÜÏàËÆ£¬Í¨¹ýÔÚÖ´ÐкóУÑéʲôÒѾ­±»µ÷Óã¬Ïû³ýÁË¶ÔÆÚÍûÐÐΪ£¨expectations£©µÄÐèÒª£¬¸Ä±äÆäËûmocking¿âÒÔ¡°¼Ç¼-»Ø·Å¡±£¨Õâ»áµ¼Ö´úÂë³óª£©µÄ²âÊÔÁ÷³Ì£¬Ê¹µÃ×ÔÉíµÄÓï·¨¸üÏñ×ÔÈ»ÓïÑÔ¡£

MockitoʾÀý£º

List mock = mock(List.class);
when(mock.get(0)).thenReturn("one");
when(mock.get(1)).thenReturn("two");
someCodeThatInteractsWithMock();
verify(mock).clear();

EasyMockʾÀý£º

List mock = createNiceMock(List.class);
expect(mock.get(0)).andStubReturn("one");
expect(mock.get(1)).andStubReturn("two");
mock.clear();
replay(mock);
someCodeThatInteractsWithMock();
verify(mock);

¹Ù·½¶Ô±ÈÎÄÕ£ºhttp://code.google.com/p/mockito/wiki/MockitoVSEasyMock

·´À¡Æ½Ì¨£ºJenkins&Sonar

³ÖÐø¼¯³Éƽ̨£ºJenkins

Jenkins µÄǰÉíÊÇ Hudson ÊÇÒ»¸ö¿ÉÀ©Õ¹µÄ³ÖÐø¼¯³ÉÒýÇæ£¬Ö÷ÒªÓÃÓÚ£º

1.³ÖÐø¡¢×Ô¶¯µØ¹¹½¨²âÊÔÈí¼þÏîÄ¿

2.¼à¿ØÒ»Ð©¶¨Ê±Ö´ÐеÄÈÎÎñ

Jenkins½«×÷Ϊ×Ô¶¯»¯µ¥Ôª²âÊÔ³ÖÐø¼¯³ÉµÄƽ̨,ʵÏÖ×Ô¶¯»¯¹¹½¨¡£

ͼ-2-3-Jenkinsƽ̨

´úÂëÖÊÁ¿¹ÜÀíÆ½Ì¨£ºSonar

Sonar (SonarQube)ÊÇÒ»¸ö¿ªÔ´Æ½Ì¨£¬ÓÃÓÚ¹ÜÀíÔ´´úÂëµÄÖÊÁ¿¡£Sonar ²»Ö»ÊÇÒ»¸öÖÊÁ¿Êý¾Ý±¨¸æ¹¤¾ß£¬¸üÊÇ´úÂëÖÊÁ¿¹ÜÀíÆ½Ì¨¡£Ö§³ÖµÄÓïÑÔ°üÀ¨£ºJava¡¢PHP¡¢C#¡¢C¡¢Cobol¡¢PL/SQL¡¢Flex µÈ¡£

Ö÷ÒªÌØµã£º

1.´úÂ븲¸Ç£ºÍ¨¹ýµ¥Ôª²âÊÔ£¬½«»áÏÔʾÄÄÐдúÂ뱻ѡÖÐ

2.¸ÄÉÆ±àÂë¹æÔò

3.ËÑѰ±àÂë¹æÔò£º°´ÕÕÃû×Ö£¬²å¼þ£¬¼¤»î¼¶±ðºÍÀà±ð½øÐвéѯ

4.ÏîÄ¿ËÑѰ£º°´ÕÕÏîÄ¿µÄÃû×Ö½øÐвéѯ

5.¶Ô±ÈÊý¾Ý£º±È½ÏͬһÕűíÖеÄÈκβâÁ¿µÄÇ÷ÊÆ

Sonar½«×÷Ϊ×Ô¶¯»¯µ¥Ôª²âÊÔ·´À¡±¨¸æÍ³Ò»Õ¹ÏÖÆ½Ì¨£¬°üÀ¨£º

µ¥Ôª²âÊÔ¸²¸ÇÂÊ¡¢³É¹¦ÂÊ¡¢´úÂë×¢ÊÍ¡¢´úÂ븴ÔӶȵȶÈÁ¿Êý¾ÝµÄÕ¹ÏÖ¡£

ͼ-2-4 Sonarƽ̨

3 Ô­Ôò

×Ô¶¯»¯²âÊÔ½ð×ÖËþ£¬Ò²³ÆÎª×Ô¶¯»¯·Ö²ã²âÊÔ£¬UnitÊÇÕû¸ö½ð×ÖËþµÄ»ùʯ£¬×îÖØÒªÌØµãÊÇÔËÐÐËٶȷdz£¿ì£»µÚ¶þ¸öÖØÒªÌØµãÊÇUTÓ¦¸²¸Ç´úÂë¿âµÄ´ó²¿·Ö£¬Äܹ»È·¶¨Ò»µ©UTͨ¹ýºó£¬Ó¦ÓóÌÐò¾ÍÄÜÕý³£¹¤×÷¡£

Unit£º70%£¬´ó²¿·Ö×Ô¶¯»¯ÊµÏÖ£¬ÓÃÓÚÑéÖ¤Ò»¸öµ¥¶Àº¯Êý»ò¶ÀÁ¢¹¦ÄÜÄ£¿éµÄ´úÂ룻

Service£º20%£¬Éæ¼°Á½¸ö»òÁ½¸öÒÔÉÏ£¬ÉõÖÁ¸ü¶àÄ£¿éÖ®¼ä½»»¥µÄ¼¯³É²âÊÔ£»

UI£º10%£¬¸²¸ÇÈý¸ö»òÒÔÉϵŦÄÜÄ£¿é£¬ÕæÊµÓû§³¡¾°ºÍÊý¾ÝµÄÑéÊÕ²âÊÔ£»

ÕâÀï½ö½öÁоÙÁËÿ¸ö²ã´ÎµÄ°Ù·Ö±È£¬Êµ¼ÊÒª¸ù¾ÝÍŶӵķ½ÏòÀ´×öµ÷Õû¡£

×Ô¶¯»¯µ¥Ôª²âÊÔÔ­Ôò

Ìá½»´úÂë¡¢ÔËÐвâÊÔµÄÖØµãÊÇʲô£¿¿ìËÙ²¶»ñÄÇЩÒòÐÞ¸ÄÏòϵͳÖÐÒýÈëµÄ×î³£¼û´íÎ󣬲¢Í¨Öª¿ª·¢ÈËÔ±£¬ÒÔ±ãËûÃÇÄÜ¿ìËÙÐÞ¸´ËûÃÇ¡£Ìá½»½×¶ÎÌṩ·´À¡µÄ¼ÛÖµÔÚÓÚ£¬¶ÔËüµÄͶÈë¿ÉÒÔÈÃϵͳ¸ßЧÇÒ¸ü¿ìµØ¹¤×÷¡£

1¡¢¸ôÀëUI²Ù×÷

UIÓ¦µ±×÷Ϊ¸ü¸ß²ã´ÎµÄ²âÊÔLevel£¬ÐèÒª»¨·Ñ´óÁ¿Ê±¼ä×¼±¸Êý¾Ý£¬ÒµÎñÂß¼­¸´ÔÓ£¬¹ýÔç½øÈëUI½×¶Î£¬ÈÝÒ×·ÖÉ¢¿ª·¢µÄµ¥Ôª²âÊÔ¾«Á¦¡£

2¡¢¸ôÀëÊý¾Ý¿âÒÔ¼°Îļþ¶ÁÐ´ÍøÂ翪ÏúµÈ²Ù×÷

×Ô¶¯»¯²âÊÔÖÐÈç¹ûÐèÒª½«½á¹ûдÈëÊý¾Ý¿â£¬È»ºóÔÙÑéÖ¤¸Ä½á¹ûÊÇ·ñ±»ÕýȷдÈ룬ÕâÖÖÑéÖ¤·½·¨¼òµ¥¡¢ÈÝÒ×Àí½â£¬µ«ÊÇËü²»ÊÇÒ»¸ö¸ßЧµÄ·½·¨¡£Õâ¸öÓ¦µ±´Ó¼¯³É²âÊÔµÄLevelÈ¥½â¾ö¡£

Ê×ÏÈ£ºÓëÊý¾Ý¿âµÄ½»»¥£¬ÊÇÂþ³¤µÄ£¬ÉõÖÁÓпÉÄÜҪͶÈëά»¤Êý¾Ý¿âµÄʱ¼ä£¬Äǽ«³ÉΪ¿ìËÙ²âÊÔµÄÒ»¸öÕϰ­£¬¿ª·¢ÈËÔ±²»Äܵõ½¼°Ê±ÓÐЧµÄ·´À¡¡£¼ÙÉ裬ÎÒÐèÒª»¨·ÑÒ»¸öСʱ£¬²ÅÄÜÑéÖ¤Íê±ÏÓëÊý¾Ý¿â½»»¥µÄ½á¹û£¬ÕâÖֵȴýÊǶàôÂþ³¤Ñ½¡£

Æä´Î£¬Êý¾Ý¹ÜÀíÐèÒª³É±¾£¬´ÓÊý¾ÝµÄɸѡ£¨ÏßÉÏÊý¾Ý¿ÉÄÜÊÇT¼¶£©µ½²âÊÔ»·¾³µÄM¼¶±ð£¬ÈçºÎ°ÑɸѡºÏÊʵĴóС£¬ÕⶼʹµÃ¹ÜÀí³É±¾Ôö¼Ó£¨µ±È»ÔÚ¼¯³É²âÊÔÖпÉÒÔʹÓÃDBUnitÀ´½â¾ö²¿·ÖÎÊÌ⣩¡£

×îºó£¬Èç¹ûÒ»¶¨ÒªÓжÁд²Ù×÷²ÅÄÜÍê³ÉµÄ²âÊÔ£¬Ò²Òª·´Ë¼´úÂëµÄ¿É²âÊÔÐÔ×öµÄÈçºÎ£¿ÊÇ·ñÐèÒªÖØ¹¹¡£

µ¥Ôª²âÊÔ¾ö²»ÒªÒÀÀµÓÚÊý¾Ý¿âÒÔ¼°Îļþϵͳ¡¢ÍøÂ翪ÏúµÈÒ»ÇÐÍⲿÒÀÀµ¡£

3¡¢Ê¹ÓÃMockÌæÉíÓëSpringÈÝÆ÷¸ôÀë

Èç¹ûÔÚµ¥Ôª²âÊÔÖУ¬»¹ÐèÒªÆô¶¯SpringÈÝÆ÷½øÐÐÒÀÀµ×¢Èë¡¢¼ÓÔØÒÀÀµµÄWebServiceµÈ£¬Õâ¸ö¹ý³ÌÊÇÏ൱ÏûºÄʱ¼äµÄ¡£

¿ÉÒÔʹÓÃÄ£Ä⹤¾ß¼¯£ºMockito¡¢EasyMock¡¢JMockµÈÀ´½â¾ö£¬Ñз¢ÍŶÓÖ÷ÒªÊÇ»ùÓÚMockitoµÄʵ¼ù¡£ÓëÐèÒª×é×°ËùÓеÄÒÀÀµºÍ״̬Ïà±È£¬Ê¹ÓÃÄ£Äâ¼¼ÊõµÄ²âÊÔÔËÐÐÆðÀ´Í¨³£ÊǷdz£¿ì£¬ÕâÑù×Ó¿ª·¢ÈËÔ±ÔÚÌá½»´úÂëÖ®ºó£¬¿ÉÒÔÔÚ³ÖÐø¼¯³Éƽ̨¿ìËٵõ½·´À¡¡£

4¡¢Éè¼Æ¼òµ¥µÄ²âÊÔ

Ã÷È·¶¨Òå·½·¨£º

³É¹¦£ºpublic void testSendReportLongDateSuccess()

ʧ°Ü£ºpublic void testSendReportLongDateFail()£¬¿ÉÒÔ°üÀ¨Òì³£

ºÍµ¥Ò»µÄ¶ÏÑÔ£¬±ÜÃâÔÚÒ»¸ö·½·¨ÄÚʹÓöà¸ö¸´ÔÓ¶ÏÑÔ£¬Õâ»áÔì³É´úÂë½á¹¹µÄ¸´ÔÓ£¬Ê¹µÃ²âÊԵĸ´ÔÓÐÔÌá¸ß¡£

5¡¢¶¨Òå²âÊÔÌ×¼þµÄÔËÐÐʱ¼ä

ʹÓÃMock¹¹½¨µÄµ¥Ôª²âÊÔ£¬Ã¿¸ö·½·¨µÄ¹¹½¨Ê±¼äÓ¦¸ÃÊǺÁÃë¼¶±ð£¬Õû¸öÀàÊÇÃë¼¶±ð£¬ÀíÏëµÄÊÇÕûÌå¹¹½¨Ê±¼ä¿ØÖÆÔÚ5·ÖÖÓÒÔÄÚ£¬Èç¹û³¬¹ýÔõô°ìÄØ£¿

Ê×ÏÈ£¬²ð·Ö³É¶à¸öÌ×¼þ£¬ÔÚ¶ą̀»úÆ÷Éϲ¢ÐÐÖ´ÐÐÕâЩÌ×¼þ£»

Æä´Î£¬Öع¹ÄÇЩÔËÐÐʱ¼ä±È½Ï³¤ÇÒ²»¾­³£Ê§°ÜµÄ²âÊÔÀࣻ

¸ü¶à²Î¿¼ÍƼöÔĶÁ£º¡¶Unit Testing Guidelines¡·

http://geosoft.no/development/unittesting.html

4 Á÷³Ì

ͼ-4-1-µäÐ͹¤×÷Á÷³Ì

¿ª·¢ÈËÔ±×ñѭÿÈÕ¹¹½¨Ô­Ôò£¬Ìá½»¹¦ÄÜ´úÂë¡¢²âÊÔ´úÂ루ÒÔUnitTest½áβµÄ²âÊÔÀࣩµ½Svn£»

Jenkinsƽ̨£¬¸ù¾ÝÅäÖÃÔ­Ôò£¨¼ÙÉèÅäÖö¨Ê±Æ÷ÿ6·ÖÖÓ¼ì²éSvnÓдúÂë¸üÐÂÔò¹¹½¨£©½øÐУº´úÂë¸üС¢´úÂë±àÒë¡¢UnitTest¡¢³ÖÐø·´À¡µÄÁ÷Ë®Ïß¹¤×÷£»

¹¹½¨½á¹û·¢Ë͵½Sonar£¬²¢ÇÒ°Ñʧ°ÜµÄ¹¹½¨ÒÔÓʼþ·½Ê½Í¨ÖªÓ°Ïì´úÂëµÄ¿ª·¢ÈËÔ±£»

¿ª·¢ÈËÔ±¡¢²âÊÔÈËÔ±ÐèÒªÔÚSonarƽ̨½øÐÐreview£»

5 ʵ¼ù

JenkinsÅäÖÃÖØµã

¹¹½¨´¥·¢Æ÷£ºÍƼöʹÓÃPollSCM

Poll SCM£º¶¨Ê±¼ì²éÔ´Âë±ä¸ü£¨¸ù¾ÝSCMÈí¼þµÄ°æ±¾ºÅ£©£¬Èç¹ûÓиüоÍÖ´ÐÐcheckout¡£

Build periodically£ºÖÜÆÚ½øÐÐÏîÄ¿¹¹½¨£¨Ëü²»careÔ´ÂëÊÇ·ñ·¢Éú±ä»¯£©¡£

ÅäÖÃʱ¼ä£ºH/6 * * * *

1¡¢BuildÅäÖÃ

Goals and options£ºemma:emma -Dtest=*UnitTest soanr:sonar

×¢Ã÷£º

emma:emma£¬Add the "emma:emma" goal to your build to generate Emma reports£»

-Dtest=*UnitTest£¬²ÎÊýÅäÖã¬ÔËÐÐÒÔUnitTest½áβµÄ²âÊÔÀࣻ

sonar:sonar£¬À´´¥·¢¾²Ì¬´úÂë·ÖÎö¡£

ÐèÒª°²×°Emma Plugin£¨https://wiki.jenkins-ci.org/display/JENKINS/Emma+Plugin£©

2¡¢¹¹½¨ºó²Ù×÷
Ôö¼ÓAggregate downstream test results£¬¹´Ñ¡×Ô¶¯ÕûºÏËùÓеÄdownstream²âÊÔ£»

Ôö¼ÓEditable Email Notification£¬ÔÚ¡°¸ß¼¶¡±Ñ¡ÏîÔö¼Ó´¥·¢Æ÷¡°Unstable¡±£¬

¹´Ñ¡¡°Send To Committers¡±£¬Check this checkbox to send the email to anyone who checked in code for the last build¡£

×¢Ã÷£ºEditable Email Notification²å¼þÊÇ https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin

ÁíÍâһЩJenkinsµÄµ¥Ôª²âÊÔ¸²¸ÇÂÊÕ¹ÏÖ·½Ê½£¬¿ÉÒԲ鿴¹ÙÍø¡£

¹¹½¨¹ÜÀí¹¤¾ß£¨Maven£©

1¡¢ÏîĿͳһʹÓÃMaven½øÐй¹½¨¹ÜÀí£¬ÔÚpom.xmlÖнøÐÐÒÀÀµjar°üÅäÖÃ

2¡¢³ÖÐø¼¯³É·þÎñÆ÷ÉÏͬʱÐèÒª°²×°Maven£¬setting.xml³ýÁËÅäÖòֿâÖ®Í⣬»¹ÐèÒªÅäÖÃsonar£¬°üÀ¨sonar·þÎñÆ÷µØÖ·¡¢Êý¾Ý¿âÁ¬½Ó·½Ê½£º

<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- EXAMPLE FOR MYSQL -->
<sonar.jdbc.url>
jdbc:mysql://127.0.0.1:3306/sonar?useUnicode=true&characterEncoding=utf8
</sonar.jdbc.url>
<sonar.jdbc.driverClassName>com.mysql.jdbc.Driver</sonar.jdbc.driverClassName>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>
<!-- SERVER ON A REMOTE HOST -->
<sonar.host.url>http:/127.0.0.1:9000</sonar.host.url>
</properties>
</profile>

MockitoÅäÖÃÖØµã

ËùÓе¥Ôª²âÊԼ̳ÐMockitoTestContext¸¸Àà

MockitoTestContext ¸¸Àࣺ

package com.chinacache.portal;
import java.util.Locale;
import org.junit.BeforeClass;
import org.mockito.MockitoAnnotations;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.chinacache.portal.web.util.SessionUtil;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
/**
* Mockito ²âÊÔ»·¾³¡£¼Ì³Ð¸ÃÀàºó£¬Mockito µÄÏà¹Ø×¢½â (@Mock, @InjectMocks, ...) ¾ÍÄÜÉúЧ
*/
public class MockitoTestContext {
public MockitoTestContext() {
MockitoAnnotations.initMocks(this);
}
}

BillingBusinessManager Ô´Â룺

package com.chinacache.portal.service.billing;
//ÒýÈë°üºöÂÔ...
/**
* ¼Æ·ÑÒµÎñÏà¹ØµÄÒµÎñ·½·¨
*/
@Transactional
public class BillingBusinessManager {
private static final Log log = LogFactory.getLog(BillingBusinessManager.class);
@Autowired
private UserDAO userDAO;
@Autowired
private BillingBusinessDAO billingBusinessDAO;
@Autowired
private BillingBusinessSubscriptionDAO billingBusinessSubscriptionDAO;
@Autowired
private BillingBusinessSubscriptionDetailDAO billingBusinessSubscriptionDetailDAO;
@Autowired
private BillingRegionSubscriptionDAO billingRegionSubscriptionDAO;
@Autowired
private BillingRegionDAO billingRegionDAO;
@Autowired
private ContractTimeManager contractTimeManager;
/**
* ¸ù¾Ýid²éѯҵÎñÐÅÏ¢
* @return Èç¹û²ÎÊýΪ¿Õ»òÕß²éѯ²»µ½Êý¾Ý£¬·µ»Ø¿ÕÁбí

* O ÖеÄÖС¢Ó¢ÎÄÒµÎñÃûÀ´×Ô BILLING_BUSINESS ±í
*/
public List getBusinessesByIds(List businessIds) { return billingBusinessDAO.getBusinessbyIds(businessIds); } }
BillingBusinessManagerUnitTestÀࣺ

//ÒýÈë°üºöÂÔ...
public class BillingBusinessManagerUnitTest extends MockitoTestContext {
@InjectMocks
private BillingBusinessManager sv;
@Mock
private BillingBusinessDAO billingBusinessDAO;
@Test
public void testGetBusinessesByIds() {
List<BusinessVO> expected = ListUtil.toList(new BusinessVO(1l, "a", "b"));
//¼ò½àµÄÓï·¨ÈçÏÂËùʾ
when(billingBusinessDAO.getBusinessbyIds(anyListOf(Long.class))).thenReturn(expected);
List<Long> businessIds = ListUtil.toList(TestConstants.BUSINESS_ID_HTTP_WEB_CACHE);
List<BusinessVO> actual = sv.getBusinessesByIds(businessIds);
Assert.assertEquals(expected, actual);
}
}

BillingBusinessManagerUnitTestÀࣺ

//ÒýÈë°üºöÂÔ...
public class BillingBusinessManagerUnitTest extends MockitoTestContext {
@InjectMocks
private BillingBusinessManager sv;
@Mock
private BillingBusinessDAO billingBusinessDAO;
@Test
public void testGetBusinessesByIds() {
List<BusinessVO> expected = ListUtil.toList(new BusinessVO(1l, "a", "b"));
//¼ò½àµÄÓï·¨ÈçÏÂËùʾ
when(billingBusinessDAO.getBusinessbyIds(anyListOf(Long.class))).thenReturn(expected);
List<Long> businessIds = ListUtil.toList(TestConstants.BUSINESS_ID_HTTP_WEB_CACHE);
List<BusinessVO> actual = sv.getBusinessesByIds(businessIds);
Assert.assertEquals(expected, actual);
}
}

¸ü¶àMockitoµÄʹÓ㬿ÉÒԲο¼¹ÙÍø£ºhttp://code.google.com/p/mockito/

6 ×ܽá

ÈçºÎ¼ÓÇ¿¿ª·¢¹ý³ÌÖеÄ×Բ⻷½Ú£¬Ò»Ö±¶¼ÊǸöÍ·Í´µÄÎÊÌ⣬¿ª·¢µÄ´úÂëÖÊÁ¿¾¿¾¹ÈçºÎ£¿Ä£¿éÖ®¼äµÄÖÊÁ¿¾¿¾¹ÈçºÎ£¿»Ø¹é²âÊÔµÄЧÂÊÈçºÎ£¿Öع¹Ö®ºó£¬ÈçºÎ¿ìËÙÑé֤ģ¿éµÄÓÐЧÐÔ£¿

ÕâЩÔÚûÓÐ×ö×Ô¶¯»¯µ¥Ôª²âÊÔ֮ǰ£¬¶¼ÊÇÄÑÒÔ¿¼¾¿µÄÎÊÌ⡣ΨÓÐͨ¹ýÊý¾ÝÈ¥ºâÁ¿£¬ºáÏò¶Ô±È¶à¸ö°æ±¾µÄ¹¹½¨·ÖÎö½á¹û£¬²ÅÄܹ»·¢ÏÖÕû¸öÏîÄ¿ÖÊÁ¿µÄÇ÷ÊÆ£¬ÊÇÌáÉýÁË£¬»¹ÊÇϽµÁË£¬ÕâÑù¿ª·¢¡¢²âÊÔÈËÔ±²ÅÄܹ»ÓÐÐÅÐÄ×ö³öÇ¡µ±µÄÅжϡ£

µ±È»£¬µ¥Ôª²âÊÔÒ²²»ÊÇÒøµ¯£¬¼´±ãÏîÄ¿µÄ¸²¸ÇÂÊ´ïµ½100%£¬Ò²²»ÄܱíÃ÷²úÆ·ÖÊÁ¿Ã»ÓÐÈκÎÎÊÌ⣬²»»á²úÉúÈκÎȱÏÝ¡£ÖصãÔÚÓÚÈ·±£µ¥Ôª²âÊÔ»·½ÚµÄʵʩ£¬¿ÉÒÔÌáǰÊÍ·ÅѹÁ¦¡¢·çÏÕ¡¢±©Â¶ÎÊÌâµÈ¶à¸ö·½Ã棬¸Ä±äÒÔÍùûÓе¥Ôª²âÊÔ£¬ËùÓÐÎÊÌâ¶¼¼¯Öе½×îºó±¬·¢µÄ±×¶Ë¡£

×îºó£¬ÓÃÒ»ÕÅͼÀ´×ö¸ö¶Ô±È£º

ͼ-6-1-ʹÓÃǰºó¶Ô±È

Ôö¼Óµ¥Ôª²âÊÔÖ®ºó£º

¿ª·¢Ð§ÂÊÓÐÍûÌáÉý5-20%£»Öع¹¡¢»Ø¹é²âÊÔЧÂÊÌáÉý10%£¬½µµÍ³ö´íµÄ¼¸ÂÊ£¬×ÜÌå´úÂëÖÊÁ¿ÌáÉý£»

ÔÚ¿ª·¢¹ý³ÌÖб©Â¶¸ü¶àÎÊÌ⣬½«·çÏÕºÍѹÁ¦ÌáǰÊÍ·Å£¬³ÖÐø¹¹½¨´Ùʹ¿ª·¢ÖØÊÓ´úÂëÖÊÁ¿£»

UnitTestÖÊÁ¿¶ÔÓÚÍŶÓÀ´Ëµ£¬ÊÇ¿ÉÊÓ»¯ÁË£¬½»¸¶µÄÊÇÓÐÖÊÁ¿µÄ²úÆ·£¬¶ø²»ÊÇÊýÁ¿£»

   
4602 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

΢·þÎñ²âÊÔÖ®µ¥Ôª²âÊÔ
һƪͼÎÄ´øÄãÁ˽â°×ºÐ²âÊÔÓÃÀýÉè¼Æ·½·¨
È«ÃæµÄÖÊÁ¿±£ÕÏÌåϵ֮»Ø¹é²âÊÔ²ßÂÔ
È˹¤ÖÇÄÜ×Ô¶¯»¯²âÊÔ̽Ë÷
Ïà¹ØÎĵµ

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
jenkins³ÖÐø¼¯³É²âÊÔ
ÐÔÄܲâÊÔÕï¶Ï·ÖÎöÓëÓÅ»¯
ÐÔÄܲâÊÔʵÀý
Ïà¹Ø¿Î³Ì

³ÖÐø¼¯³É²âÊÔ×î¼Ñʵ¼ù
×Ô¶¯»¯²âÊÔÌåϵ½¨ÉèÓë×î¼Ñʵ¼ù
²âÊԼܹ¹µÄ¹¹½¨ÓëÓ¦ÓÃʵ¼ù
DevOpsʱ´úµÄ²âÊÔ¼¼ÊõÓë×î¼Ñʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

LoadRunnerÐÔÄܲâÊÔ»ù´¡
Èí¼þ²âÊÔ½á¹û·ÖÎöºÍÖÊÁ¿±¨¸æ
ÃæÏò¶ÔÏóÈí¼þ²âÊÔ¼¼ÊõÑо¿
Éè¼Æ²âÊÔÓÃÀýµÄËÄÌõÔ­Ôò
¹¦ÄܲâÊÔÖйÊÕÏÄ£Ð͵Ľ¨Á¢
ÐÔÄܲâÊÔ×ÛÊö


ÐÔÄܲâÊÔ·½·¨Óë¼¼Êõ
²âÊÔ¹ý³ÌÓëÍŶӹÜÀí
LoadRunner½øÐÐÐÔÄܲâÊÔ
WEBÓ¦ÓõÄÈí¼þ²âÊÔ
ÊÖ»úÈí¼þ²âÊÔ
°×ºÐ²âÊÔ·½·¨Óë¼¼Êõ


ij²©²ÊÐÐÒµ Êý¾Ý¿â×Ô¶¯»¯²âÊÔ
IT·þÎñÉÌ Web°²È«²âÊÔ
IT·þÎñÉÌ ×Ô¶¯»¯²âÊÔ¿ò¼Ü
º£º½¹É·Ý µ¥Ôª²âÊÔ¡¢Öع¹
²âÊÔÐèÇó·ÖÎöÓë²âÊÔÓÃÀý·ÖÎö
»¥ÁªÍøweb²âÊÔ·½·¨Óëʵ¼ù
»ùÓÚSeleniumµÄWeb×Ô¶¯»¯²âÊÔ