±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚÔÆÆÜÉçÇø£¬±¾ÎÄÖ÷Òª½éÉÜÁËÐÐΪÇý¶¯¿ª·¢BDD£¬ÈçºÎÈ·±£´ï³É¹²Ê¶£¬ÒÔ¼°BDDµÄ·½·¨½éÉÜ£¬Ï£Íû¶ÔÄúµÄѧϰÓÐËù°ïÖú¡£ |
|
ÐÐΪÇý¶¯¿ª·¢(Behavior-Driven Development,
BDD)£¬ÊÇÒ»ÖÖÃô½Ý¿ª·¢µÄ¼¼Êõ£¬Ïë±Ø´ó¶àÊýͬѧ¶¼¶ÔÃô½Ý¿ª·¢ÁìÓòÖÐÁíÒ»¼¼Êõ£¬²âÊÔÇý¶¯¿ª·¢£¨Test-Driven
Development£¬TDD£©½ÏΪÊìϤ¡£
TDDµÄ˼ÏëÔÔòÊÇ£¬Ê×ÏÈÏȱàдµ¥Ôª²âÊÔ£¬µ±È»ÔÚûÓпª·¢¹¦ÄÜ´úÂë֮ǰ£¬Ò»¶¨ÊÇÒ»¸öʧ°ÜµÄ²âÊÔ£»È»ºóÔÙ±àд¹¦ÄÜ´úÂ룬Ïë·½Éè·¨ÈòâÊÔ¿ÉÒÔͨ¹ý£»ÔÙÖØ¹¹´úÂëÈ¥³ýÖØ¸´µÄ²¿·Ö¡£

ͼƬÀ´×Ôcucumber¹ÙÍø
TDDµÄ˼Ïë´òÆÆÁË´«Í³¿ª·¢µÄÁ÷³Ì£¬ºÃ´¦Ò²²»ÑÔ¶øÓ÷¡£Ìá¸ß´úÂëÖÊÁ¿£¬¿ÉѸËÙ·¢ÏÖ²¢¶¨Î»bug¡£
BDDÊǽ¨Á¢ÔÚ²âÊÔÇý¶¯¿ª·¢»ù´¡Ö®ÉÏ£¬ÏȱàдÑéÊÕ²âÊÔ£¬ËùÓÃÓïÑÔÒ²ÊÇÍŶӳÉÔ±£¨ÒµÎñ¡¢²úÆ·¡¢¿ª·¢¡¢²âÊԵȣ©¶¼¿ÉÒÔ¶Á¶®µÄʵÀý£¬ÔÙ½øÐÐÉÏÊöTDDµÄÁ÷³Ì¡£

ͼƬԴ×Ô¡¶ÐÐΪÇý¶¯¿ª·¢¿Î¼þ¡·
Èç¹û˵TDDÊÇÈÃÎÒÃÇÕýÈ·µÄ×öÊ£¬ÄÇôBDD¾ÍÊÇÈÃÎÒÃÇ×öÕýÈ·µÄÊ¡£
BDDÄ¿µÄ£ºÔÚÒµÎñºÍ¿ª·¢Ö®¼ä´ï³É¹²Ê¶¡£
ÔÚÈí¼þÏîÄ¿ÖÐÉæ¼°¶àÈ˽ôÃÜÐ×÷£¬ÓɲúÆ·ÒµÎñ½²½â¹¦ÄÜÐèÇ󣬿ª·¢¸ºÔð´úÂëʵÏÖ£¬²âÊÔ±£Ö¤Èí¼þÖÊÁ¿£¬¸ßÖÊÁ¿µÄ¹µÍ¨¶ÔÏîÄ¿³É¹¦ÖÁ¹ØÖØÒª¡£Èç¹ûÔÚÒ»¸öÏîÄ¿ÖÐÒµÎñÈËÔ±ÓÃ×Ô¼ºÐл°£¬¿ª·¢ÈËÔ±Óü¼ÊõÓïÑÔ¡¢¼¼Êõ˼άȥÀí½âÒµÎñ£¬ÔÚ¹µÍ¨¹ý³ÌÄÑÃâ³öÏÖ·ÖÆç£¬¿ª·¢ÈËÔ±¾Í¿ÉÄܰ´×Ô¼ºµÄÀí½âȥʵÏÖÁËÒ»¸ö´íÎóµÄ¹¦ÄÜ¡£

ÈçºÎÈ·±£´ï³É¹²Ê¶£¿
BDDµÄ·½·¨£º
ÓÃͨÓÃ×ÔÈ»ÓïÑÔÃèÊöʵÀý£¨ÏµÍ³ÐÐΪ£©
ÍŶӳÉԱʹÓÃͳһ¡¢Ò×¶ÁµÄÓïÑÔÃ÷ȷʵÀý£¬×÷ΪÑéÊÕ²âÊÔ±ê×¼¡£Ò»·½Ãæ¿ÉÒÔÏû³ýÀí½âÉÏµÄÆçÒ壬һ·½Ãæ¿ÉÒÔ¼¤·¢Ë¼¿¼Ã»Óп¼Âǵ½µÄ³¡¾°¡£
»îÎĵµ
ÕâÀïµÄʵÀýÊÇ¿ÉÒÔËæÊ±ÔËÐУ¬·´À¡ÏµÍ³ÔËÐÐÕæÊµ½á¹û£¬Èç¹ûÔËÐÐʧ°Ü£¬ÒªÃ´Îĵµ¹ýʱÐèÒª¸üУ¬ÒªÃ´ÏµÍ³³öÏÖÎÊÌâÐèÒªÐÞ¸´¡£
BDDµÄʵÏÖ£¬CucumberÊÇBDDµÄÒ»¸öÓÅÐ㿪Դ¿ò¼Ü¡£
CucumberÊÇÒ»¿îÐ×÷¹¤¾ß¡£
Ö§³Ö¶àÖÖ¿ª·¢ÓïÑÔJava C++ Ruby pythonµÈµÈ
ËüÊÇÒ»¸öÃüÁîÐй¤¾ß¡£ÔËÐÐÊÇ´ÓÌØÐÔfeatureÎı¾ÖнâÎöÒª²âÊԵij¡¾°scenario,ÿ¸ö³¡¾°ÓÉһϵÁеIJ½Öèstep×é³É£¬cucumberÒ»²½²½Ö´ÐÐÕâЩ²½Ö裬µÃµ½×îÖյIJâÊÔ½á¹û¡£
CucumberµÄʹÓÃ
»·¾³×¼±¸£º
JavaSE£¨java9»¹²»Ö§³Ö£©
Maven 3.31ÒÔÉÏ
IntellJ IDEA °²×°cucumber for java ²å¼þ
´´½¨Ò»¸ömavenÏîÄ¿£¬½²cucumber-jvmÒÀÀµÌí¼Óµ½pomÎļþÖÐ
<dependency>
<groupId>junit</groupId> <artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency> <groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
</dependency>
<dependency> <groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version> <scope>test</scope>
</dependency>
? |
´´½¨Ò»¸öÌØÐÔÎļþ¡£
user.featureÎļþ£¬¹¦ÄÜÊǹÜÀíÔ±¸øÏµÍ³ÐÂÔöÓû§Õ˺ţ¬²¢ÅжÏÕ˺Ŵ´½¨³É¹¦
#language:zh-CN
@api@user
¹¦ÄÜ:¹ÜÀíÔ±¸øÏµÍ³ÐÂÔöÓû§Õ˺Å
³¡¾°´ó¸Ù:´´½¨Óû§Õ˺Å
µ± ¹ÜÀíԱн¨Óû§Õ˺Å"<accountName>"ÊÖ»úºÅ"<mobile>"
ÄÇô ËûÓ¦¸Ã¿ÉÒÔ²éѯµ½¸ÃÕ˺Å"<accountName>"
Àý×Ó:
|accountName|mobile|
|test|11111111111| |
ÌØÐÔÎļþ±ØÐëÒÔ.featureΪºó׺
#language:zh-CN˵Ã÷ʹÓõÄÊÇÖÐÎļòÌåÓïÑÔ£¬cucumberÖ§³Ö50¶àÖÖÓïÑÔ¡£²»×¢Ã÷µÄÇé¿öĬÈÏÊÇÓ¢ÎÄ¡£
ͨ¹ýjava cucumber.api.cli.Main --i18n--help¿ÉÒÔ²éÖ§³ÖµÄÓïÑÔ¡£
µ«ÓÉÓÚÏà¹Øjar°ü²¢Ã»ÓÐÔÚclasspathÖУ¬Ö´ÐлáÖ±½Ó±¨´íÎó: ÕÒ²»µ½»òÎÞ·¨¼ÓÔØÖ÷Àà cucumber.api.cli.Main
°ÑÏà¹Øjar°ü·ÅÔÚÒ»¸öjarÎļþ¼ÐÖУ¬´´½¨Ò»¸öcucumber.batÎļþ£¬ÄÚÈÝÈçÏ£º
java -cp "./jars/*" cucumber.api.cli.Main
%*£¬ÔÙÖ´ÐоͿÉÒÔÕý³£ÔËÐÐÁË

@api@user£¬ÊDZêÇ©£¬¿ÉÒÔ½«³¡¾°¹éÀ࣬ÔÚÖ´ÐвâÊÔʱҲ¿ÉÒÔ·½±ãÖ¸¶¨Ö´ÐÐÄĸö±êÇ©µÄ³¡¾°¡£
²é¿´Ò»ÏÂÖÐÎÄÖ§³ÖµÄ¹Ø¼ü´Ê

´´½¨²½Ö趨Òå¡£
ÔËÐвâÊÔmvn clean test£¬cucumber»áÖ±½Ó¸æËßÎÒÓÐ1¸ö³¡¾°Ã»Óж¨Ò壬2¸ö²½ÖèûÓж¨Òå

²¢ÇÒ¸æËßÐèҪʵÏÖÄÄЩȱʧµÄsteps

¸´ÖÆÌáʾȱʧµÄstepµÄ´úÂ룬µ½ApiStepdefsÎļþÖУ¬ÎļþÃüÃûʲôÎ޹ؽôÒª¡£
ÔÙ´ÎÔËÐÐmvn clean test£¬½á¹ûÊÇ µÚÒ»¸ö²½Öèpending£¬ÏÂÒ»²½ÐèҪȥʵÏÖstep

ºÃÎÒÃÇ¿ªÊ¼Ð´Ò»¸öʧ°ÜµÄrest apiµÄ²âÊÔ£¬²¢Ö´ÐС£
@µ±("^¹ÜÀíԱн¨Óû§$")
public void ¹ÜÀíԱн¨Óû§(List<User> users) throws
Throwable {
for(User user:users){
apiHelper.post("/api/adduser",user);
apiHelper.expectStatus(201);
}? |

»¹Ã»ÓÐÈ¥¿ª·¢Õâ¸örest api·þÎñ¡£ÕâÀïʹÓõÄspring boot¿ò¼Ü¿ª·¢rest api·þÎñ¡£¿ªÊ¼²ÉÓÃTDDµÄ·½Ê½£¬ÏÈдһ¸öʧ°ÜµÄ²âÊÔ
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void addUserAddsearch() throws Exception
{
User user = new User();
String username = "test";
user.setAccountName(username);
user.setMobile("11111111111");
String userInJson = JSON.toJSONString(user);
System.out.println(userInJson);
mvc.perform(post("/api/adduser")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(userInJson))
.andDo(print())
.andExpect(status().isCreated());
}
} |
Ö´ÐвâÊÔ£¬¶ÏÑÔʧ°Ü·µ»Ø404¡£

¼ÌÐøÐ´rest api·þÎñʵÏÖ£¬ÔËÐвâÊÔ£¬Ê¹µÃ²âÊÔͨ¹ý¡£
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/api/adduser",
method = RequestMethod.POST, produces = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public void create(@RequestBody User user) {
userService.create(user);
}
} |
Æô¶¯spring-boot·þÎñ mvn spring-boot:run;
ÔÙÔËÐÐtest¹¤³ÌÖеÄbdd²âÊÔ´úÂ룬Õâ´ÎµÄ½á¹ûÊǵÚÒ»²½pass£¬µÚ¶þ²½
pending¡£

ÔÙ°´ÕÕÉÏÃæµÄ·½Ê½£¬¼ÌÐøÍê³ÉµÚ¶þ²½¡£×îÖÕ½á¹û2¸ö²½Ö趼ͨ¹ý¡£

²é¿´²âÊÔ±¨¸æ

˼¿¼:
ÐÐΪÇý¶¯¿ª·¢ÄܰïÖúÍŶӿìËÙ¹¹½¨ºÍ½»¸¶¸ü¶àÓмÛÖµºÍ¸ßÖÊÁ¿µÄ²úÆ·¡£
Ŀǰ²úÆ·¿ª·¢¹ý³ÌÒÀÈ»ÊÇÆÙ²¼Ê½ÐèÇó-Éè¼Æ-¿ª·¢-²âÊÔ-ÑéÊÕ¡£ÈçʹÓÃBDDµÄʵ¼ù£¬ÎÒ
ÃÇ»áÓÐÄÄЩ¸Ä±ä¡£

ÏëÒýÈëBDDµÄ¿ª·¢µ½×Ô¼ºµÄ²úÆ·Ïß¿ª·¢Êµ¼ùÖУ¬»¹»áÓкܳ¤µÄ·Ҫ×ߣ¬Öмä¹ý³ÌÃâ²»ÁËÓöµ½¸÷ÖÖ×èÁ¦¡£

|