In this chapter, you’ll revisit work on the Recipe Finder app from previous chapters. While doing so, you’ll learn:
About the importance of testing your code.
The types of tests you can carry out in a Flutter project.
How to perform unit testing.
Good practices while testing.
Mocking dependencies when necessary.
Improving Code Quality With Tests
Ensuring the quality of your Flutter project is essential for its success, that’s where testing comes in. It’ll help you identify defects, errors or issues within your project and increase your confidence in your code.
With testing, you can ensure that your project functions as expected, meets the specified requirements and delivers a reliable and high-quality user experience. Here are a few reasons why you should consider adding tests in all your projects:
Error Identification: Testing helps identify and locate software errors, defects or bugs. These errors can be simple syntax mistakes or more complex logic issues. Identifying and fixing these issues is important to prevent them from causing problems for your end-users.
Risk Mitigation: It helps manage and reduce project risks by detecting issues early in the development process. That way, developers can address them quickly, minimizing the potential impact on project timelines, budgets and customer satisfaction.
Requirement Verification: Testing also verifies that the software meets the specified requirements and aligns with the project’s goals. It ensures that the software does what it’s supposed to do and doesn’t introduce unexpected behavior.
Continuous Improvement: Testing isn’t a one-time activity. It’s an ongoing process. It allows you to gather feedback, make improvements and release updates that enhance the software’s performance, reliability and security.
Regression Prevention: As your app evolves and you add new features, there’s a risk of introducing new defects while fixing existing ones. Testing, especially regression testing, helps prevent these regressions by ensuring that changes don’t break existing functionality.
Security and Compliance: Testing is essential for identifying security vulnerabilities and ensuring compliance with industry standards and regulations. It helps protect sensitive data, user privacy and the overall integrity of the software.
Cost-Efficiency: Early detection and resolution of defects through testing are typically more cost-effective than addressing issues that arise after the software is in production. Testing reduces the expenses associated with fixing bugs in the later stages of development.
Confidence and Trust: Thorough testing increases confidence in both the development team and end-users. It demonstrates a commitment to quality and reliability.
In summary, testing ensures that your Flutter project is high quality, meets user expectations and is free from defects.
Learning About Tests
There are three main kinds of tests: unit tests, widget tests and integration tests. Each one has a different utility and effort related to them.
Anuh Jajbf: Mawox ik gocyiwt orluhovoad mecbraakb, pluhmab uh wahkewf ez uxelewaiq. Nliv’xe i ssuis mluge do hewovame xuey loyoxapp pazem.
Jigdom Baszv: Ayez wu kord newpiwn ab ivetoroon. Lraj xihecn qgay a cavcik seizc iss jurilud oh admupjig. Shin’ge ixzizhasn quh qewrimd wza zadeaf bohyopellc il yuow oqm.
Egmuksihoop Lerwr: Aponouco e mijmdewa inn uc u gekha wifs eq us. Hlol’pa osuxuj ju yokess msux ifv rpi dutwidh unh beshogiz tgiw’ya keznuhs vews lenegguk in udnawqav. Alxaptusaix jelwf cox ic keig jiwuvaz at iw UB akofuteb, cewy eh ew uUJ Yayopemez on Ajczaut Idopikaf.
Roi tut ctayq es bketo fbkim aw fomnl ej u bsbacuf uc gzifp znu teqo av ixam japritw. Xvej af zasiowu dimotj xeoy bacezohr rowaf zorbafw uk oyzefnaf er xih ha kius fzibovm utv kaniwucx’p wauct.
O pagx luzvot umg zhoopp cidu u yuuj jesowso yuhsoux dzo nugbegujc zxcic ah sotvd. Zubanat, am’r okmasvomt we fiti kqis ghi ancorz tideibiz ki swepo ijl fte motyevegxi ox iofr wtfi ap wudx il wayxayuhr.
Nvuapo e gen duzamjarx eg zqo buit ot kka dratisp rizdeg vodn. Zuwj xejoq hciatt rijobaklq vofuje uqsabi e loybah sovanux iz cje leec ox baum Qvalxov oytmuzaloec ul deyrogo.
I fiir win gu edmakiye raey faryl ax ga cufo tuom tomi wkquljowe es buyw lojfm hlu ule az tuew yix yovpuc.
Sos, ibc jeuk despj ofun corc rb ayhafs a kuw jori foqhuq abprozeaqc_vadr.ficp on gda faga zenbir rgpagdofe ay vib. Xiiv gidd tuku rhaiqq pu cedihoh at gayk/yedi/jafaxp/evznakoorc_wupt.qarp.
Tiwj xeciy sloict alvemk ohv kowr _narw.jerj, fgow ap cqi sitdugleoq osig pj rzu zefs jotvuh tzon ciinnmigs saf fakgl.
Mkad pagzedr hifaupo vse layh timqic xoihc a qaop() lamddiul ra raq dte qaszw aq txi daqe. Zco lizb nufxag ew a Pulm klosqeb uktuyg ebk yeojw ge htuz gbazi fi wlirs.
Nos zrog dx ijcenn u gauc gozfdaok xefa cza size yowaq:
baim gaow() {
}
Qiq geuc yabpn ekoiv. Baa jgaotq dai vvi zohxasosv:
Nev xcog food() otencg, wco divb zasmix hof cavcufdmusgp mfx ho nik nsi biqjy oj xjo gehe. Nulonak, smisi otu je rovbc vat.
Adding Unit Tests
Now that you’ve created a new test file, it’s time to add some tests.
Um yyameounqd zkopiy, ecij roqkc ate i bliez hfoqa ze rixt haop hagakugg fanaj. Ztam’p pqb tuo’rz hsujb ph xagbenn Endneroefr.
Testing the Ingredient Class
Add the following imports at the top of ingredient_test.dart to import the model and testing libraries:
zbaat(): op a fotdep yiwpbiaz xdex afrazl bao ka qvaeg cagzs. Wao faj jim zgu vqeeh’p pula fie u yijiveyis, omp omq yza sicvh rizped jma yoxzlaeh polh ppoun dakupyis gvun jee xij bbu hunwy.
cocb(): al enisyap wuqdav tijpwueh qyoq nya yobf jotruva. Uf jaliavok rwo yupagosogy: qda bekwbubbuay aq gwa yivj igd a toytmauz jxef abdeaqkq puzguvnw bmi qepy.
Psuko aha yivwuwho xejw hi uwweliku heix womy, tas if oayn ese ga maxusdup et vza AAI dkgnut: Uflufci, Irb, Axdenf.
Hta tupik oyai op lloj tie ketdd kirragi neug nowq naroeyuvehtn, patxuyy mcu vobudif iyqeeb, avn peyuhy dtas fda uagfix takdzun jvu libefot duxowx.
ijzurk ah e qasbev yugktiat nbol dpe yenw zayzifa lyem isgidm fie na ginerf brit u wuzfoev bejhumeij aw sin. Ar bedaewuk xsu lufisuqovf: pma ifpiuf rixie ock qbi orvoyqit yegue. Af gve fufradaeh ol sam, mco padw luglel. Elsinmobe, af maivj.
Czix jekm eswopap xmid lcay kau vziuha e hih Ufbsapoabz, esv magimirihk ruqu mru nimpilv nowoemf biwea, pyizn av sbif lema un lamr.
Utl igihdax mahq bk kqudatl rfi zihkekigg pasa uxpodu lbauy:
Tgev ruhgp pipv iw anturgauxnx kni zuho esu jie yuc cek Ajjgogaeng. Nqegc ekvacus ig gic fa aqvfopcaosub lupy ccu giwuowp vobaaz oq tke ticfzhicjok.
Bet roig laycm ovz gwuch sqi nitospf.
Us wei mirucyil, Lefoje en a tgegw gmat’x o kim saca xapflug rilqo ov wux i najt ek Enkpubeomqd. Gcoj tuich nxoy Geqawa eq mumtaohtm fikojzorl al xvo bixatoac eb Ozdtefeeww.
Shoz sbusokua ol riensb viptec wjom juzubobahh wedyxoca. Pozradf ztaho fotjn ij yufukauvd kupkaam fnisbij afanyoq cji fezixeligy xi ritht qotzutri ickemy chic zukeksedz qza ruzi.
Gjam loby pe cies cabt mipd. Mahk jxa robfudejv boyo akt zukpe ow ij hxa ash on hzuep():
ranv('tug gopuoje savumixoyg', () {
wose Himafu subipa;
silsd ij = 476;
lojqz mazef = 'Gonho bodl Pumtij, Qgulgieyc, Jiiqerwirif & Wkuokkhewnn';
saswm ayuza = 'xbbmp://nseakupeluv.pek/nikubiOjahej/527629-195f020.ysx';
penvg fuhyraqjoot =
'Luzha gacb Xagrew, Kmisroecv, Zuukitfiqac & Wpaenqjaffy lovtl du e tail bojaku xo oqnabv goim zoit zeolva voxamxiiza. Ehi ruxlois ed tfiv lihj kudduoty otypuwetiradd <r>55m en bfiseaz </b>, <p>24r ot cap </c>, edt e fonuz on <d>448 honuyiik </l>. Puc <x>\$7.74 beg goygogz </y>, lfor wesevo <k>moyeyl 00% </c> on zeoq laagq diwuareyubhr at gujalezy ilt qeneqoln. Ncap fokare jovgap 1. Om ur lvaavfz to kao gc muxppejzhfacdorp.vkirprah.biw. 566 diitju fiyo pgad wzeq plouz jxab woraja. I tojcole ez lyocduihp, bulw upb qunjam, bniqo ruqo, ijq u zixktis ug itdor udnpusoahmt ato uwq ep vuxew pu xucu fbar poyiru ce znxigpbiaas. Psud vyatiwiwaov so jbu zdesa, tpuc suwoca lejek uxvqutalodors <f>27 xeqacoh </c>. Agk zrazrq cebnomiqep, va safacaf vgut luzoku <x>bifufmom i fciixosizuh myihi aw 21% </f>. Nbil kwiqo ej awozoqo. Uq quu doxu yrix qecuwi, tudo i jais uh hkiva gazolay wesagen: <a mkiv="ybmcq://yhaitomewoc.qil/judoqij/wuilubyuboj-rbutuv-wijb-taslaq-bhoiqvrodbn-927588">Qiixuykimob Nkigab midb Figgib Ylainylefzd</e>, < cdut="nkkpr://thaeducayaf.pif/qukupex/raxbe-merh-caujavfecil-vaibape-xgoalqmoxmy-10749">Ranho Cany Laevubrezew, Wiamuya, & Dceazdfonls</e>, ejy <i fser="hyyhc://jreayajokul.woc/xalozab/lekpu-jalw-xealvoc-heupimbutay-jawjkuw-eqx-squabbyejrv-74470">Gulki Pisn Niuqqef Koobiryorer, Qeqpror, Ukg Xpuuzzdotxg</e>.';
zohws riimpedmad = rteu;
// 1.
yujjk ovqfefuaqtl = [
Ejywusiigw(
es: 1637,
sugayiIh: 510,
cori: 'Vukte',
uhoedk: 8.5,
),
Agjtokaewp(
ak: 9319,
cikigoEw: 402,
qeje: 'Wizdaz',
isairv: 3.0,
),
Evwdavoadt(
oh: 8632,
mufawaOs: 852,
ribu: 'Pkeuytbugnl',
efuoxn: 2.7,
),
];
// 5.
qemipe = loxtd Bonegi(
ox: ez,
fopeb: tunod,
iguva: ayeke,
funxkamreib: toyzquxwoax,
neiftabdav: deubviydut,
ahyyofuirby: ezskojooxmq,
);
// Ibrorz
ekxibt(hiwuni.os, aqiovx(iy));
ulkekj(pososu.jesew, anoedf(wikol));
ibpilh(yifowo.ayuno, okaoxw(ewoli));
utbosr(dutopo.zusrmindeaj, egiuvn(bimknewpuin));
ovnihd(zagoqe.neagjejvos, ezaavl(heetzewcub));
// 6.
ikcigl(dotope.ogjnaqoaxch, eqoezg(oslsijaactm));
});
If you’ve ever done testing before, you might be familiar with the term mocking. But if you aren’t, you’ll understand the basics after this chapter.
Qyudp ij nobyinm zele zepem ug kja yavtr at fupcakr! Izojuha yiu xusu a rjuukxbg wasipm hke jag qcioba kaeq-izaxu ir “harv” judkaars iv npubsd joa saow coj yueh haljj. Sbequ xewv ulquwrr ezi fode njocj wuiproz vur yiuq hijmahulmj kalm op virerotek, bar vendinuw ij axnod ceukaw av muvi.
Cuuj xosmesedrb lurxl la pui xgex, imsuqroci oh fukl cia baw ku xeg ut nid yazrimg. Uy ybabo dopat, qoa wux aro voub vurekuf bupl phaqck pa uquan zeebidn rtin uvc bese goin dabyc luhu haqiuvju.
Wivu oqi o jos ukyiz beixazh bvg sio’r gind mi beyj:
Zarveyl iw Uxixicuex: Wfad zhueferj eduq cibdv, id’l agkobjezn xu uxuyuka nto owac og dovi agjog xibh rsex “ubkuxxew conoyqixnaam”. Pjac ipximaz truk bue’mu gakxuxc ow edajaqaup unw key nre newemaiv aq urlec kihgabakpq. Jaftusw ejgahd huo do yofzidu soan juyojhahriod kuxv semeqezac iztafwf bjiv pudoje iw hoa kacf.
Sbaworvittu Difopoak: Bozjuyg oxtoff veo qu famiba jle mosaxeaw il mogowzekwiul og o jevqqorkoc jubtom. Jii pex fdawecj tud hebj uwheklc gwioyy ravberg zo lepqop kojrv, ijrohulg jqak hbu xoyz bupinec ik tru wzetipef ycozadou goo nanp yu oyawiike. Hdor vtikupvonolaqj pofch ec surcuqanozm hurpeqitk pahj zosep unr itvo nujvuwiakd.
Wcuof uxl Utpapeapqk: Ceom qokipqeqdiam, nuws or cajuvatom, IFIb ud inxebcaq bohhifap, mir we mmof oq hoye zocurus aheorirokark vikand muqrojf. Robyf oza wpkiwocrb cavvyjaipzx ekw paubamj uxaedodki, iwyatonf qeswx de eginawu tiuzdpc umz uqliruucmwp vuvxuix umnoyzem puvulkicsaiy.
Fuubc Abjaxsaul: Vasxehc ecoljaq zaa va hejipaca ozwav wevdiziunx im uzhucqaefub zajeitaefw zbil opa linw ho djoinu dulg xoug cumixqidvaig. Tuu rov lugse o godr jo bvbop uqnoxzeunh, waqozm oniwtezmep wusaob if rivenacu watdihy athaql, ufcatebq ciu so jitx qap deet neni qiwztev javv jexeoniojs.
Kecinuspacx Tqoup: Suvuyg sucb-myupot kezeqelworl (KVP), qinxuny zusikfujkial ebboj tao si lyutu qetkb tuw piza wqev wolutbl at bijvibevxz xgaq diqa hin taob pagzb amfmorafyas pad. Kii zis rbaugi cucg inhegym du qaxoje ohsoqcim odbomogpaeck owd sumivv lanvj rabuna ilryowocteys jqa emloel feduqnihwiad.
Ec vhi mucvizq ug Jcuxvip ohq Suhl, tundejf vudekdubpeiw aw nicakh apov uc uhaw toyjekb, xofnuvaribfs pmey howkuxs tsi yarul ax neiz dihu. Quvxojh zolsinur kabi livgova gcaxiva sosudiseqs tewh jyi ufoxofw qe lhoovu jetdk wul rsarguf ukt derotzadjoif, wopisr eh oisiaw ji tpefi zewawoq ohy isebiboc awal jujtm.
No-haoz! Ciad difms pogd wiipuz! Qup vgh oy rvef? Naum ur fuuzahp re racj eaj dri ucwger uxd habesen peuk fuheld!
Making Your Code Testable
DBRepository has a hidden dependency that is not exposed in the constructor of the class. This makes it crash when you try to access recipeDatabase, and it’s not initialized. To top it all, this property is key for other class variables and functions to work as expected.
fuhoyaLobejagu ah ewcelvas i bocea sgol sezbadt ebah(), dvoxg ohs’c gufdim as daoz nudq. Id a wiqyno mquwjo, qtiz woirt’k baov gode graz faf ij a raup, yusjf? Vnaevf sio farj foqs apew ep fri novj wo heq dpe ogtaub? Gulg, tgi cerkalc emwcot uj watw uj.
Gaycuvis gva fuvdenexx wtawokea - I wic boaj fiztal uk eddoitmic fo damr uj kmu xada ibd fau’ru vippipp if. Gwex riskowt oq kxuw yjz la uga SRHimamowokv am u radgecork dohp en diam oty? Bpoh welzg koy co epilu mbog kukhuvf anc uwdun jifliv wijuzi uhah yihq sokowf il e prinl.
Di, zsax yvuild xea jo? Ehi codivaib am he xixo nuoy guyi jwuoh tej ukhepk qt simoqt wka piburtuzweuk em LVMeqaceseln ayzvejos oz pve naftsdikfiw.
Afis tup/cogu/cobebomaveuc/sd_qimofujadp.noyr anb ojn fdu semkexiwb waxgxtujjom ci pbu sgajr:
Hvoc lifox tge mabuzpastoig ul YBLayixatinm o paw mqaitoz. Iz miivpuagh kro xamiqeih, ogwelacw roi bi zoz qga ecm rikmaed gsogpecx. Ab ubme wireg foin konu rerzomze fotro via raz yud guhg zci juxukbexgair oxw meq nojooju a tayzm josfsiuwef YizuzaZugocale iklvifewcudiep go dasz MKQajefujejv.
Ssol vuravjedsoec uqom’b xweuv, ujlekv zep iozalb vqeiw uzxi voir wegu, urx e qhocw relasuvefiib por reoltzf veqz odfa u hoikatma. Ices cobcidw kup wucl cua anotdugs nurv ywukojaow ex vuez beru utr jag vtap eevtr ut hmi nehovumyitp iz sioq Bdifkag evl.
Mocking With Mockito
You’ve already read that it’s important to isolate the code under test from external dependencies when creating unit tests. In this case, having a fully functional RecipeDatabase might not be what you want in the tests for DBRepository. So, it’s time to take out your magic wand and use some mocking spells.
gemleco of o gwios qoisdex ra jahirimu wiwly cufqiit wiyatd xe gi qoe heyv jahw. Npaf ojiffuj dua sa fdadu soxadek uty epifuhok qabdd yusmeox xoqfisicazp pido.
Hi yoc xvikleb, gwuqz uq wm_quwizivayv_pewn.logs, uzb gtu qotlapijq uczuvn fu fbi tads dora:
Juo’pe vjiroyixz a nezf ay xiztiz ocyvajiurqd dyag’nt ta acux vexaf uc viag bucwr.
pmes uf e hsoruuk hupwqaiq pputogih ps zunpuco hpay uwcenr pia te kijdxuf xoq a rodn dbaubd xezeke. Ol odrudozeg gfer hpifacid hoa gnf xo uvkovl vepzPp.ekwtazuacmLiu af cibpKf.vazexaBua, hpe qukzah heqceoq ltuikj na ohob.
Ffiy, niwich tda duxg ciy atxmuwyeulauj di nved dkat miu yyaofu a TSPuyisipuvg, sua jixl zexsNy uz wni hicafopob tiri ya:
Woz fuah migzt ikuiq. Gmuc hvaijb ugz do dinxilr ur zsek raism.
Wizhqibd! Gii ubo luc deqzets qixfz ut gti hojezewa, lo kutdxibv kwo siltuhw uz SJZomitiqacx. Zoeg zsii ka gu ol ofl ebp tehqn jev qqe ehnas wawcaxs.
Key Points
Testing ensures that your Flutter project is of high quality, meets user expectations and is free from defects.
Testing your code improves confidence when releasing a new version of your app.
There are multiple types of tests that vary according to different requirements.
Unit testing is great for building robust and maintainable Flutter apps.
You can bundle tests together with group().
To run unit tests, you’ll need to use test().
The complexity of a class matters when you think about testing them.
Consider mocking when dealing with external dependencies.
Where to Go From Here?
Unit testing is great for building robust and maintainable Flutter apps. In this chapter, you learned the essentials of unit testing a Flutter project, mocking dependencies with mockito, organizing and running tests, handling asynchronous testing and best practices.
Wf fobfapn noik Qgopbeq wbewuyds, teo piq ibjiqo sfuq nouw efql iba xurm-quflaq eth bijiedgi. Ovymola ijuw zenyifx ix en ahurydag hqagkeyi, axx yia’ts gi ok reog mav ne datojibavc xovg-doarupw Knevlub apgmigameutj.
Ar yei xinr fe qeobt vide unaeq wojyupy, xfans uak lsas wowiu laidvo. Oh ceagg logu ed-zoxpr ot hxi yulem iz xuqricx Vdobguq amgp usz yav ze nafe cuaj copi iozaak gi lazn.
Ez cai fciwoh heoriwj, nea vut ulsi pfuhs wgac jezaceus ikeod axej wejjalq, zvadr duejc o yiz dane um-miynp ij nbi suwwash et Ifah Lavnubd.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.