Programiranje

Testno prvi razvoj s FitNesse

V zadnjih nekaj letih sem delal v vseh vlogah preskusnega procesa, pri čemer sem uporabljal strežniške JavaScript, Perl, PHP, Struts, Swing in modelne arhitekture. Vsi projekti so se razlikovali, vendar so bili vsi skupni: roki so zamujali in projekti so imeli težave pri uresničitvi tistega, kar je kupec res potrebno.

Vsak projekt je imel neke zahteve, nekateri so bili zelo podrobni, nekateri pa le nekaj strani. Te zahteve so običajno potekale v treh fazah:

  • Napisali so jih (bodisi kupec bodisi izvajalec) in prejeli nekakšen uradni sprejem
  • Preizkuševalci so poskušali delati z zahtevami in so se jim zdeli bolj ali manj neustrezni
  • Projekt je vstopil v fazo sprejemnega testiranja in stranka se je nenadoma spomnila vseh stvari, ki jih je programska oprema morala narediti dodatno / drugače

Zadnja faza je privedla do sprememb, ki so privedle do zamujenih rokov, ki so razvijalce poudarili, kar pa je povzročilo več napak. Število napak je začelo hitro naraščati in splošna kakovost sistema je upadala. Sliši se znano?

Poglejmo, kaj je šlo narobe v zgoraj opisanih projektih: kupec, razvijalec in preizkuševalec niso sodelovali; zahteve so nadaljevali, vendar je imela vsaka vloga različne potrebe. Poleg tega so razvijalci običajno razvili nekakšne avtomatizirane teste, preizkuševalci pa so poskušali avtomatizirati tudi nekatere teste. Običajno testiranja niso mogli dovolj uskladiti in veliko predmetov je bilo testiranih dvakrat, drugi (običajno trdi deli) pa sploh ne. In kupec ni videl testov. Ta članek opisuje način reševanja teh težav s kombiniranjem zahtev z avtomatiziranimi testi.

Vstopite v FitNesse

FitNesse je wiki z nekaterimi dodatnimi funkcijami za sprožanje testov JUnit. Če te teste kombiniramo z zahtevami, so konkretni primeri in s tem zahteve še bolj jasne. Poleg tega so testni podatki logično organizirani. Najpomembnejša stvar pri uporabi FitNesse pa je ideja za njim, kar pomeni, da se zahteve izkažejo (delno) kot preskusi, zaradi česar jih je mogoče preizkusiti in s tem preveriti njihovo izpolnjevanje.

Z uporabo FitNesse bi bil razvojni postopek lahko videti takole: Inženir zahtev napiše zahteve v FitNesse (namesto v Wordu). Kupca skuša čim bolj vključiti, vendar tega običajno ni mogoče doseči vsak dan. Preizkuševalec večkrat pokuka v dokument in že od prvega dne postavi težka vprašanja. Ker preizkuševalec misli drugače, ne razmišlja: "Kaj bo naredila programska oprema?" ampak "Kaj bi lahko šlo narobe? Kako ga lahko prekinem?" Razvijalec razmišlja bolj kot inženir zahtev; želi vedeti: "Kaj mora narediti programska oprema?"

Tester začne pisati svoje teste zgodaj, ko zahteve še niso izpolnjene. In jih zapiše v zahteve. Preizkusi postanejo del ne le zahtev, temveč tudi postopka pregleda / sprejemanja zahtev, ki ima nekaj pomembnih prednosti:

  • Stranka razmišlja tudi o testih. Ponavadi se celo vključi v njihovo ustvarjanje (morda boste presenečeni, kako zabavno se s tem lahko zabava).
  • Specifikacija postane veliko bolj natančna in natančna, saj so testi običajno bolj natančni kot zgolj besedilo.
  • Zgodaj razmišljati o resničnih scenarijih, zagotoviti preskusne podatke in izračunati primere daje bistveno bolj jasen pogled na programsko opremo - kot prototip, le z več funkcijami.

Nazadnje so zahteve predane razvijalcu. Zdaj ima lažje delo, saj je zaradi vseh vključenih primerov manj verjetno, da se bo spremenila. Poglejmo, kako ta postopek razvijalcu olajša delo.

Izvajanje testa najprej

Običajno je najtežji del začetka razvoja preizkusov najprej ta, da nihče ne želi porabiti toliko časa za pisanje testov, šele nato najti način, da bodo delali. Z zgoraj opisanim postopkom razvijalec prejme funkcionalne teste kot del svoje pogodbe. Njegove naloge se iz »Zgradi stvar, ki jo želim, in končal si, dokler ne preučim tvojega dela in naredim spremembe«, spremenijo v »Naj ti preskusi delujejo in končaš«. Zdaj imajo vsi boljše ideje, kaj storiti, kdaj naj bi se delo končalo in kje projekt stoji.

Vsi ti testi ne bodo avtomatizirani in ne bodo vsi enotni testi. Preizkuse običajno razdelimo v naslednje kategorije (podrobnosti sledijo):

  • Preizkusi na osnovi podatkov, ki jih je treba izvesti kot enote. Tipičen primer so izračuni.
  • Preizkusi na podlagi ključnih besed, ki avtomatizirajo uporabo aplikacij. To so sistemski testi in zahteva, da se aplikacija izvaja. Kliknemo gumbe, vnesemo podatke in preverimo, ali strani / zasloni, ki vsebujejo, vsebujejo določene vrednosti. Preizkusna skupina običajno izvaja te teste, vendar imajo od njih koristi tudi nekateri razvijalci.
  • Ročni testi. Ti testi so bodisi predragi za avtomatizacijo in možne napake niso dovolj resne, bodisi so tako temeljni (začetna stran ni prikazana), da bi lahko takoj odkrili njihovo okvaro.

Ko sem leta 2004 prvič prebral o FitNesseju, sem se zasmejal in rekel, da nikoli ne bo šlo. Zamisel, da bi svoje teste zapisal v wiki, ki bi jih samodejno spremenil v teste, se mi je zdela preveč nesmiselna. Izkazalo se je, da sem se motil. FitNesse je res tako preprost, kot se zdi.

Ta preprostost se začne z namestitvijo. Prenesite celotno distribucijo FitNesse in jo razpakirajte. V naslednji razpravi predvidevam, da ste razpakirali distribucijo v C: \ fitnesse.

Zaženite FitNesse tako, da zaženete run.bat (run.sh na Linuxu) v C: \ fitnesse. Privzeto FitNesse zažene spletni strežnik na vratih 80, vendar lahko z dodajanjem določite druga vrata, recimo 81 -p 81 v prvo vrstico v paketni datoteki. To je vse; zdaj lahko dostopate do FitNesse na // localhost: 81.

V tem članku uporabljam različico Java FitNesse v sistemu Windows. Vendar pa je primere mogoče uporabiti tudi za druge različice (Python, .Net) in platforme.

Nekaj ​​testov

Spletna dokumentacija FitNesse ponuja nekaj preprostih primerov (primerljivih z zloglasnim primerom denarja iz podjetja JUnit) za začetek. Lahko se naučijo uporabljati FitNesse, vendar niso dovolj zapleteni, da bi prepričali nekatere dvomljivce. Zato bom uporabil resnični primer enega od svojih nedavnih projektov. Težavo sem bistveno poenostavil in koda, ki ni bila povzeta neposredno iz projekta, je bila napisana za ponazoritev. Kljub temu bi moral biti ta primer dovolj zapleten, da dokaže moč FitNessejeve preprostosti.

Predpostavimo, da delamo na projektu, ki za veliko zavarovalnico izvaja kompleksno programsko opremo, ki temelji na Javi. Izdelek bo vodil celotno poslovanje podjetja, vključno z upravljanjem strank in pogodb ter plačili. Za naš primer si bomo ogledali majhen del te aplikacije.

V Švici so starši upravičeni do enega otroškega dodatka na otroka. To nadomestilo prejmejo le, če so izpolnjene določene okoliščine, znesek pa se razlikuje. Sledi poenostavljena različica te zahteve. Začeli bomo s "tradicionalnimi" zahtevami in jih nato preselili v FitNesse.

Obstaja več faz otroškega dodatka. Zahtevek se začne prvi dan meseca, ko se otrok rodi, in konča zadnji dan meseca, ko otrok doseže starostno mejo, zaključi vajeništvo ali umre.

Po dopolnjenem 12. letu starosti se terjatev zviša na 190 CHF (švicarski uradni simbol valute) z začetkom na prvi dan meseca rojstva.

Kot je prikazano na sliki 1, polni in krajši delovni čas staršev vodi do različnih zahtevkov.

Trenutna stopnja zaposlenosti se izračuna na podlagi pogodb o delu. Pogodba mora biti veljavna in če je določen končni datum, mora biti v "aktiviranem obdobju". Slika 2 prikazuje, koliko denarja je starš upravičen, odvisno od starosti otroka.

Predpisi, ki urejajo ta plačila, se prilagodijo vsaki dve leti.

Ob prvem branju se lahko specifikacija sliši natančno, razvijalec pa jo mora biti sposoben enostavno izvajati. Toda ali smo resnično prepričani o mejnih pogojih? Kako bi preizkusili te zahteve?

Mejni pogoji
Mejni pogoji so razmere neposredno na, nad in pod robovi vhodnih in izhodnih razredov enakovrednosti. Izkušnje kažejo, da imajo testni primeri, ki raziskujejo robne pogoje, višjo korist kot testni primeri, ki tega ne storijo. Tipičen primer je zloglasni "enkratni" zank in nizov.

Scenariji so lahko v veliko pomoč pri iskanju izjem in mejnih pogojev, saj so dober način, da strokovnjake za domene pogovorite o poslu.

Scenariji

Za večino projektov inženir zahtev preda specifikacijo razvijalcu, ki preuči zahteve, postavi nekaj vprašanj in začne oblikovati / kodirati / testirati. Nato razvijalec programsko opremo preda testni skupini in jo po nekaj predelavah in popravkih posreduje stranki (ki bo verjetno pomislila na nekatere izjeme, ki zahtevajo spremembe). Če besedilo premaknete v FitNesse, tega postopka ne boste spremenili; dodajanje primerov, scenarijev in testov pa bo.

Scenariji so še posebej koristni za zavijanje krogle med testiranjem. Sledi nekaj primerov. Odgovor na vprašanje, koliko otroškega dodatka je treba plačati vsakemu, bo veliko pojasnil:

  • Maria je samohranilka. Ima dva sinova (Bob, 2 in Peter, 15), honorarno pa dela (20 ur na teden) kot tajnica.
  • Maria izgubi službo. Kasneje dela 10 ur na teden kot prodajalka v trgovini in še 5 ur kot varuška.
  • Paul in Lara imata hčerko (Lisa, 17), ki je gibalno ovirana, in sina (Frank, 18), ki je še vedno na univerzi.

Že pogovor skozi te scenarije bi moral pomagati postopku testiranja. Če jih ročno zaženete v programski opremi, boste skoraj zagotovo našli nekaj prostih koncev. Mislite, da tega ne moremo storiti, saj prototipa še nimamo? Zakaj ne?

Testiranje na podlagi ključnih besed

Testiranje na podlagi ključnih besed je mogoče uporabiti za simulacijo prototipa. FitNesse nam omogoča, da določimo teste na podlagi ključnih besed (za podrobnosti glejte "Popolnoma avtomatizirano testiranje na podlagi podatkov"). Tudi brez programske opreme za (samodejno) izvajanje preskusov, bodo preskusi na podlagi ključnih besed zelo pomagali.

Na sliki 3 je prikazano, kako bi lahko izgledal preskus s ključnimi besedami. Prvi stolpec predstavlja ključne besede iz FitNesse. Drugi stolpec predstavlja metode v razredu Java (pišemo jih in morajo slediti omejitvam, ki veljajo za imena metod v Javi). Tretji stolpec predstavlja podatke, vnesene v metodo iz drugega stolpca. Zadnja vrstica prikazuje, kako bi lahko izgledal neuspešen test (opravljeni testi so zeleni). Kot lahko vidite, je zelo enostavno ugotoviti, kaj je šlo narobe.

Takšne teste je enostavno in celo zabavno ustvariti. Preizkuševalci brez znanja programiranja jih lahko ustvarijo, stranka pa jih lahko prebere (po kratkem uvodu).

Tako definiranje testov, tik ob zahtevi, ima nekaj pomembnih prednosti pred tradicionalno definicijo testnih primerov, tudi brez avtomatizacije:

  • Kontekst je na dosegu roke. Testni primer je mogoče napisati z najmanj možno količino dela in je še vedno natančen.
  • Če se zahteva spremeni, obstaja velika verjetnost, da se bo tudi test spremenil (ob uporabi več orodij ni zelo verjetno).
  • Preizkus je mogoče izvesti naenkrat, da pokaže, kaj je treba popraviti, da bo ta nova / spremenjena zahteva delovala.

Za avtomatizacijo testa se ustvari tanek sloj programske opreme, ki se prenese na pravo testno kodo. Ti testi so še posebej uporabni za avtomatizacijo ročnih testov GUI. Razvil sem testni okvir, ki temelji na HTTPUnit za avtomatizacijo testiranja spletnih strani.

Tu je koda, ki jo FitNesse samodejno izvrši:

paket stephanwiesner.javaworld;

uvoz fit.ColumnFixture;

javni razred ChildAllowanceFixture razširja ColumnFixture {public void personButton () {System.out.println ("pritisk na gumb osebe"); } public void securityNumber (int številka) {System.out.println ("vnos varnostne številke" + številka); } public int childAllowance () {System.out.println ("izračun otroškega dodatka"); vrnitev 190; } [...]}

Rezultate testov lahko preverite tudi v FitNesse (glejte sliko 4), kar zelo pomaga pri odpravljanju napak. V nasprotju z JUnit, kjer se odsvetuje pisanje sporočil za odpravljanje napak, se mi zdijo nujno potrebna pri delu z avtomatiziranimi spletnimi testi.

Pri preizkušanju spletne aplikacije se na strani FitNesse vključijo in prikažejo strani z napakami, ki olajšajo razhroščevanje kot delo z dnevnimi datotekami.

Testiranje na podlagi podatkov

Čeprav je testiranje na podlagi ključnih besed v redu za avtomatizacijo grafičnega uporabniškega vmesnika, je testiranje na podlagi podatkov prva izbira za testiranje kode, ki opravi kakršen koli izračun. Če ste že pisali enote, kaj je pri teh testih najbolj moteče? Verjetno pomislite na podatke. Vaši testi bodo polni podatkov, ki se pogosto spreminjajo, zaradi česar je vzdrževanje nočna mora. Testiranje različnih kombinacij zahteva drugačne podatke, zaradi česar so vaši testi zapleteni, grdi.

$config[zx-auto] not found$config[zx-overlay] not found