Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testien kirjoittaminen

Testit ovat Rust-funktioita, jotka varmistavat, että ei-testikoodi toimii odotetulla tavalla. Testifunktioiden rungot suorittavat tyypillisesti nämä kolme toimintoa:

  • Valmistele tarvittavat tiedot tai tila.
  • Suorita testattava koodi.
  • Varmista, että tulokset ovat odotetut.

Katsotaan Rustin tarjoamia ominaisuuksia erityisesti testien kirjoittamiseen, jotka sisältävät nämä toiminnot: test-attribuutti, muutamia makroja ja should_panic-attribuutin.

Testifunktioiden rakenne

Yksinkertaisimmillaan Rustin testi on funktio, joka on merkitty test- attribuutilla. Attribuutit ovat metatietoa Rust-koodin osista; yksi esimerkki on derive-attribuutti, jota käytimme structeissa luvussa 5. Muuttaaksesi funktion testifunktioksi, lisää #[test] riville ennen fn:ää. Kun ajat testisi cargo test -komennolla, Rust rakentaa testiajaminen binääritiedoston, joka ajaa merkityt funktiot ja raportoi, läpäiseekö kukin testifunktio vai epäonnistuuko se.

Aina kun luomme uuden kirjastoprojektin Cargolla, testimoduuli testifunktiolla luodaan automaattisesti meille. Tämä moduuli antaa mallin testien kirjoittamiseen, jotta sinun ei tarvitse etsiä tarkkaa rakennetta ja syntaksia joka kerta, kun aloitat uuden projektin. Voit lisätä niin monta lisätestifunktiota ja testimoduulia kuin haluat!

Tutkimme testien toiminnan eri puolia kokeilemalla mallitestiä ennen kuin testaamme varsinaista koodia. Sitten kirjoitamme joitakin tosielämän testejä, jotka kutsuvat kirjoittamaamme koodia ja varmistavat, että sen käyttäytyminen on oikea.

Luodaan uusi kirjastoprojekti nimeltä adder, joka laskee yhteen kaksi lukua:

$ cargo new adder --lib
     Created library `adder` project
$ cd adder

adder-kirjastosi src/lib.rs-tiedoston sisällön pitäisi näyttää listaukselta 11-1.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs}}
Listing 11-1: cargo new -komennon automaattisesti luoma koodi

Tiedosto alkaa esimerkki-add-funktiolla, jotta meillä on jotain testattavaa.

Toistaiseksi keskitytään pelkästään it_works-funktioon. Huomaa #[test]- merkintä: Tämä attribuutti ilmaisee, että tämä on testifunktio, joten testiajaminen tietää käsitellä tätä funktiota testinä. Meillä voi myös olla ei-testifunktioita tests-moduulissa yhteisten skenaarioiden valmisteluun tai yleisten operaatioiden suorittamiseen, joten meidän täytyy aina ilmaista, mitkä funktiot ovat testejä.

Esimerkkifunktion runko käyttää assert_eq!-makroa varmistaakseen, että result, joka sisältää add-funktion kutsun tuloksen arvoilla 2 ja 2, on yhtä suuri kuin 4. Tämä varmistus toimii esimerkkinä tyypillisestä testin muodosta. Ajetaan se nähdäksemme, että testi läpäisee.

cargo test -komento ajaa kaikki projektimme testit, kuten listauksessa 11-2.

{{#include ../listings/ch11-writing-automated-tests/listing-11-01/output.txt}}
Listing 11-2: Automaattisesti luodun testin ajamisen tuloste

Cargo käänsi ja ajoi testin. Näemme rivin running 1 test. Seuraava rivi näyttää luodun testifunktion nimen, nimeltä tests::it_works, ja että testin ajamisen tulos on ok. Yhteenveto test result: ok. tarkoittaa, että kaikki testit läpäisivät, ja osa 1 passed; 0 failed laskee läpäisseiden tai epäonnistuneiden testien määrän.

Testin voi merkitä ohitetuksi, jotta se ei aja tietyssä tilanteessa; käsittelemme tämän luvun myöhemmässä osiossa ”Testien ohittaminen, ellei niitä erikseen pyydetä”. Koska emme ole tehneet sitä tässä, yhteenveto näyttää 0 ignored. Voimme myös antaa cargo test -komennolle argumentin ajaa vain testit, joiden nimi vastaa merkkijonoa; tätä kutsutaan suodatukseksi (filtering), ja käsittelemme sen osiossa ”Testien osajoukon ajaminen nimen perusteella”. Tässä emme ole suodattaneet ajettavia testejä, joten yhteenvedon loppu näyttää 0 filtered out.

0 measured -tilasto koskee suorituskykytestejä (benchmark tests). Tällä hetkellä suorituskykytestit ovat saatavilla vain yönightly-Rustissa. Katso dokumentaatio suorituskykytesteistä saadaksesi lisätietoja.

Testitulosteen seuraava osa alkaen Doc-tests adder koskee dokumentaatiotestien tuloksia. Meillä ei ole vielä dokumentaatiotestejä, mutta Rust voi kääntää API-dokumentaatiossamme esiintyvät koodiesimerkit. Tämä ominaisuus auttaa pitämään dokumentaation ja koodin synkassa! Käsittelemme dokumentaatiotestien kirjoittamista luvun 14 osiossa ”Dokumentaatiokommentit testeinä”. Toistaiseksi ohitamme Doc-tests- tulosteen.

Aloitetaan testin mukauttaminen omiin tarpeisiimme. Ensin vaihdetaan it_works- funktion nimi eri nimeksi, kuten exploration, näin:

Filename: src/lib.rs

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs}}

Sitten ajetaan cargo test uudelleen. Tuloste näyttää nyt exploration it_works- kohdan sijaan:

{{#include ../listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt}}

Nyt lisätään toinen testi, mutta tällä kertaa tehdään testi, joka epäonnistuu! Testit epäonnistuvat, kun jokin testifunktiossa paniikkiutuu. Jokainen testi ajetaan uudessa säikeessä, ja kun pääsäie näkee testisäikeen kuolleen, testi merkitään epäonnistuneeksi. Luvussa 9 puhuimme, että yksinkertaisin tapa paniikkiutua on kutsua panic!-makroa. Syötä uusi testi funktiona nimeltä another, jolloin src/lib.rs-tiedostosi näyttää listaukselta 11-3.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs}}
Listing 11-3: Toisen testin lisääminen, joka epäonnistuu, koska kutsumme panic!-makroa

Aja testit uudelleen cargo test -komennolla. Tulosteen pitäisi näyttää listaukselta 11-4, joka näyttää, että exploration-testimme läpäisi ja another epäonnistui.

{{#include ../listings/ch11-writing-automated-tests/listing-11-03/output.txt}}
Listing 11-4: Testitulokset, kun yksi testi läpäisee ja yksi epäonnistuu

ok-kohdan sijaan rivi test tests::another näyttää FAILED. Kaksi uutta osiota ilmestyy yksittäisten tulosten ja yhteenvedon väliin: Ensimmäinen näyttää yksityiskohtaisen syyn kunkin testin epäonnistumiselle. Tässä tapauksessa saamme tiedot, että tests::another epäonnistui, koska se paniikkiutui viestillä Make this test fail rivillä 17 src/lib.rs-tiedostossa. Seuraava osio listaa vain kaikkien epäonnistuneiden testien nimet, mikä on hyödyllistä, kun testejä ja paljon yksityiskohtaista epäonnistuneen testin tulostetta on paljon. Voimme käyttää epäonnistuneen testin nimeä ajamaan vain kyseisen testin debugataksemme sitä helpommin; puhumme lisää testien ajamisen tavoista osiossa ”Testien ajamisen hallinta”.

Yhteenvetorivi näkyy lopussa: Kaiken kaikkiaan testituloksemme on FAILED. Yksi testi läpäisi ja yksi epäonnistui.

Nyt kun olet nähnyt, miltä testitulokset näyttävät eri skenaarioissa, katsotaan joitakin muita makroja kuin panic!, jotka ovat hyödyllisiä testeissä.

Tulosten tarkistaminen assert!-makrolla

assert!-makro, jonka standardikirjasto tarjoaa, on hyödyllinen, kun haluat varmistaa, että jokin ehto testissä evaluoituu arvoksi true. Annetaan assert!-makrolle argumentti, joka evaluoituu totuusarvoksi. Jos arvo on true, mitään ei tapahdu ja testi läpäisee. Jos arvo on false, assert!- makro kutsuu panic!:a saadakseen testin epäonnistumaan. assert!-makron käyttö auttaa meitä tarkistamaan, että koodimme toimii tarkoittamallamme tavalla.

Luvussa 5, listauksessa 5-15, käytimme Rectangle-structia ja can_hold- metodia, jotka toistetaan tässä listauksessa 11-5. Laitetaan tämä koodi src/lib.rs-tiedostoon ja kirjoitetaan sille testejä assert!-makron avulla.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs}}
Listing 11-5: Rectangle-struct ja sen can_hold-metodi luvusta 5

can_hold-metodi palauttaa totuusarvon, mikä tekee siitä täydellisen käyttötapauksen assert!-makrolle. Listauksessa 11-6 kirjoitamme testin, joka testaa can_hold-metodia luomalla Rectangle-instanssin, jonka leveys on 8 ja korkeus 7, ja varmistamalla, että se voi sisältää toisen Rectangle-instanssin, jonka leveys on 5 ja korkeus 1.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs:here}}
Listing 11-6: Testi can_hold-metodille, joka tarkistaa, voiko suurempi suorakulmio todella sisältää pienemmän

Huomaa use super::*; -rivi tests-moduulin sisällä. tests-moduuli on tavallinen moduuli, joka noudattaa tavallisia näkyvyyssääntöjä, joita käsittelimme luvussa 7 osiossa ”Polut moduulipuun kohteeseen viittaamiseen”. Koska tests-moduuli on sisämoduuli, meidän täytyy tuoda testattava koodi ulommassa moduulissa sisämoduulin näkyvyysalueelle. Käytämme tässä globia, joten kaikki ulommassa moduulissa määrittelemämme on käytettävissä tässä tests-moduulissa.

Olemme nimenneet testimme larger_can_hold_smaller, ja olemme luoneet kaksi tarvitsemaamme Rectangle-instanssia. Sitten kutsuimme assert!-makroa ja annoimme sille lausekkeen larger.can_hold(&smaller). Tämän lausekkeen pitäisi palauttaa true, joten testimme pitäisi läpäistä. Katsotaan!

{{#include ../listings/ch11-writing-automated-tests/listing-11-06/output.txt}}

Se läpäisee! Lisätään toinen testi, joka tällä kertaa varmistaa, ettei pienempi suorakulmio voi sisältää suurempaa suorakulmiota:

Filename: src/lib.rs

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs:here}}

Koska can_hold-funktion oikea tulos tässä tapauksessa on false, meidän täytyy kääntää tämä tulos ennen kuin annamme sen assert!-makrolle. Näin testimme läpäisee, jos can_hold palauttaa false:

{{#include ../listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt}}

Kaksi testiä läpäisee! Katsotaan nyt, mitä testituloksille tapahtuu, kun tuomme virheen koodiimme. Muutamme can_hold-metodin toteutusta korvaamalla suurempi-kuin-merkin (>) pienempi-kuin-merkillä (<) leveyksiä vertailtaessa:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs:here}}

Testien ajaminen nyt tuottaa seuraavan:

{{#include ../listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt}}

Testimme löysivät virheen! Koska larger.width on 8 ja smaller.width on 5, leveyksien vertailu can_hold-metodissa palauttaa nyt false: 8 ei ole pienempi kuin 5.

Yhtäsuuruuden testaaminen assert_eq!- ja assert_ne!-makroilla

Yleinen tapa varmistaa toiminnallisuus on testata yhtäsuuruutta testattavan koodin tuloksen ja odottamasi arvon välillä. Voit tehdä tämän assert!-makrolla ja antamalla sille lausekkeen, joka käyttää ==-operaattoria. Tämä on kuitenkin niin yleinen testi, että standardikirjasto tarjoaa makroparin — assert_eq! ja assert_ne! — suorittaakseen tämän testin kätevämmin. Nämä makrot vertaavat kahta argumenttia yhtäsuuruuden tai erisuuruuden osalta. Ne myös tulostavat kaksi arvoa, jos varmistus epäonnistuu, mikä helpottaa miksi testi epäonnistui; päinvastoin assert!-makro ilmaisee vain, että se sai false-arvon ==- lausekkeelle tulostamatta arvoja, jotka johtivat false-arvoon.

Listauksessa 11-7 kirjoitamme funktion nimeltä add_two, joka lisää 2 parametriinsa, ja testaamme sitten tämän funktion assert_eq!-makrolla.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs}}
Listing 11-7: Funktion add_two testaaminen assert_eq!-makrolla

Tarkistetaan, että se läpäisee!

{{#include ../listings/ch11-writing-automated-tests/listing-11-07/output.txt}}

Luomme muuttujan nimeltä result, joka sisältää add_two(2)-kutsun tuloksen. Sitten annamme result- ja 4-arvot assert_eq!-makrolle. Tulostusrivi tälle testille on test tests::it_adds_two ... ok, ja ok-teksti ilmaisee, että testimme läpäisi!

Tuodaan virhe koodiimme nähdäksemme, miltä assert_eq! näyttää epäonnistuessaan. Muutetaan add_two-funktion toteutus lisäämään 3 2:n sijaan:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs:here}}

Aja testit uudelleen:

{{#include ../listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt}}

Testimme löysi virheen! tests::it_adds_two -testi epäonnistui, ja viesti kertoo, että epäonnistunut varmistus oli left == right ja mitkä left- ja right-arvot ovat. Tämä viesti auttaa aloittamaan debuggauksen: left- argumentti, jossa meillä oli add_two(2)-kutsun tulos, oli 5, mutta right- argumentti oli 4. Voit kuvitella, että tästä olisi erityisen hyötyä, kun testejä on paljon.

Huomaa, että joissakin kielissä ja testikehyksissä yhtäsuuruusvarmistusten funktioiden parametreja kutsutaan expected- ja actual-arvoiksi, ja argumenttien järjestys on merkityksellinen. Rustissa niitä kutsutaan kuitenkin left- ja right-arvoiksi, eikä sillä ole väliä, missä järjestyksessä määrittelemme odottamamme arvon ja koodin tuottaman arvon. Voisimme kirjoittaa testin varmistuksen muodossa assert_eq!(4, result), mikä johtaisi samaan epäonnistumisviestiin, joka näyttää assertion `left == right` failed.

assert_ne!-makro läpäisee, jos kaksi antamaamme arvoa eivät ole yhtä suuret, ja epäonnistuu, jos ne ovat. Tämä makro on hyödyllisin tapauksissa, joissa emme ole varmoja, mikä arvo tulee olemaan, mutta tiedämme, mikä arvo ei todellakaan saa olla. Esimerkiksi jos testaamme funktiota, joka muuttaa syötteensä jollakin tavalla, mutta tapa, jolla syöte muuttuu, riippuu viikonpäivästä, jolloin ajamme testejämme, paras asia varmistaa saattaa olla, ettei funktion tuloste ole yhtä suuri kuin syöte.

Pinnan alla assert_eq!- ja assert_ne!-makrot käyttävät operaattoreita == ja !=. Kun varmistukset epäonnistuvat, nämä makrot tulostavat argumenttinsa debug-muotoilulla, mikä tarkoittaa, että verrattavien arvojen täytyy toteuttaa PartialEq- ja Debug-traitit. Kaikki primitiivityypit ja useimmat standardikirjaston tyypit toteuttavat nämä traitit. Itse määrittelemillesi structeille ja enum-arvoille sinun täytyy toteuttaa PartialEq varmistaaksesi näiden tyyppien yhtäsuuruuden. Sinun täytyy myös toteuttaa Debug tulostaaksesi arvot, kun varmistus epäonnistuu. Koska molemmat traitit ovat johdettavia traitteja, kuten mainittiin listauksessa 5-12 luvussa 5, tämä on yleensä yhtä suoraviivaista kuin #[derive(PartialEq, Debug)]-merkinnän lisääminen struct- tai enum-määrittelyysi. Katso liite C, ”Johdettavat traitit” näistä ja muista johdettavista traiteista.

Mukautettujen virheviestien lisääminen

Voit myös lisätä mukautetun viestin, joka tulostetaan epäonnistumisviestin kanssa, valinnaisina argumentteina assert!-, assert_eq!- ja assert_ne!- makroille. Pakollisten argumenttien jälkeen määritellyt argumentit välitetään format!-makrolle (käsiteltiin luvussa 8 osiossa ”Yhdistäminen +- tai format!-operaattorilla”), joten voit antaa muotoilumerkkijonon, joka sisältää {}-paikkamerkit ja arvot näihin paikkamerkkeihin. Mukautetut viestit ovat hyödyllisiä dokumentoimaan, mitä varmistus tarkoittaa; kun testi epäonnistuu, sinulla on parempi käsitys siitä, mikä koodissa on vikana verrattuna siihen, mitä odotimme tapahtuvan.

Esimerkiksi sanotaan, että meillä on funktio, joka tervehtii ihmisiä nimellä, ja haluamme testata, että funktiolle antamamme nimi näkyy tulosteessa:

Filename: src/lib.rs

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs}}

Tämän ohjelman vaatimuksista ei ole vielä sovittu, ja olemme melko varmoja, että tervehdyksen alussa oleva Hello-teksti muuttuu. Päätimme, ettei meidän haluta päivittää testiä, kun vaatimukset muuttuvat, joten tarkistamme tarkan yhtäsuuruuden greeting-funktion palauttamaan arvoon sen sijaan, että varmistaisimme vain, että tuloste sisältää syöteparametrin tekstin.

Tuodaan nyt virhe tähän koodiin muuttamalla greeting jättämään name pois nähdäksemme, miltä oletusarvoinen testin epäonnistuminen näyttää:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs:here}}

Tämän testin ajaminen tuottaa seuraavan:

{{#include ../listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt}}

Tämä tulos ilmaisee vain, että varmistus epäonnistui ja millä rivillä varmistus on. Hyödyllisempi epäonnistumisviesti tulostaisi greeting-funktion arvon. Lisätään mukautettu epäonnistumisviesti, joka koostuu muotoilumerkkijonosta paikkamerkillä, joka täytetään todellisella arvolla, jonka saimme greeting- funktiosta:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs:here}}

Nyt kun ajamme testin, saamme informatiivisemman virheviestin:

{{#include ../listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt}}

Näemme testitulosteessa todellisen arvon, jonka saimme, mikä auttaisi debuggaamaan, mitä tapahtui sen sijaan, mitä odotimme tapahtuvan.

Paniikin tarkistaminen should_panic-attribuutilla

Palautusarvojen tarkistamisen lisäksi on tärkeää tarkistaa, että koodimme käsittelee virhetilanteet odottamallamme tavalla. Esimerkiksi harkitse Guess-tyyppiä, jonka loimme luvussa 9, listauksessa 9-13. Muu koodi, joka käyttää Guess-tyyppiä, luottaa takuuseen, että Guess-instanssit sisältävät vain arvoja välillä 1–100. Voimme kirjoittaa testin, joka varmistaa, että Guess-instanssin luominen arvolla tämän alueen ulkopuolelta paniikkiutuu.

Teemme tämän lisäämällä should_panic-attribuutin testifunktiollemme. Testi läpäisee, jos funktion sisällä oleva koodi paniikkiutuu; testi epäonnistuu, jos funktion sisällä oleva koodi ei paniikkiudu.

Listaus 11-8 näyttää testin, joka tarkistaa, että Guess::new-funktion virhetilanteet tapahtuvat, kun odotamme niitä.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs}}
Listing 11-8: Testaus, että ehto aiheuttaa panic!-kutsun

Sijoitamme #[should_panic]-attribuutin #[test]-attribuutin jälkeen ja ennen testifunktiota, johon se kohdistuu. Katsotaan tulos, kun tämä testi läpäisee:

{{#include ../listings/ch11-writing-automated-tests/listing-11-08/output.txt}}

Näyttää hyvältä! Tuodaan nyt virhe koodiimme poistamalla ehto, jonka perusteella new-funktio paniikkiutuu, jos arvo on suurempi kuin 100:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs:here}}

Kun ajamme listauksen 11-8 testin, se epäonnistuu:

{{#include ../listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt}}

Emme saa tässä tapauksessa kovin hyödyllistä viestiä, mutta kun katsomme testifunktiota, näemme, että se on merkitty #[should_panic]-attribuutilla. Saamamme epäonnistuminen tarkoittaa, että testifunktion koodi ei aiheuttanut paniikkia.

should_panic-attribuuttia käyttävät testit voivat olla epätarkkoja. should_panic-testi läpäisisi, vaikka testi paniikkiutuisi eri syystä kuin odotimme. Tehdäksemme should_panic-testeistä tarkempia voimme lisätä valinnaisen expected-parametrin should_panic-attribuuttiin. Testiajaminen varmistaa, että epäonnistumisviesti sisältää annetun tekstin. Esimerkiksi harkitse muokattua Guess-koodia listauksessa 11-9, jossa new-funktio paniikkiutuu eri viesteillä riippuen siitä, onko arvo liian pieni vai liian suuri.

Filename: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs:here}}
Listing 11-9: Testaus panic!-kutsulle, jonka paniikkiviesti sisältää määritellyn osamerkkijonon

Tämä testi läpäisee, koska arvo, jonka laitamme should_panic-attribuutin expected-parametriin, on osamerkkijono viestistä, jolla Guess::new-funktio paniikkiutuu. Olisimme voineet määrittää koko odottamamme paniikkiviestin, joka tässä tapauksessa olisi Guess value must be less than or equal to 100, got 200. Mitä määrität riippuu siitä, kuinka uniikki tai dynaaminen paniikkiviesti on ja kuinka tarkka haluat testisi olevan. Tässä tapauksessa paniikkiviestin osamerkkijono riittää varmistamaan, että testifunktion koodi suorittaa else if value > 100 -tapauksen.

Nähdäksemme, mitä tapahtuu, kun should_panic-testi expected-viestillä epäonnistuu, tuodaan taas virhe koodiimme vaihtamalla if value < 1- ja else if value > 100 -lohkojen rungot:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs:here}}

Tällä kertaa kun ajamme should_panic-testin, se epäonnistuu:

{{#include ../listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt}}

Epäonnistumisviesti ilmaisee, että tämä testi todellakin paniikkiutui kuten odotimme, mutta paniikkiviesti ei sisältänyt odotettua merkkijonoa less than or equal to 100. Paniikkiviesti, jonka saimme tässä tapauksessa, oli Guess value must be greater than or equal to 1, got 200. Nyt voimme alkaa selvittää, missä virheemme on!

Result<T, E>-tyypin käyttö testeissä

Kaikki testimme tähän asti paniikkiutuvat epäonnistuessaan. Voimme myös kirjoittaa testejä, jotka käyttävät Result<T, E>-tyyppiä! Tässä on testi listauksesta 11-1, kirjoitettu uudelleen käyttämään Result<T, E>-tyyppiä ja palauttamaan Err paniikkiutumisen sijaan:

{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs:here}}

it_works-funktiolla on nyt palautustyyppi Result<(), String>. Funktion rungossa kutsumme assert_eq!-makron sijaan Ok(()), kun testi läpäisee, ja Err-arvoa, jonka sisällä on String, kun testi epäonnistuu.

Testien kirjoittaminen niin, että ne palauttavat Result<T, E>-tyypin, mahdollistaa kysymysmerkkioperaattorin käytön testien rungossa, mikä voi olla kätevä tapa kirjoittaa testejä, joiden pitäisi epäonnistua, jos mikä tahansa operaatio niiden sisällä palauttaa Err-variantin.

Et voi käyttää #[should_panic]-merkintää testeissä, jotka käyttävät Result<T, E>-tyyppiä. Varmistaaksesi, että operaatio palauttaa Err-variantin, älä käytä kysymysmerkkioperaattoria Result<T, E>-arvolla. Sen sijaan käytä assert!(value.is_err()).

Nyt kun tiedät useita tapoja kirjoittaa testejä, katsotaan, mitä tapahtuu, kun ajamme testejämme, ja tutkitaan eri vaihtoehtoja, joita voimme käyttää cargo test -komennolla.