еÄÌôÕ½
΢·þÎñºÍ´«Í³µÄµ¥¿éÓ¦ÓÃÏà±È£¬ÔÚ²âÊÔ²ßÂÔÉÏ£¬»áÓÐһЩ²»Ì«Ò»ÑùµÄµØ·½¡£¼òµ¥À´Ëµ£¬ÔÚ΢·þÎñ¼Ü¹¹ÖУ¬²âÊԵ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 |