Spring Boot gurnalan programma test edilişini ýeňilleşdirýän birnäçe utilit we annotasiýalary üpjün edýär. Test goldawy iki modul bilen üpjün edilýär: spring-boot-test esasy elementleri öz içine alýar, şol bir wagtyň özünde spring-boot-test-autoconfigure testler üçin awtomaçn konfigurasiýany goldaýar.
Köp sanly programmist "başlaýjy" spring-boot-starter-test ulanýarlar, ol iki test modullaryny, şeýle hem JUnit Jupiter, AssertJ, Hamcrest we başga-da birnäçe peýdaly kitaphanany import edýär.
Eger siziň JUnit 4 ulanýan testleriňiz bolsa, olary işlemek üçin JUnit 5-njiň köne hereketlendirijisini ulanyp bilersiňiz. Köne hereketlendirijini ulanmak üçin aşakdaky mysalda görkezilişi ýaly junit-vintage-engine-den garaşlylygy goşup bilersiňiz:
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
hamcrest-core org.hamcrest:hamcrest-iň peýdasyna çykaryldy, ol spring-boot-starter-test-iň bir bölegidir.
Test Meýdanynyň Garaşlylyklary
"başlaýjy" spring-boot-starter-test (test scope-da) aşakdaky kitaphanalary üpjün edýär:
-
JUnit 5: Java programmalaryň bir görnüşli test edilmegi üçin de-fakto standart.
-
Spring Test we Spring Boot Test: Spring Boot programmalary üçin utilit we integrasiýa test goldawy.
-
AssertJ: Akynly tassyklamalar kitaphanasy.
-
Hamcrest: Meçerli zatlar (matchers) (şeýle hem çäklendirmeler ýa-da predikatlar hökmünde bellidir).
-
Mockito: Java meýdançasy üçin imitasiýalar (mocking)
-
JSONassert: JSON üçin tassyklamalar kitaphanasy.
-
JsonPath: JSON üçin XPath.
Adatça, bu umumy kitaphanalar test ýazmakda peýdaly bolýar. Eger bu kitaphanalar siziň islegleriňizi kanagatlandyrsa, siz öz islegine görä goşmaça test garaşlylyklaryny goşup bilersiňiz.
Spring Programmalaryň Test Edilişi
Garaşlylyklaryň girizilmeginiň esasy artykmaçlyklaryndan biri, kodyň bir görnüşli test edilişini ýeňilleşdirmekdir. Siz Spring ulanmadan new operator bilen obýektleriň nusgalaryny döredip bilersiňiz. Şeýle hem hakyky garaşlylyklaryň ýerine imitasiýa obýektlerini ulanyp bilersiňiz.
Köp sanly ýagdaýda bir görnüşli test çäklerinden çykmak we integrasiýa test başlamak talap edilýär (Spring-den ApplicationContext bilen). Programma ýa-da başga infrastruktura bilen baglanyşygyny hökmany etmän, integrasiýa testleri geçirip bilmek peýdalydyr.
Spring Framework şeýle integrasiýa testleri üçin aýratyn test moduly öz içine alýar. Siz garaşlylygy göni org.springframework:spring-test-den ýazyp bilersiňiz ýa-da geçiriş bilen birikme üçin "başlaýjy" spring-boot-starter-test ulanyp bilersiňiz.
Spring Boot Programmalaryň Test Edilişi
Spring Boot programma – bu Spring üçin ApplicationContext-dir, şonuň üçin ony test etmek üçin Spring-iň wanil kontekstinde ýerine ýetirilýän operasiýalardan başga zat talap etmeýär.
SpringApplication ony döretmek üçin ulansaňyz.
Spring Boot @SpringBootTest annotasiýasyny üpjün edýär, ony Spring Boot-iň aýratynlyklary talap edilen wagtda spring-test üçin adaty annotasiýa @ContextConfiguration alternatiwasy hökmünde ulanyp bilersiňiz. Annotasiýa testlerde ulanylýan ApplicationContext-i SpringApplication arkaly döredýär. @SpringBootTest annotasiýasyna goşmaça, siziň programmaňyzyň has anyk dilimlerini test etmek üçin başga-da birnäçe annotasiýa üpjün edilýär.
@RunWith(SpringRunner.class) testine goşmagy ýatdan çykarmaň. Eger siz JUnit 5 ulansañyz, onuň ekwiwalenti annotasiýasyny
@ExtendWith(SpringExtension.class) goşmak hökman däl, sebäbi
@SpringBootTest we beýleki
@...Test annotasiýalary bilen eýýäm bellendi.
Adaty ýagdaýda @SpringBootTest annotasiýasy serweri işledip goýmaýar. Siz öz testleriňiziň durmuşa geçirilişini has anyklaşdyrmak üçin @SpringBootTest annotasiýasynyň webEnvironment atributyny ulanyp bilersiňiz:
-
MOCK(adaty):ApplicationContextweb kontekstini ýükläp, web gurşawynyň imitasiýa obýektini üpjün edýär. Bu anotasiýany ulanyp, gurulan serwerler işledilmeýär. Eger web gurşawy sizin classpath-de elýeterli däl bolsa, bu tertip adaty web dälApplicationContextdöretmäge çalt geçýär. Onuň işini@AutoConfigureMockMvcýa-da@AutoConfigureWebTestClientannotasiýasy bilen bilelikde test etmek üçin ulanyp bilersiňiz. -
RANDOM_PORT:WebServerApplicationContextgurşawy web gurşawynyň hakyky görnüşini üpjün edýär. Gurulan serwerler işledilýär we tötänleýin porty diňleýär. -
DEFINED_PORT:WebServerApplicationContextgurşawy web gurşawyň has hakyky görnüşini üpjün edýär. Gurulan serwerler işledilip, belgilenen porty berýär (application.propertiesfaýlyndan) ýa-da adaty port8080. -
NONE:ApplicationContext-iSpringApplicationarkaly belleýär, emma hiç hili web gurşawyny (imitasiýa ýa-da başga) üpjün etmeýär.
@Transactional goşulsa, ol adaty ýagdaýda her test metodynyň soňunda transaksiýany yzyna öwürýär. Emma
RANDOM_PORT ýa-da
DEFINED_PORT ýaly hakykat gurşawynda serwerleri we HTTP-müşderi bölümlerini goýmak şol bir wagtda transaksiýalarda yzyna öwürülmeýär.
@SpringBootTest
webEnvironment = WebEnvironment.RANDOM_PORT hem dürli tötänleýin port üstünden dolandyrmak serwer işini açýar, eger-de programma başga portda dolandyrmak serwerini ulanýan bolsa.
Web Programmasynyň Tübin Kesgitlemek
Eger Spring MVC elýeterli bolsa, adaty MVC esasynda programmanyň konteksti sazlanar. Diňe Spring WebFlux bar bolsa, ol tapylyp, programmanyň konteksti WebFlux-ä esaslanýar.
Eger frameworklaryň ikisi hem bar bolsa, Spring MVC öňe sürülýär. Bu ýagdaýda reaktiw web programmany test etmek üçin spring.main.web-application-type häsiýetini kesgitlär:
@SpringBootTest(properties = "spring.main.web-application-type=reactive") class MyWebFluxTests { // ... }
@SpringBootTest(properties = ["spring.main.web-application-type=reactive"]) class MyWebFluxTests { // ... }
Test Konfigurasiýasyny Kesgitlär
Eger siz Spring Test Framework bilen tanyş bolsaňyz, onda @ContextConfiguration(classes=…) ulanmaňa öwrenişen bolsaňyz gerek, haçanda Spring üçin haýsy @Configuration ýükläp bolar. Mysal üçin, siz köplenç testiňizde @Configuration bilen bellikli içki klassa basgaça ulanýardyňyz.
Spring Boot programmalar test edilende, bu adaty talap edilmeýär. Spring Boot-yň @*Test annotasiýalary haýsy ilkinji konfigurasiýaňyzy bellik etmedigiňiz ýagdaýynda awtomatilk tapar.
Gözleg algoritmi testi öz içine alýan bukjanyň içinden başlaýar we @SpringBootApplication ýa-da @SpringBootConfiguration bilen belliklenen klassy tapmazdan galýar. Eger-de siz kodyňyzy laýyk derejede gurluşlandyran bolsaňyz, esasy konfigurasiýany tapmak mümkin bolup biler.
Programmanyň aýratyn gatlaklaryny barlamak üçin test annotasiýasy ulanylýanda, programmanyň esasy metod klassynda belli bir ugra degişli konfigurasiýa parametrlerini goşmagyň öňüni alyň.
Komponentleri skanirlemegiň esasy konfigurasiýasy, @SpringBootApplication annotasiýasy bilen baglanyşykly, kabul edilen dilimleriň işleýşi ýaly bolmagyny üpjün etmek üçin ulanylýan çyzyk filtirlerini kesgitleýär. Eger-de @SpringBootApplication bilen belliklenen klass üçin @ComponentScan bilen açyk buýruk ulanylýan bolsa, bu filtirler işlemeýär. Eger siz dilimleri almaga degişli bolsa, olary täzeden kesgitläň.
Eger ilkinji konfigurasiýany düzmek gerek bolsa, test annotasiýasy bilen bellikli içki klass ulanyp bilersiňiz @TestConfiguration. Içki klas hökmünde ulanylan @Configuration bilen belliklenmedik, ol programmanyň esasy konfigurasiýasyny ulanyp ulanylýar, lakin @TestConfiguration bilen bellikli içki klass programmanyň esasy konfigurasiýasyny doldurýar.
Test Konfigurasiýasyny Çykarmak
Eger siziň programmanyň komponent skaneri ulanýan (meselem, @SpringBootApplication ýa-da @ComponentScan annotasiýalary bilen) bolsa, siz belli bir testler üçin döredilen ýokary derejeli konfigurasiýa klasslary bilen işleşip bilersiňiz, olar hemme ýerde haýal döredilip tapylýar.
Test annotasiýasy @TestConfiguration belleklemek üçin ulanylyp bilner içki test klassda esasy konfigurasiýa sazlamak üçin. Şeýle-de, @TestConfiguration bilen bellikli ýokary derejeli klassy bellemek, src/test/java içindäki klasslaryň skanirleme wagtynda tanaw edilmeýänini görkezýär. Soňra, mysalda görkezilişi ýaly, bu klassy açyk görnüşde import edip ulanyp bolýar:
@SpringBootTest @Import(MyTestsConfiguration.class) class MyTests { @Test void exampleTest() { // ... } }
@SpringBootTest @Import(MyTestsConfiguration::class) class MyTests { @Test fun exampleTest() { // ... } }
@ComponentScan annotasiýasy göni ulanylýan bolsa (ýa-da
@SpringBootApplication däl), onda
TypeExcludeFilter goşmaly.
Programmanyň Argumentlerini Ulanyş
Eger programma argumentleri kabul edýän bolsa, siz @SpringBootTest annotasiýasy bilen olary args atributy arkaly ýerleşdirip bilersiňiz.
@SpringBootTest(args = "--app.test=one") class MyApplicationArgumentTests { @Test void applicationArgumentsPopulated(@Autowired ApplicationArguments args) { assertThat(args.getOptionNames()).containsOnly("app.test"); assertThat(args.getOptionValues("app.test")).containsOnly("one"); } }
@SpringBootTest(args = ["--app.test=one"]) class MyApplicationArgumentTests { @Test fun applicationArgumentsPopulated(@Autowired args: ApplicationArguments) { assertThat(args.optionNames).containsOnly("app.test") assertThat(args.getOptionValues("app.test")).containsOnly("one") } }
Imitasiýa Gurşawynda Test Edilişi
Adaty ýagdaýda @SpringBootTest annotasiýasy serweri işledip goýmaýar, onuň ýerine web nokatlary test üçin imitasiýa gurşawyny döredýär.
Spring MVC-de imitasiýa gurşawynda MockMvc ýa-da WebTestClient ulanyp web nokatlaryny barlap bilersiňiz, mysal üçin aşakda görkezilişi ýaly:
@SpringBootTest @AutoConfigureMockMvc class MyMockMvcTests { @Test void testWithMockMvc(@Autowired MockMvc mvc) throws Exception { mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World")); } // Eger Spring WebFlux classpath-de bar bolsa, WebTestClient bilen MVC-testler dolandyrylýar @Test void testWithWebTestClient(@Autowired WebTestClient webClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk() .expectBody(String.class).isEqualTo("Hello World"); } }
@SpringBootTest @AutoConfigureMockMvc class MyMockMvcTests { @Test fun testWithMockMvc(@Autowired mvc: MockMvc) { mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isOk) .andExpect(MockMvcResultMatchers.content().string("Hello World")) } // Eger Spring WebFlux classpath-de bar bolsa, WebTestClient bilen MVC-testler dolandyrylýar @Test fun testWithWebTestClient(@Autowired webClient: WebTestClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk .expectBody<String>().isEqualTo("Hello World") } }
ApplicationContext işletmek islemeýän bolsaňyz,
@WebMvcTest annotasiýasyny ulanyp, alternativ hökmünde göz öňünde tutuň.
WebTestClient ulanyp, Spring WebFlux soňky nokatlaryny, aşakdaky mysalda görkezilişi ýaly barlap bilersiňiz:
@SpringBootTest @AutoConfigureWebTestClient class MyMockWebTestClientTests { @Test void exampleTest(@Autowired WebTestClient webClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk() .expectBody(String.class).isEqualTo("Hello World"); } }
@SpringBootTest @AutoConfigureWebTestClient class MyMockWebTestClientTests { @Test fun exampleTest(@Autowired webClient: WebTestClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk .expectBody<String>().isEqualTo("Hello World") } }
Adatça imitasiýa gurşawynda test geçirilmegi doly servlet konteýner ulanylyşyndan has çalt geçýär. Emma, imitasiýa Spring MVC derejasynda bolup geçýär, servlet konteýner işleriniň ýokarky logikasy bilen bagly kod göni MockMvc bilen test edilip bilmez.
Mysal üçin, Spring Boot-da ýalňyş beýany konteýneriň öz serişdelerine degişlidir. Bu, MVC derejesiniň döredýän we beýan edýän aralyklaryny test etmek mümkin, belli ýalňyş sahypalaryny göni görkezmek mümkin däldir. Eger siziň beýik derejeli nuanslary test isleseňiz, aşakdaky bölümde beýan edilişi ýaly, doly işläp duran serwer işledip bilersiňiz.
Işleýän Serwer Ulgamy Bilen Test
Eger doly işläp duran serweri işletmek isleseňiz, tötänleýin portlaryň ulanylmagyny maslahat berýäris. Siz @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) ulanyňyzda test her gezek işledilende elýeterli port tötänleýin saýlanýar.
@LocalServerPort annotasiýasyny ulanyp, test bilen ulanylýan port bellik edip biler. REST-çaýyrmak üçin döredilen testler, @Autowire bilen belliklenen, WebTestClient baglanýan testler, serweri belliklenen linklere ýol berip, aşakdaky mysalda görkezilişi ýaly, öz spesifik API-sini berip biler:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyRandomPortWebTestClientTests { @Test void exampleTest(@Autowired WebTestClient webClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk() .expectBody(String.class).isEqualTo("Hello World"); } }
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyRandomPortWebTestClientTests { @Test fun exampleTest(@Autowired webClient: WebTestClient) { webClient .get().uri("/") .exchange() .expectStatus().isOk .expectBody<String>().isEqualTo("Hello World") } }
WebTestClient ulanyp, hakyky serwerler hem imitasiýa gurşawlarynda ulanyp bolýar.
Bu konfigurasiýa spring-webflux -ni classpath-de goşmak talap edýär. Webflux goşup bilmeýän ýa-da islemeýän bolsaňyz, Spring Boot TestRestTemplate ulanma mümkinçiligini hem üpjün edýär:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyRandomPortTestRestTemplateTests { @Test void exampleTest(@Autowired TestRestTemplate restTemplate) { String body = restTemplate.getForObject("/", String.class); assertThat(body).isEqualTo("Hello World"); } }
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyRandomPortTestRestTemplateTests { @Test fun exampleTest(@Autowired restTemplate: TestRestTemplate) { val body = restTemplate.getForObject("/", String::class.java) assertThat(body).isEqualTo("Hello World") } }
WebTestClient Ulanma Konfigurasiýasy
WebTestClient sazlamak üçin, WebTestClientBuilderCustomizer binini sazlaň. Şeýle binalar WebTestClient.Builder arkaly WebTestClient döretmek üçin ulanylýar.
JMX Ulanmak
Test kontekst çarçuwasy konteksti keşe ulanýandygy üçin, JMX tehnologýasy öňünden öçürilip, şol bir domen bilen baglanyşykly komponentleriň hasaba alynmagynyň öňüni alar. Eger şeýle teste MBeanServer-e giriş gerek bolsa, ony hapalaň:
@SpringBootTest(properties = "spring.jmx.enabled=true") @DirtiesContext class MyJmxTests { @Autowired private MBeanServer mBeanServer; @Test void exampleTest() { assertThat(this.mBeanServer.getDomains()).contains("java.lang"); // ... } }
@SpringBootTest(properties = ["spring.jmx.enabled=true"]) @DirtiesContext class MyJmxTests(@Autowired val mBeanServer: MBeanServer) { @Test fun exampleTest() { assertThat(mBeanServer.domains).contains("java.lang") // ... } }
Metri ýolari Ulanma
Classpath-den garaşly bolmazdan, hasaplaýjy registrler, @SpringBootTest ulanylanda, diňe ýüzerinde saklanmak bilen awtomatik sazlanmaýar.
Eger intigrasiýa testi çarçuwasynda beýleki serwerde metri maglumatlaryny çykarmaly bolsa, @AutoConfigureMetrics bilen bellikläň.
GO TO FULL VERSION