Sissejuhatus üksuste testimisse Pythonis

Lõpetasite just koodijupi kirjutamise ja mõtlete, mida teha. Kas esitate tõmbenõude ja lasete tiimikaaslastel koodi üle vaadata? Või testite koodi käsitsi?

Peaksite tegema mõlemad need toimingud, kuid täiendava sammuga: peate oma koodi testima, et veenduda, kas kood töötab ettenähtud viisil.

Ühikutestid võivad läbida või ebaõnnestuda ning see teeb neist suurepärase tehnika teie koodi kontrollimiseks. Selles õpetuses näitan, kuidas Pythonis üksuste teste kirjutada, ja näete, kui lihtne on neid oma projektis käivitada.

Alustamine

Parim viis testimise mõistmiseks on see, kui teete seda praktiliselt. Sel eesmärgil kirjutan faili name_function.py lihtsa funktsiooni, mis võtab ees- ja perekonnanime ning tagastab täisnime:

#Generate a formatted full name def formatted_name(first_name, last_name): full_name = first_name + ' ' + last_name return full_name.title()

Funktsioon vormindatud_nimi () võtab ees- ja perekonnanime ning ühendab need tühikuga täisnime moodustamiseks. Seejärel tõstetakse iga sõna algustäht suurtähega. Selle koodi toimimise kontrollimiseks peate kirjutama koodi, mis seda funktsiooni kasutab. Aadressil names.py kirjutan lihtsa koodi, mis võimaldab kasutajatel sisestada oma ees- ja perekonnanime:

from name_function import formatted_name print("Please enter the first and last names or enter x to E[x]it.") while True: first_name = input("Please enter the first name: ") if first_name == "x": print("Good bye.") break last_name = input("Please enter the last name: ") if last_name == "x": print("Good bye.") break result = formatted_name(first_name, last_name) print("Formatted name is: " + result + ".")

See kood impordib format__name () from name_function.py ja töötab, võimaldab kasutajal sisestada rea ​​ees- ja perekonnanimesid ning kuvab vormindatud täisnimed.

Ühikutest ja testjuhtumid

Pythoni standardses teegis on moodul nimega unittest, mis sisaldab tööriistu koodi testimiseks. Üksuse testimine kontrollib, kas teie funktsiooni käitumise kõik konkreetsed osad on õiged, mis muudab nende integreerimise teiste osadega palju lihtsamaks.

Testjuhtum on ühikutestide kogum, mis koos tõestab, et funktsioon töötab kavandatud viisil kõigis olukordades, kus see funktsioon võib sattuda ja mida ta eeldatavasti haldab. Testjuhtum peaks kaaluma kõiki võimalikke sisendeid, mida funktsioon kasutajatelt saaks, ja seetõttu peaks see hõlmama teste, mis esindaksid neid olukordi.

Testi sooritamine

Siin on tüüpiline stsenaarium testide kirjutamiseks:

Kõigepealt peate looma testfaili. Seejärel impordige unittest-moodul, määrake testimisklass, mis pärineb unittest.TestCase'ist ja lõpuks kirjutage rida meetodeid oma funktsiooni käitumise kõigi juhtumite testimiseks.

Järgmise koodi all on rida realt selgitus:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger")

Esiteks peate importima unittesti ja funktsiooni, mida soovite testida, vormindatud_nimi (). Seejärel loote klassi, näiteks NamesTestCase, mis sisaldab funktsiooni vormindatud_nimi () teste. See klass pärib klassi unittest.TestCase.

NamesTestCase sisaldab ühte meetodit, mis testib vormingu_nimi () ühte osa. Seda meetodit saate kutsuda test_first_last_name ().

Pidage meeles, et iga meetod, mis algab tähega „test_”, käivitatakse automaatselt, kui käivitate test_name_function.py.

Testmeetodi test_first_last_name () raames kutsute funktsiooni, mida soovite testida, ja salvestate tagastusväärtuse. Selles näites kutsume vormingut_nimi () argumentidega "pete" ja "seeger" ning salvestame tulemuse saadud muutujasse.

Viimases reas kasutame kinnitusmeetodit. Kinnitusmeetod kinnitab, et saadud tulemus vastab tulemusele, mille eeldatavasti soovite saada. Ja sel juhul teame, et funktsioon formatted_name () tagastab täisnime suurtähtedega, seega eeldame tulemust “Pete Seeger”. Selle kontrollimiseks kasutatakse unittesti meetodit assertEqual ().

self.assertEqual(result, “Pete Seeger”)

See rida tähendab põhimõtteliselt: võrrelge saadud muutuja väärtust väärtusega „Pete Seeger” ja kui need on võrdsed, on kõik korras, kuid kui neist ei teatata.

Test_name_function.py käivitamisel peaksite saama OK, mis tähendab, et test on läbitud.

Ran 1 test in 0.001s OK

Katse läbikukkumine

Et näidata teile, kuidas ebaõnnestunud test välja näeb, muudan funktsiooni formatted_name (), lisades uue keskmise nime argumendi.

Nii et ma kirjutan funktsiooni ümber nii, et see näeks välja järgmine:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name, middle_name): full_name = first_name + ' ' + middle_name + ' ' + last_name return full_name.title()

See vormingu_nimi () versioon töötab keskmise nimega inimeste jaoks, kuid seda testides näete, et funktsioon on rikutud inimeste jaoks, kellel pole keskmist nime.

Nii et kui käivitate test_name_function.py, saate väljundi, mis näeb välja umbes selline:

Error Traceback (most recent call last): File “test_name_function.py”, line 7, in test_first_last_name result = formatted_name(“pete”, “seeger”) TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’ Ran 1 test in 0.002s FAILED (errors=1)

Väljundis näete teavet, mis ütleb teile kõik, mida peate teadma, kus test ebaõnnestub:

  • Esimene väljundi element on viga, mis ütleb teile, et vähemalt üks testjuhtumi test tõi kaasa vea.
  • Järgmisena näete faili ja meetodit, milles viga ilmnes.
  • Pärast seda näete rida, milles viga ilmnes.
  • Ja mis viga see on, sel juhul on meil puudu 1 argument “kesknimi”.
  • Samuti näete testide arvu, testide lõpuleviimiseks vajalikku aega ja tekstisõnumit, mis tähistab testide olekut koos ilmnenud vigade arvuga.

Mida teha, kui test on ebaõnnestunud

Katse läbimine tähendab, et funktsioon käitub vastavalt sellele, mida temalt oodatakse. Ebaõnnestunud test tähendab aga, et teid ootab veel lõbusam.

Olen näinud paari programmeerijat, kes eelistavad koodi parandamise asemel testi muuta - aga mitte sellega. Kulutage probleemi lahendamiseks veidi rohkem aega, kuna see aitab teil koodi paremini mõista ja pikas perspektiivis aega kokku hoida.

In this example, our function formatted_name() first required two  parameters, and now as it is rewritten it requires one extra: a middle name. Adding a middle name to our function broke the desired behavior of  it. Since the idea is not to make changes to the tests, the best solution is to make middle name optional.

After we do this the idea is to make the tests pass when the first and last name are used, for example “Pete Seeger”, as well as when first, last and middle names are used, for example “Raymond Red Reddington”. So  let’s modify the code of formatted_name() once again:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name,): if len(middle_name) > 0: full_name = first_name + ' ' + middle_name + ' ' + last_name else: full_name = first_name + ' ' + last_name return full_name.title()

Now the function should work for names with and without the middle name.

And to make sure it still works with “Pete Seeger” run the test again:

Ran 1 test in 0.001s OK
Ja seda ma kavatsesin teile näidata: alati on parem koodis muudatusi teha, et need vastaksid teie testidele, kui vastupidi. Nüüd on aeg lisada uus test nimedele, millel on keskmine nimi.

Uute testide lisamine

Kirjutage NamesTestCase klassi uus meetod, mis testib keskmisi nimesid:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger") def test_first_last_middle_name(self): result = formatted_name("raymond", "reddington", "red") self.assertEqual(result, "Raymond Red Reddington")

Pärast testi käivitamist peaksid mõlemad testid läbima:

Ran 2 tests in 0.001s OK
Rinnahoidja gjort!

Hästi tehtud!

Olete oma testid kirjutanud, et kontrollida, kas funktsioon töötab nimedega koos keskmise nimega või ilma. Püsige 2. osas, kus räägin rohkem Pythonis testimisest.

Aitäh, et lugesid! Vaadake veel selliseid artikleid minu freeCodeCampi profiilis: //www.freecodecamp.org/news/author/goran/ ja muud lõbusat, mida ma oma GitHubi lehele ehitan: //github.com/GoranAviani