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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
΢·þÎñ³¡¾°ÏµÄ×Ô¶¯»¯²âÊÔ
 
À´Ô´£ºicodeit.org ·¢²¼ÓÚ£º 2017-3-28
  3591  次浏览      27
 

еÄÌôÕ½

΢·þÎñºÍ´«Í³µÄµ¥¿éÓ¦ÓÃÏà±È£¬ÔÚ²âÊÔ²ßÂÔÉÏ£¬»áÓÐһЩ²»Ì«Ò»ÑùµÄµØ·½¡£¼òµ¥À´Ëµ£¬ÔÚ΢·þÎñ¼Ü¹¹ÖУ¬²âÊԵIJã´Î±äµÃ¸ü¶à£¬¶øÇÒ¶Ô»·¾³µÄ´î½¨ÒªÇó¸ü¸ß¡£±ÈÈç¶Ôµ¥¿éÓ¦Óã¬ÔÚÒ»¸ö»úÆ÷ÉϾͿÉÒÔsetup³öËùÓеÄÒÀÀµ£¬µ«ÊÇÔÚ΢·þÎñ³¡¾°Ï£¬ÓÉÓÚÒÀÀµµÄ·þÎñÍùÍùºÜ¶à£¬Òª´î½¨Ò»¸öÍêÕûµÄ»·¾³·Ç³£À§ÄÑ£¬Õâ¶ÔÍŶӵÄDevOpsµÄÄÜÁ¦Ò²ÓбȽϸߵÄÒªÇó¡£

Ïà¶ÔÓÚµ¥¿éÀ´Ëµ£¬Î¢·þÎñ¼Ü¹¹¾ßÓÐÒÔÏÂÌØµã£º

ÿ¸ö΢·þÎñÔÚÎïÀíÉÏ·ÖÊô²»Í¬½ø³Ì

·þÎñ¼äÍùÍùͨ¹ýRESTfulÀ´¼¯³É

¶àÓïÑÔ£¬¶àÊý¾Ý¿â£¬¶àÔËÐÐʱ

ÍøÂçµÄ²»¿É¿¿ÌØÐÔ

²»Í¬µÄÍŶӺͽ»¸¶ÖÜÆÚ

ÉÏÊöµÄÕâЩ΢·þÎñ»·¾³µÄÌØµã£¬¾ö¶¨ÁËÔÚ΢·þÎñ³¡¾°ÖнøÐвâÊÔ×ÔÈ»»áÃæÁÙµÄһЩÌôÕ½£º

·þÎñ¼äÒÀÀµ¹ØÏµ¸´ÔÓ

ÐèҪΪÿ¸ö²»Í¬ÓïÑÔ£¬²»Í¬Êý¾Ý¿âµÄ·þÎñ´î½¨¸÷×ԵĻ·¾³

¶Ëµ½¶Ë²âÊÔʱ£¬»·¾³×¼±¸¸´ÔÓ

ÍøÂçµÄ²»¿É¿¿»áµ¼Ö²âÊÔÌ×¼þµÄ²»Îȶ¨

ÍŶÓÖ®¼äµÄ¹µÍ¨³É±¾

²âÊԵķֲã

Ïà±ÈÓÚ³£¼ûµÄÈý²ã²âÊÔ½ð×ÖËþ£¬ÔÚ΢·þÎñ³¡¾°Ï£¬Õâ¸ö²ã´Î¿ÉÒÔ±»À©Õ¹Îª5²ã£¨Èç¹û½«UI²âÊÔµ¥¶À³éÈ¡³öÀ´£¬¿ÉÒÔ·ÖΪÁù²ã£©¡£

µ¥Ôª²âÊÔ

¼¯³É²âÊÔ

×é¼þ²âÊÔ

ÆõÔ¼²âÊÔ

¶Ëµ½¶Ë²âÊÔ

ºÍ²âÊÔ½ð×ÖËþµÄ»ù±¾Ô­ÔòÏàͬ£º

Ô½ÍùÉÏ£¬Ô½½Ó½üÒµÎñ/×îÖÕÓû§£»Ô½ÍùÏ£¬Ô½½Ó½ü¿ª·¢

Ô½ÍùÉÏ£¬²âÊÔÓÃÀýÔ½ÉÙ

Ô½ÍùÉÏ£¬²âÊԳɱ¾Ô½¸ß£¨Ô½ºÄʱ£¬Ê§°ÜʱµÄÐÅϢԽģºý£¬Ô½ÄѸú×Ù£©

µ¥Ôª²âÊÔ

µ¥Ôª²âÊÔ£¬¼´Ã¿¸ö΢·þÎñÄÚ²¿£¬¶ÔÓÚÁìÓò¶ÔÏó£¬ÁìÓòÂß¼­µÄ²âÊÔ¡£ËüµÄ¸ôÀëÐԱȽϸߣ¬ÎÞÐèÆäËûÒÀÀµ£¬Ö´ÐÐËٶȽϿ졣

¶ÔÓÚÒµÎñ¹æÔò£º

ÉÌÓÃÈí¼þÐèÒªLicense²Å¿ÉÒÔʹÓã¬LicenseÓÐʱ¼äÏÞÖÆ

ÐèÒªLicenseµÄÈí¼þÔÚµ½ÆÚ֮ǰ£¬ÏµÍ³ÐèÒª·¢³ö¸æ¾¯

@Test
public void license_should_expire_after_the_evaluation_period() {
LocalDate fixed = getDateFrom("2015-09-03");
License license = new License(fixed.toDate(), 1);

boolean isExpiredOn = license.isExpiredOn(fixed.plusYears(1).plusDays(1).toDate());
assertTrue(isExpiredOn);
}

@Test
public void license_should_not_expire_before_the_evaluation_period() {
LocalDate fixed = getDateFrom("2015-09-05");
License license = new License(fixed.toDate(), 1);

boolean isExpiredOn = license.isExpiredOn(fixed.plusYears(1).minusDays(1).toDate());
assertFalse(isExpiredOn);
}

ÉÏÃæÕâ¸öÀý×Ó¾ÍÊÇÒ»¸ö·Ç³£µäÐ͵ĵ¥Ôª²âÊÔ£¬ËüºÍÆäËû×é¼þ»ù±¾ÉÏûÓÐÒÀÀµ¡£¼´Ê¹Òª²âÊԵĶÔÏó¶ÔÆäËûÀàÓÐÒÀÀµ£¬ÎÒÃÇ»áStub/MockµÄÊÖ¶ÎÀ´½«ÕâЩÒÀÀµÏû³ý£¬±ÈÈçʹÓÃmockito/PowerMock¡£

¼¯³É²âÊÔ

ϵͳÄÚÄ£¿é£¨Ò»¸öÄ£¿é¶ÔÆäÖܱߵÄÒÀÀµÏ¼äµÄ¼¯³É£¬ÏµÍ³¼äµÄ¼¯³É¶¼¿ÉÒÔ¹éÀàΪ¼¯³É²âÊÔ¡£±ÈÈç

Êý¾Ý¿â·ÃÎÊÄ£¿éÓëÊý¾Ý¿âµÄ¼¯³É

¶ÔÍⲿserviceÒÀÀµµÄ²âÊÔ£¬±ÈÈç¶ÔµÚÈý·½Ö§¸¶£¬Í¨ÖªµÈ·þÎñµÄ¼¯³É

¼¯³É²âÊÔÇ¿µ÷Ä£¿éºÍÍⲿµÄ½»»¥µÄÑéÖ¤£¬ÔÚ¼¯³É²âÊÔʱ£¬Í¨³£»áÉæ¼°µ½ÍⲿµÄ×é¼þ£¬±ÈÈçÊý¾Ý¿â£¬µÚÈý·½·þÎñ¡£ÕâʱºòÐèÒª¾¡¿ÉÄÜÕæÊµµÄÈ¥ÓëÍⲿ×é¼þ½øÐн»»¥£¬±ÈÈçʹÓúÍÕæÊµ»·¾³ÏàͬÀàÐ͵ÄÊý¾Ý¿â£¬²ÉÓöÀÁ¢Ä£Ê½£¨Standalone£©µÄWireMockÀ´Æô¶¯ÍⲿÒÀÀµµÄRESTfulϵͳ¡£

ͨ³£»áÓÃÀ´×öÄ£ÄâÍⲿÒÀÀµ¹¤¾ß°üÀ¨£º

WireMock

mountebank

ÆäÖУ¬mountbank»¹Ö§³ÖSocket¼¶±ðµÄMock£¬¿ÉÒÔÔÚ·ÇHTTPЭÒéµÄ³¡¾°ÖÐʹÓá£

×é¼þ²âÊÔ

¹á´©Ó¦ÓòãºÍÁìÓò²ãµÄ²âÊÔ¡£²»¹ýͨ³£À´Ëµ£¬Õⲿ·ÖµÄ²âÊÔ²»»á·ÃÎÊÕæÊµµÄÍⲿÊý¾ÝÔ´£¬¶øÊÇʹÓÃͬschemaµÄÄÚ´æÊý¾Ý¿â£¬¶øÇÒ¶ÔÍⲿserviceµÄ·ÃÎÊÒ²»áʹÓÃStubµÄ·½Ê½£º

ÄÚ´æÊý¾Ý¿â

StubÍⲿ·þÎñ£¨WireMock£©

RestAssured

±ÈÈçʹÓÃh2À´×öÄÚ´æÊý¾Ý¿â£¬²¢ÇÒ×Ô¶¯Éú³Éschema¡£Ê¹ÓÃWireMockÀ´StubÍⲿµÄ·þÎñµÈ¡£

 

@Test
public void should_create_user() {
given().contentType(ContentType.JSON).body(prepareUser()).
when().post("/users").
then().statusCode(201).
body("id", notNullValue()).
body("name", is("Juntao Qiu")).
body("email", is("juntao.qiu@gmail.com"));
}

private User prepareUser() {
User user = new User();
user.setName("Juntao Qiu");
user.setEmail("juntao.qiu@gmail.com");
user.setPassword("password");
return user;
}

Èç¹ûʹÓÃSpring£¬»¹¿ÉÒÔͨ¹ýprofileÀ´Çл»²»Í¬µÄÊý¾Ý¿â¡£±ÈÈçÏÂÃæÕâ¸öÀý×ÓÖУ¬Ä¬ÈϵÄprofile»áÁ¬½ÓÊý¾Ý¿âjigsaw£¬¶øintegrationµÄprofile»áÁ¬½Ójigsaw_testÊý¾Ý¿â£º

spring:
datasource:
url: jdbc:mysql://localhost:3306/jigsaw
driver-class-title: com.mysql.jdbc.Driver
username: root
password: password

---

spring:
profiles: integration

datasource:
url: jdbc:mysql://localhost:3306/jigsaw_test
driver-class-title: com.mysql.jdbc.Driver
username: root
password: password

×é¼þ²âÊÔ»áÉæ¼°µ½µÄ×é¼þ°üÀ¨£º

URL·ÓÉ

ÐòÁл¯Óë·´ÐòÁл¯

Ó¦ÓöÔÁìÓò²ãµÄ·ÃÎÊ

ÁìÓò²ã¶ÔÊý¾ÝµÄ·ÃÎÊ

Êý¾Ý¿â·ÃÎʲã

ǰºó¶Ë·ÖÀë

³ýÁ˺ó¶ËµÄ²âÊÔÖ®Í⣬ÔÚĿǰµÄǰºó¶Ë·ÖÀ볡¾°Ï£¬Ç°¶ËµÄÓ¦ÓÃÔ½À´Ô½¸´ÔÓ£¬ÔÚÕâÖÖÇé¿öÏ£¬Ç°¶ËµÄ×é¼þ²âÊÔÒ²ÊÇÒ»¸ö²âÊÔµÄÖØµã¡£

Ò»¸öǰ¶ËÓ¦ÓÃÖÁÉÙ°üÀ¨ÁËÕâÑùһЩ×é¼þ£º

ǰ¶Ë·ÓÉ

Ä£°å

ǰ¶ËµÄMVVM

À¹½ØÆ÷

ʼþµÄÏìÓ¦

Ҫȷ±£ÕâЩ×é¼þ×éºÏÆðÀ´»¹ÄÜÈçÔ¤ÆÚµÄÖ´ÐУ¬Ïà¹Ø²âÊԱز»¿ÉÉÙ¡£ÕâÆªÎÄÕÂÏêϸÌÖÂÛÁËǰºó¶Ë·ÖÀëÖ®ºóµÄ²âÊÔ¼°¿ª·¢Êµ¼ù¡£

ÆõÔ¼²âÊÔ

ÔÚ΢·þÎñ³¡¾°ÖУ¬·þÎñÖ®¼ä»áÓкܶàÒÀÀµ¹ØÏµ¡£¸ù¾ÝÏû·ÑÕßÇý¶¯ÆõÔ¼£¬ÎÒÃÇ¿ÉÒÔ½«·þÎñ·ÖΪÏû·ÑÕ߶˺ÍÉú²úÕß¶Ë£¬Í¨³£Ïû·ÑÕß×Ô¼º»á¶¨ÒåÐèÒªµÄÊý¾Ý¸ñʽÒÔ¼°½»»¥Ï¸½Ú£¬²¢Éú³ÉÒ»¸öÆõÔ¼Îļþ¡£È»ºóÉú²úÕ߸ù¾Ý×Ô¼ºµÄÆõÔ¼À´ÊµÏÖ×Ô¼ºµÄÂß¼­£¬²¢ÔÚ³ÖÐø¼¯³É»·¾³ÖгÖÐøÑéÖ¤¡£

PactÒѾ­»ù±¾ÉÏÊÇÏû·ÑÕßÇý¶¯ÆõÔ¼£¨Consumer Driven Contract£©µÄÊÂʵ±ê×¼ÁË¡£ËüÒѾ­ÓжàÖÖÓïÑÔµÄʵÏÖ£¬Javaƽ̨µÄ¿ÉÒÔʹÓÃpact-jvm¼°ÏàÓ¦µÄmaven/gradle²å¼þ½øÐпª·¢¡£

pact/pact-jvm

pact-broker

(ͼƬÀ´Ô´£ºWhy you should use Consumer-Driven Contracts for Microservice integration tests)

ͨ³£ÔÚ¹¤³Ìʵ¼ùÉÏ£¬µ±Ïû·ÑÕ߸ù¾ÝÐèÒªÉú³ÉÁËÆõÔ¼Ö®ºó£¬ÎÒÃǻὫÆõÔ¼ÉÏ´«ÖÁÒ»¸ö¹«¹²¿É·ÃÎʵĵØÖ·£¬È»ºóÉú²úÕßÔÚÖ´ÐÐʱ»á·ÃÎÊÕâ¸öµØÖ·£¬²¢»ñµÃ×îа汾µÄÆõÔ¼£¬È»ºó¶Ô×ÅÕâЩÆõÔ¼À´Ö´ÐÐÏàÓ¦µÄÑéÖ¤¹ý³Ì¡£

Ò»¸öµäÐÍµÄÆõÔ¼µÄƬ¶ÎÊÇÕâÑùµÄ£¨Ê¹ÓÃpact£©£º

"interactions": [
{
"description": "Project Service",
"request": {
"method": "GET",
"path": "/projects/11046"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=UTF-8"
},
"body": {
"project-id": "004c97"
},
"matchingRules": {
"$.body.project-id": {
"match": "type"
}
}
},
"providerState": "project service"
}
]

¶Ëµ½¶Ë²âÊÔ

¶Ëµ½¶Ë²âÊÔÊÇÕû¸ö΢·þÎñ²âÊÔÖÐ×îÀ§Äѵģ¬Ò»¸öÍêÕûµÄ»·¾³µÄ´´½¨ÓÚά»¤¿ÉÄÜÐèÒª»¨·ÑºÜ´óµÄ¾­Àú£¬ÌرðÊǵ±Óжà¸ö²»Í¬µÄÍŶÓÔÚ¶ÀÁ¢¿ª·¢µÄ³¡¾°Ï¡£

ÁíÒ»·½Ã棬´Ó´«Í³µÄ²âÊÔ½ð×ÖËþÀ´¿´£¬¶Ëµ½¶Ë²âÊÔÓ¦¸Ã¸²¸ÇÄÇЩҵÎñ¼ÛÖµ×î¸ßµÄHappy Path¡£Ò²¾ÍÊÇ˵£¬¶Ëµ½¶Ë²âÊÔ²¢²»¹Ø×¢Òì³£³¡¾°£¬ÉõÖÁ´ó²¿·ÖµÄÒµÎñ³¡¾°¶¼²»¿¼ÂÇ¡£Òª×öµ½ÕâÒ»µã£¬ÐèÒªÔÚÉè¼Æ²âÊÔʱ£¬´Ó×îÖÕÓû§µÄ½Ç¶ÈÀ´¿¼ÂÇ£¬Í¨¹ýÓû§»­ÏñºÍUser JourneyÀ´È·¶¨²âÊÔ³¡¾°¡£

Ôڶ˵½¶Ë²âÊÔÖУ¬×îÖØÒªµÄ·´¶ø²»ÊDzâÊÔ±¾Éí£¬¶øÊÇ»·¾³µÄ×Ô¶¯»¯ÄÜÁ¦¡£±ÈÈç¿ÉÒÔͨ¹ýÒ»¼ü¾Í¿ÉÒÔ½«Õû¸ö»·¾³provision³öÀ´£º

°²×°ºÍÅäÖÃÏà¹ØÒÀÀµ

×Ô¶¯½«²âÊÔÊý¾ÝFeedµ½Êý¾Ý¿â

×Ô¶¯²¿Êð

·þÎñµÄ×Ô¶¯ÖØÆô

Ëæ×ÅÈÝÆ÷¼¼ÊõºÍÈÝÆ÷µÄ±àÅż¼ÊõµÄ³ÉÊ죬Õⲿ·Ö¹¤×÷ÒѾ­¿ÉÒԱȽϺõÄ×Ô¶¯»¯£¬ÒÀÀµµÄ¹¤¾ß°üÀ¨£º

Docker

Rancher

Ò»¸öµäÐ͵ÄÁ÷³ÌÊÇ£º

´î½¨³ÖÐø·¢²¼Á÷Ë®Ïß

Ó¦ÓôúÂëµÄÿһ´ÎÌá½»¶¼¿ÉÒÔ¹¹½¨³ödocker¾µÏñ

½«docker¾µÏñ·¢²¼ÔÚÄÚ²¿µÄdocker-hubÉÏ

´¥·¢²¿ÊðÈÎÎñ£¬Í¨¹ýrancherµÄupgradeÃüÁеľµÏñ·¢²¼

Ö´Ðж˵½¶Ë²âÊÔÌ×¼þ

¶Ëµ½¶Ë²âÊÔ»¹¿ÉÒÔϸ·ÖΪÁ½¸ö²»Í¬µÄ³¡¾°£º

ûÓÐÓû§½»»¥µÄ³¡¾°£¬ÈçһϵÁеÄ΢·þÎñ×é³ÉÁËÒ»¸öÒµÎñAPI

ÓÐÓû§½»»¥µÄ³¡¾°

UI²âÊÔ

×î¶¥²ãµÄUI²âÊÔ¸ú´«Í³·½Ê½µÄUI²âÊÔ²¢ÎÞ¶þÖ¡£ÎÒÃÇ¿ÉÒÔʹÓÃBDDÓëʵÀý»¯ÐèÇó£¨Specification By Example£©µÄ¸ÅÄ´ÓÓû§Ê¹ÓõĽǶÈÀ´ÃèÊöÐèÇó£¬ÒÔ¼°Ïà¹ØµÄÑéÊÕÌõ¼þ¡£ÕâÀïÎÒÃÇ»áʹÓÃWebDriverÀ´Çý¶¯ä¯ÀÀÆ÷£¬²¢Í¨¹ýÖîÈçCapybaraµÈ¹¤¾ßÀ´Ä£ÄâÓû§µÄ²Ù×÷¡£

BDD¹¤¾ß£ºCucumber

WebÓ¦ÓÃÑéÊÕ²âÊÔ¹¤¾ß£ºCapybara

Page ObjectµÄDSL¹¤¾ß£ºSite_prism

   
3591 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

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

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
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×Ô¶¯»¯²âÊÔ