×Ô¶¯»¯µ¥Ôª²âÊÔ²¢²»ÊÇʲôÐÂÏÊÊÂÎËüÓ¦¸ÃÊÇÍŶӳÖÖ®ÒÔºãµÄÊÂÇ飬¿ÉÄÜÓкܶàÍŶÓÖªµÀÈçºÎÈ¥×ö£¬µ«ÊÇ»¹×öµÃ²»¹»ºÃ£»»¹Óв»ÉÙÍŶӲ»ÖªµÀÈçºÎÈ¥×ö£¬ÉõÖÁÓÐһЩ¾Éϵͳ»¹²»¸ÒÈ¥ÖØ¹¹£¬»¹ÔÚ¼á³Ö×Å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ÖÊÁ¿¶ÔÓÚÍŶÓÀ´Ëµ£¬ÊÇ¿ÉÊÓ»¯ÁË£¬½»¸¶µÄÊÇÓÐÖÊÁ¿µÄ²úÆ·£¬¶ø²»ÊÇÊýÁ¿£» |