บทความนี้แนะนำวิธีการรวมสปริงบูตเข้ากับแตงกวา (BDD) และแชร์กับคุณ รายละเอียดมีดังนี้:
1. สร้างโครงสร้างโครงการ Springboot ใหม่ดังนี้:
2. เพิ่มการพึ่งพา POM
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <project xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/ XSI: schemalocation = "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" <ArtIfactId> Spring-Boot-Cucumber </artifactid> <sersion> 0.0.1-Snapshot </Sersion> <packaging> JAR </packaging> <name> Spring-Boot-Cucumber </name> <คำอธิบาย> โครงการสาธิตสำหรับการบูตฤดูใบไม้ผลิ <ArtIfactId> Spring-Boot-Starter-Parent </artifactid> <version> 1.5.6.release </เวอร์ชัน> <inelypath/> <!-ผู้ปกครองค้นหาจากที่เก็บ-> </parenties> <properties> <cucumber.version> 1.2.4 <Project.build.sourceencoding> utf-8 </project.build.sourceencoding> <project.raporting.outputUntening> UTF-8 </project.Reporting.outputencoding> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter-Web </artifactid> </serpendency> <pendency> <roupid> info.cukes </groupid> <ratifactid> Cucumber-java <roupId> info.cukes </groupId> <ratifactid> Cucumber-core </artifactid> <cersion> $ {Cucumber.version} </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupid> info.cukes </groupid> <Serpendency> <sderctId> info.cukes </groupId> <ratifactId> Cucumber-Junit </artifactid> <sersion> $ {cucumber.version} </version> <eplusions> <exclusion> <RoupID> org.springframework.boot </groupId> <ratifactid> ฤดูใบไม้ผลิ-boot-starter-test </artifactid> <scope> ทดสอบ </scope> </derpendency> </erpendencies> <uffactid> <การกำหนดค่า> <source> 1.7 </source> <source> <target> 1.7 </เป้าหมาย> </การกำหนดค่า> </plugin> <plugin> <slugin> <roupid> org.codehaus.mojo </groupId> <pare> การรวมการรวม </เฟส> <goals> <goal> Java </goal> </goals> <การกำหนดค่า> <scrasspathscope> ทดสอบ </classpathscope> <mainclass> com.chhliu.test.cucumbertest.java </mainclass> <igration> src/test/resources/</argver> </arguments> </configuration> </execution> </encutions> </plugin> </plugins> </build>2. เขียนอินเทอร์เฟซบริการและคลาสการใช้งาน
แพ็คเกจ com.chhliu.service; / ** * การเข้าสู่ระบบการจำลอง * @author Chhliu * */ อินเตอร์เฟสสาธารณะ userinfoservicei {การเข้าสู่ระบบบูลีน (ชื่อผู้ใช้สตริง, รหัสผ่านสตริง, สตริงยืนยันผ่านคำ); - แพ็คเกจ com.chhliu.service; นำเข้า org.springframework.stereotype.service; @Service ("UserInFoservice") คลาสสาธารณะ UserInFoservice ใช้ userInFoservicei {ล็อกอินบูลีนสาธารณะ (ชื่อผู้ใช้สตริง, รหัสผ่านสตริง, สตริงยืนยันผ่าน) {return (ชื่อผู้ใช้. equals ("chhliu") && password.equals ("123456") && - 3. เขียนไฟล์คุณสมบัติ
#Language: zh-cn # "zh-cn": { # "แต่": "*| แต่ <", # "และ": "*| และ <| และ <| และ <| ในเวลาเดียวกัน <", # "แล้ว": "*|", # "เมื่อ": " "พื้นหลัง", # "สถานการณ์": "scenario_outline": "โครงร่างสถานการณ์ | โครงร่างสคริปต์", # "ตัวอย่าง": "ตัวอย่าง", # "ให้": "*| ถ้า <| ถ้า <| ถ้า <| ถ้า <| ถ้า <| ถ้า <" #} @bank ฟังก์ชั่น หากยอดคงเหลือคือ 500,000 สถานการณ์: ธนาคารถอนเงินถ้า: ฉันเข้าสู่ระบบด้วย "Chhliu" และรหัสผ่านที่ป้อนคือ "123456" เมื่อ: ยืนยันรหัสผ่านก็คือ "123456" ด้วยเช่นกัน: ยอดเงินบัตรธนาคารจะเป็น "500,000" 4. เขียนคลาสทดสอบ
แพ็คเกจ com.chhliu.test; นำเข้า org.junit.runner.runwith; นำเข้า cucumber.api.cucumberoptions; นำเข้า cucumber.api.junit.cucumber; /*** @runwith (cucumber.class) นี่คือนักวิ่งซึ่งหมายถึงการใช้แตงกวาเพื่อเรียกใช้การทดสอบ* @cucumberoptions ซึ่งระบุไดเรกทอรีของคุณลักษณะที่จะทำงานในรูปแบบของโครงการ* @cucumberoptions ระบุไดเรกทอรีที่ค้นหาไฟล์นิยามขั้นตอนเมื่อโครงการรัน * * ในโครงการจริงเนื่องจากโครงการดำเนินไปโครงการทดสอบอาจประกอบด้วยไฟล์คุณสมบัติหลายไฟล์และแต่ละไฟล์คุณสมบัติอาจประกอบด้วยหลายสถานการณ์ โดยค่าเริ่มต้น * การเรียกใช้แต่ละครั้งคือการเรียกใช้สถานการณ์ทั้งหมดในคุณสมบัติทั้งหมด สิ่งนี้อาจทำให้สคริปต์ทดสอบทำงานหนึ่งครั้งภายใต้สถานการณ์ปกติซึ่งใช้เวลานานมากในการรอผลการทดสอบ * อย่างไรก็ตามในกระบวนการจริงกรณีทดสอบมีความแตกต่างโดยลำดับความสำคัญ ตัวอย่างเช่น smoketest, regressiontest ฯลฯ หรือบางครั้งมีกรณีการใช้งานขนาดเล็กเป็นพิเศษเช่นระดับเป็นสิ่งสำคัญ * กรณีการใช้งานเหล่านี้จำเป็นต้องมีการดำเนินการระยะยาวเพื่อตรวจสอบว่าระบบไม่มีหน้าสีขาวหรือหน้า 404 * ดังนั้นเราต้องแยกแยะสถานการณ์ทั้งหมดหรือไม่ ในเวลานี้เราสามารถใช้แท็ก * ในแตงกวาแท็กเพิ่มจำนวนแท็กได้โดยตรงด้วยคำนำหน้า @ไปยังคุณสมบัติหรือสถานการณ์ก่อนที่คุณลักษณะสถานการณ์สถานการณ์หรือภาพร่างคำหลักและแท็กหลายแท็กจะถูกคั่นด้วยช่องว่าง * @author chhliu * */ @runwith "pretty"}, feature = "src/test/resources") คลาสสาธารณะ cucumbertest {} 5. เรียกใช้คลาสทดสอบและปรับปรุงขั้นตอนที่ไม่ได้กำหนดของเอาต์พุตทดสอบ
แพ็คเกจ com.chhliu.test; นำเข้า Javax.annotation.Resource; นำเข้า org.junit.assert; นำเข้า com.chhliu.service.userinfoservicei; นำเข้า cucumber.api.java.zh_cn.if; นำเข้า cucumber.api.java.zh_cn.when.hen; นำเข้า cucumber.api.java.zh_cn.so; การรวมกลุ่มแตงกวาสาธารณะสปริง {@Resource (name = "userInFoservice") บริการส่วนตัว userinfoservicei; ชื่อผู้ใช้สตริงส่วนตัว; รหัสผ่านสตริงส่วนตัว สตริงส่วนตัวยืนยัน Password; @if ("^: ฉันเข้าสู่ระบบ $ ด้วย/" ([^/"]*)/" $ ") โมฆะสาธารณะฉันเข้าสู่ระบบ (String arg1) โยน throwable {this.username = arg1;} @if ("^: รหัสผ่านที่ป้อนคือ/"(^/"]*)/"$") } @when ("^: รหัสผ่านยังเป็น/" ([^/"]*)/" $ ") โมฆะสาธารณะยืนยันรหัสผ่านคือ _ (String arg1) โยนได้ thingable {this.confirmpassword = arg1;} @then ("^: แสดงยอดคงเหลือของบัตรธนาคาร Service.login (ชื่อผู้ใช้รหัสผ่านยืนยัน Password); if (islogin) {system.out.println ("เข้าสู่ระบบได้สำเร็จ! ยอดคงเหลือในการสืบค้นมีดังนี้:"+arg1); assert.assertequals ("500000", Arg1); - 6. เพิ่มการสนับสนุนคำอธิบายประกอบในขั้นตอนการทดสอบ
@runwith (springjunit4classrunner.class) @contextconfiguration // หากไม่ได้เพิ่มคำอธิบายประกอบนี้ถั่วจะถูกฉีดและไม่สามารถฉีด @springboottest // หากไม่มีการเพิ่มคำอธิบายประกอบนี้
7. ผลการทดสอบ
2 สถานการณ์ (2 ผ่าน)
11 ขั้นตอน (11 ผ่าน)
0M0.091S
8. จุดรวม
เมื่อรวมการบูตฤดูใบไม้ผลิเข้ากับแตงกวาจะมีจุดที่ต้องให้ความสนใจเพราะสปริงบูตสนับสนุน de-xmlization ดังนั้นในแบบดั้งเดิมแตงกวาจะอ่านไฟล์การกำหนดค่า cucumber.xml ภายใต้ classpath เพื่อเริ่มต้นถั่ว หลังจากรวมเข้ากับสปริงวิธีนี้ไม่สามารถใช้ได้ คุณต้องใช้คำอธิบายประกอบ @ContextConfiguration เพื่อใช้การโหลดคลาส หากจำเป็นต้องโหลดไฟล์การกำหนดค่าคุณสามารถใช้ดังนี้:
@ContextConfiguration (locations = {"classpath: applicationcontext.xml"})หากคุณใช้คำอธิบายประกอบเพื่อรวมให้ใช้สิ่งต่อไปนี้:
@ContextConfiguration (คลาส = SpringBootCucumberApplication.class)
หรือโดยตรง
@ContextConfiguration
หมายเหตุพิเศษ: @ContextConfiguration คำอธิบายประกอบจะต้องเพิ่มมิฉะนั้นการฉีดถั่วจะล้มเหลว
จากนั้นมาดูกันว่าทำไมสถานการณ์นี้เกิดจากซอร์สโค้ด
รหัสที่เกี่ยวข้องในส่วนนี้อยู่ในคลาส SpringFactory ภายใต้แพ็คเกจแตงกวา-สเปน มาดูชั้นเรียนต่อไปนี้:
โมฆะสาธารณะเริ่มต้น () {// วิธีการทดสอบ Cucumber เริ่มต้นถ้า (stepclassWithSpringContext! = null) {// ถ้าใช้ @ContextConfiguration Annotation นี่ไม่ใช่ null testContextManager = ใหม่ cucumberTestContextManager } else {// มิฉะนั้น stepClassWithSpringContext จะเป็นโมฆะและจะเข้าสู่สาขาต่อไปนี้ถ้า (beanfactory == null) {beanfactory = createFallBackContext (); // วิธีนี้เป็นจุดสนใจที่เราต้องการติดตาม}} NotifyContextManageTestClassStarted (); if (beanfactory == null || isNewContextCreated ()) {beanfactory = testContextManager.getBeanFactory (); สำหรับ (คลาส <s?> stepclass: stepclasses) {RegisterStepClassBeanDefinition (BeanFactory, StepClass); }} glueCodecontext.instance.start (); - ลองทำตามวิธี CreateFallBackContext:
Private ConfigurableListableBeanFactory createFallBackContext () {configurableApplicationContext ApplicationContext; if (getClass (). getClassLoader (). getResource ("cucumber.xml")! = null) {// <span style = "font-family: arial, helvetica, sans-serif;"> configurePlicationContext } else {// ถ้า cucumber.xml ไม่ได้รับการกำหนดค่ามันจะใหม่ genericapplicationContext = new genericapplicationContext (); } ApplicationContext.registershutdownhook (); configurableListableBeanFactory beanfactory = applicationContext.getBeanFactory (); beanfactory.registerscope (gluecodescope.name, ใหม่ glueCodescope ()); สำหรับ (คลาส <s?> stepclass: stepclasses) {RegisterStepClassBeanDefinition (BeanFactory, StepClass); } return beanfactory; -สุดท้ายมาพูดคุยเกี่ยวกับคลาส GenericApplicationContext คลาสนี้จะขึ้นอยู่กับประเภทของถั่วและจากนั้นอินสแตนซ์ของ Newinstance อย่างไรก็ตามเนื่องจากคลาสอื่น ๆ ถูกฉีดเข้าไปในคลาสนี้คลาสที่ฉีดไม่สามารถเริ่มต้นผ่านอินสแตนซ์ใหม่ดังนั้นการฉีดจะล้มเหลวและจะรายงานตัวชี้โมฆะ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น