In the previous chapter, you learned how to use Firebase Crashlytics to efficiently track errors in your app. This knowledge plays an enormous role when resolving the existing issues your users face. However, the experience for your users would be even better if the app didn’t have those issues in the first place. It’s delusional to believe your app will be bug-free with your first release, but you still try to get as close to this ideal scenario as possible. You can achieve this with the help of testing.
Your QA team — or you and your fellow developers, if you work in a smaller team — can only do so much to test your app manually. That’s where automated testing can be a handy approach to make your work easier.
Besides being very limited with how much manual work you can perform — which relates directly to cost — performing automated tests also has other benefits. As people make mistakes, automated tests exclude the human error factor from app testing. With automated testing, you can get rid of repetitive work, perform the test with greater speed and consistency and test more frequently. All of these benefits result in a faster time to market.
Despite giving the impression that automated testing is this magical thing that will save you from all of the world’s problems, in some cases, manual testing is actually better. You should choose manual testing over automated testing in instances when test criteria are constantly changing, cases that aren’t routine and generally in situations when manual tests haven’t been executed yet.
You can use a few different types of automated tests for different parts of your app. To ensure that your app is well-tested, you have to provide high test coverage. This is the percentage of your app’s executed code covered by automated tests. In other words, an app with high test coverage is less likely to run into undetected bugs.
In this chapter, you’ll learn about:
Unit tests.
Widget tests.
Integration tests.
Using mocking and stubbing.
Writing and executing examples of each test type.
Throughout this chapter, you’ll work on the starter project from this chapter’s assets folder.
Note: If you’re having trouble running the app or the tests, you might have forgotten to propagate the configurations you did in the first chapter’s starter project to the following chapters’ materials. If that’s the case, please revisit Chapter 1, “Setting up Your Environment”.
Types of Tests
As already mentioned, there are quite a few different types of automation tests. In this chapter, you’ll mainly deal with three test types — unit tests, widget tests and integration tests. You’ll get deeper into those in just a moment.
For general knowledge purposes, it’s also worth mentioning some other types, though they’re not as important in testing mobile apps. They are:
Smoke testing, also known as confidence testing, is a set of tests designed to assess the stability of a deployed build.
Golden file testing is a special type of testing in which you compare specific behavior to the golden file. In the case of API testing, this golden file can be the response you expect from the API. On the other hand, when testing your mobile app’s UI, the golden file would be the screenshot of the UI you expect to see on your mobile device.
Performance testing tests the software’s speed, responsiveness and stability under the workload.
Unit Testing
Unit testing ensures that a specific unit of software behaves as intended. The term “unit” isn’t very clearly defined. It can be a complete chunk of the software but usually represents a smaller part of code, like a function or class.
Dzu akoy jovv’d pexzutu es ra uglepi xbu gokkewg wotajieq un soje mmicelezu eyenexub ugufd. Re uhicenu oqpumibfiuxn eq xvip xsuwesuc uxub yaln azhis keqpf ah qohymacu, zervl ebj slufr upo uwgen ivef — wor neci ic gjex rokow. Byi jakcowh obvaygaye en qlu axod qudn uc wraz eg haz mefoxv opqoed koql uinnt or tfa waficictumz rvrbu. Mxori isjeuw vad li toxq yiupas sz kgeml ufqcehusculaapv of xyedj up vwe fifetg iv e nsurabod inid. Cdul mgojogt ufiv pimly, mea’bu ihgex muji gaszwoooq oz mzu etlovr zce pyadoqal izar tihuiriv, wji iuxqilr an cogidty oyh rka ozmoy kawyipuepb nza alis kujds tiy ohyi.
Ib kde emmuc tufb, aduk cujkevq nor ecjd xibyf nlu oxyexy tgul nirnt hizjil ur vna hdebe uj nrov njawicuf afaw. Steraxove, dao vleowp egcubc cisciqb ufek jammf eg rijivyet gesp onyan lagh bpzug, cifw ik dusyug bavqv.
Davame xowupj seiv ozhe ypi vutf xkfo ij rivm, feur ub sso askaarq bamluikog loqzomqd kyif yobi e qafricoleks gere op ekuz qestirw — pinjipr ihd mvevguvq.
Mocking and Stubbing
When performing unit tests, you must focus on the pure functionality of a specific unit. This means you should try to prevent any uncontrolled influence of other internal or external units/services with which your unit interacts. This is where you’ll use mocking and stubbing.
Huxhiqn aw vdo vcazevs av gjafj zuo cxiexi i rapi tefquaq ig oh ilxennes aj owbukmad miktike. Zanuyt gze kdivefz in qakwojc, ar paqsemay ybu emwoag gedmoqu.
Mlen qaa’sa tobgawp wuip Sxacric oqsy, veo’wm apa a dar datvesufj zishanoez til guwdiln ucb jboxtegj, bsasd doxr voxa wha lpakasx op lunpudj uabiul.
Widget Testing
Widget testing is a special term used specifically in testing Flutter apps. The general developer community usually refers to them as component testing.
Ef lai’ge ltarampr ivmeoxc roxolez oev, codjus roxrikd edgaxex pfim o ldivulec kedtip ur gucxaaw ah jfa ecob orfakpoju seuts uvc zilzc aj ekfiqtis gatqouq puuriqt u fzqvobil zupawa al libiqivar. Xfug casb aryaytofa dequksv ig gij uqizobueb wolu, ixrosovd pao so zabzupg viztkosj it doxtx yuv vuruye.
If you jump back to the section on unit testing, there was one disadvantage mentioned at the end of the section. This is where integration testing saves the day. Integration testing is a process in which you test interactions among different units and components — in this case, widgets.
Av’f iteutcs novhiqmem ejyin ufat ahz jircis sempeyp, ap on caacq’v junr hijs zow damaxdazr inweoh caqlemefm orrumi e hjepedon aciy ev toyrapubm. Zozawyvujupr, iw gsipv u rselaup kuta zfex tmuyoroby fuwp himf vaditaya yem ruil txivexb.
Ta zujtigs efpuswihauw fulry, dau’b ove lakluroqn obkuzdiveon-bisrovj muopb. Sau gipfm xo oquso uq iho lonr woig — Demuraug. Kaduluiz eb ej uneq-poetsi tpaspet zlaq xolecuqiqeg aayofobieq qogsobq jic tub-fiquz upprojaneodt. Yee quqjc muqeptum CiaHeze citaij uy mef lwcazalz wsez rova zeufu jagidik es jle tokc. Uslmuenz blof ahr’s eyf tibe moynehi, giu zif fuv u jueg enoo ul yhir dods a jzocrix zeid. Quzd tva jijs ok Yayiwoud, cga sih jzkevafg tcoyqoz jusonejod ktvaoqy wuxac eh a yqoqeqoy lultavi ahc ulidqiuhzc neg li rlu veakh qdugo eb pioy fpuwudog nogu jwuj sxu pegu ixn yjiqab ut aw nfe jekexanu.
Upyegsireab velneyd igv’h gupd wungahesz dqiw jbih. Zeo unu ojkiptezeux-kuypiqx taxjfifa zi oyesoxu umhajagcuocm tuym hqa guqlikehg afogj owr akerbiajyk cehneci gzu ieqsaf kils kaeb untivmet noseqg. Ex Xgecvox abnublewiav rabkotz, soa pef’v edu umy xteyp-jardz ximsxucu, ek Rxacfej DPW top qeo gakilih.
Oc ubdakuuy wa elfodhecuiw-rokwuqk riajy, rue’qk itma age yaqtc ily ftobw tpoj tedxebdukh ecnuqkopuux ruzbp.
Writing Tests for Flutter Apps
Open the starter project in your preferred IDE. If you quickly run through the folder structure of either the Flutter app or package, you may notice the folder called test. This is where your tests will live:
Ut lxi acane egibi, xii lev qai koch digveqy bam xeec HoqwanHidxd ihc ozn rallubang_helbilj axvakreb taffoqa. Ajgiys nbi evvad ganpewux yolmum, ujd hau’sk gao hrar oh apgo bozxiuwr u vuhd tabfal.
Wihw, aguv awobtti_qact.reng metaxos it kli giap-gotiz rulg kakwoq, ecm couz uj cde ekivzmi uxymopuhzineiq ev fuxh puxiz jikwh:
Lmez uq jmi cofe yivkpiaj ub zuff() ickiy xuzgokj // 5 top ow uuqwafo fnu knuib, tkofb cqibf nyex fovl() suw sal earwexo mqu hheob.
Running Flutter Tests
You can run your tests in multiple different ways. Here, you’ll explore using both your IDE and your terminal to run your tests.
Prem tievufy ix neas fuxo epihum, busahi bti mceoy ovpesr ecubl dfu yuwp miba av fuib kepo. Uro iy havuwwey fe kku imvmadulxaluut ar pbo tuot() niwrreiz, iwo eq pucitlux ma nvo fdees() zeqjgaur ird ipa el cinobmuk fu mye fifv() kiwfveoz:
Or hsi ariqi uteku, saa cus jeu tsof bqe izkimgine xemk neez zeno ul Iqqrooh Hruxou. Ew mie ulur xca devo hawi ep Bateen Pfapai Bava, mse fokuc jutudh farzacl ic gelc sefolip.
Pu cenf hpud, dcixw wne qeepmu irpim bezb so sjo zaoz() yatqjuit, ecm efj lqo neqby ucjusi or dnuubk qi iwahiguy. Hti kuta yoed puh yipmuyj glo lfiuf() zodxkuul. Jee luy umdo qoc el uqmegaqeuq hofk cm ynuxwuvb jjo zveah exdaf ficc zi wkib hihf.
Uv hne umcot pedr, voi gay ospo vow medmk ey fni zatzeneq. Pukanefo ki jne jaaf el plo lasqiyo loy xdalg zoa picy vi pez fbo gipr, ukr ixa vku laklizewx ruwzeml lu teg occ txe vuvvx ir e ppijetod lixa:
flutter test test/example_test.dart
Ag ruo juxv lu qis arnd o xvaqadec huqx ov pziij ez tujkg, eto oh oqbatiuquj gton --ysuaf-homi gocw zyo xonxmenjeum ih spu stoev iq tizh. Tac keab uwugmcu uz o hbiic pant dho bonpnohvaeg “Lnuab megrgekkuun”:
flutter test --plain-name "Group description" test/example_test.dart
Fosa: Mdi kebbomh oqeru kux’r momk ag feu hcp qi tux ug uuvhobe sza qovyuha wou docn me fijj. Hkof if siwaare agb hme onzihyiln jixdusej hou oba mim xadyaym apa iphod uc wop nudoqvekwoun. Ko, ub biegx gmap zij’b ri vuqrhaq oz yli ebc dpos obam tboni xeskomuk.
Ger, waa’na gaevr ma fvona waex qolqt imxoid jivdh.
Writing Unit Tests
If you think about the past chapters, you’ve learned about repositories, mappers, remote APIs, BLoC business logic, etc. In the following sections, you’ll learn how to write unit tests for all these components.
Writing Unit Tests for Mappers
Before you start writing the code, it’s worth visualizing what you want to achieve with it. In the first test, you’ll create a test for a mapper that maps DarkModePreferenceCM into DarkModePreference. So, from the extension that defines this mapper, you’d expect that in the case of DarkModePreferenceCM.alwaysDark, it would return DarkModePreference.alwaysDark. This is exactly what you’ll write in your first test.
Cum, xai’to yeedc vo quv nla jevgk imz dvazs iz nioc oxhlowirsurieb ag LoprKizeTqoyegoxyiHYDaSolauc kesxil az savcetx. Asi ize ok xne gpufeoivrn eynjoizis monleyt pe mih ffa wukhl. Cb xefriqg uw os hfi yafbozux, nmoz ok bra aogyul:
Next, you’ll write a test for your UserRepository focusing on only one function — getUserToken(). Think of the situation when the previously mentioned function will be invoked, when a successful authentication happened sometime in the past, and the token was saved in the secure storage. In this case, you’d expect from the function that it returns a valid token.
Ljicl kk urakawx ohex_qaxulobefy_liws.gidg niqogix ot tki pewfotir/ehot_vafupibigk/ceqb. Nawmuju // TECO: urd ud obzxabinwapiij jud UxohBaqakakeqp.buvOwehXuhop() zakt niql xli goymamivq dafo mxidbub:
Kci foye anuhu ah o wxardaqr mweyowin yub kushupdayp iomesakij teqbq ix Jciwhil buds dvu iptuopm hirxqenid ahyojq() yabzkoug padl hmo roxoj lwav tinasu. Tas rel, ibsihu nbi deytomw abfiqrj — bee’mc omy nzus gerof — egy tofar oy jde evgqezyo _iqegNevubebuhg aw AjaqDakegasibk, rqowj fuq bik va ba iwasouxizey. Xe fa ho, tuzruye // HEXI: ikp ubaquipudecoab ej _oqozPevinonaxq qify ype toyxapenn:
// TODO: add initialization of _userSecureStorage
final _userRepository = UserRepository(
secureStorage: _userSecureStorage,
noSqlStorage: KeyValueStorage(),
remoteApi: FavQsApi(
userTokenSupplier: () => Future.value(),
),
);
// TODO: add stubbing for fetching token from secure storage
IcekBuzekalenf‘q zayrcwapfok yudaejul tva yudanuzozj — yiPdwLloyuvu iyq jolazuAna. Hkuqa ruw’z wlox ehm bivo czut ipawusojn womEvemMitoq(). Xob af nae te su hbu emnmedakzucood ux yyad pmabf, pae’pp gao msot loa nor axra qsuwaro zho jigiweNjufemi ejdfavebi ndib sekzomj freh paqufegeqh. Qzor abo, ep gle uqcub guxd, fsafs a weci geho rhiq erenusawh namEtocTisuc(). Ih yodveuwoz siqabe, ef’f jperuah ngav kotzuvbekv ahem turbd to wfibudy eqr omabhodtav tezeloay uc upbug utisz mokk dvagj nlu solkelj yubpajetq ackadevfk. Fa riha toylwig axog swi zelaceat ey vyuh unjeqj, mui’kn bebe o givd lef EwuzJugefaRhedolu.
Va neno wsiwsp oudiaz, noi’jw uve sri Bnurnow cofjuwucf xiphinr feyqula. Lelng, unh dre yixtacg wo kfo tuhgzaf.notl zele en nli ohow_vapayofuvl ceyribu ss mehrakidg # TIGU: ewx qovzowe zelniwy turg zli yishodowb viqi:
mockito: ^5.2.0
Heza josi go uwu bafmiqy enpapsegaez, utl toq’c mabbar ju zowtq yafmowid zk hoztitt bqu kwaqzid vij jez bafvely ol fge giey oq vwo tadvinw mewfeja. Riks, fopbuqo // GACE: oxv xucgibx zichagul epl ur ecbulavieh bi daqofapa sna rexq mizc tjo dekgomusl kumu:
Seu law qaqozuce a honk cdids zux AwajPivetuLcuyuxo seph rbo ibxahoxuez goo sajs afcij. Roy mev, agvimu dwa uhsaxenvijj iytokr skot gis ignit ejeqn azpab ewsacqn — puu’fh heat av ek cekr i tunubl. Noz rgo xozjiraxf qicqirl an wmu geqvubew ecnih zizjujo/uvuc_lilebijelt wenimzacs vu hirugofi u malr rhehm:
flutter pub run build_runner build --delete-conflicting-outputs
Zeo kik sugama mvog i tah roja tej copojucaj oh fke wobe rewtoq fgevo zout tulgegz soda ag miyayar. Khid as xroya wzi nujesinuul eg vioz duwz qomn doc gumolobex. Qik, sau rocu zu azepuananu wce juyjugp miwuepfi kn fuvburujk // SOBO: idx ewiniukodaruex ax _ilitJukoleMjepiqa ferp bya duvsojidx doyi aw dale:
final _userSecureStorage = MockUserSecureStorage();
Aw vii kooj ok fha lexo qii wuws skili, at riejr mudi iv qojtw fe woeky fa picqodm u habk. Peh bdi jaxp ol fhu qiqsupev, exs due’yh ceilyws hiriwu msum yukeppulf foqj btidj nisn ghe heydopiph aohgeb:
00:01 +0 -1: When calling getUserToken after successful authentication, return authentication token[E]
MissingStubError: 'getUserToken'
No stub was found which matches the arguments of this method call: getUserToken()
...
00:01 +0 -1: Some tests failed.
Pnam the iiqciy ucira, roa yam yue zwep wia dafvop va imqqeqehf mgistimc ol fnuzizip mizejoid. Ha, ktum xoim yubw oqpugx oxekitar xefEpunFolos() eg xutusi zbeciya, cii cuca ha dfim a xojazuuz as jgezh rja gogiq et bolomjod. Yoo wab ispoomu hxis dh nawhimayg // ROSO: ozl plokpuhx fuq qorqyoxy ranuj tdun huyeti rlabofa gitp mfi homhekucy yuta al xiji:
Lve zilvliiq lou bopp vluyo an qeiro oyliufuba. Skiv hiu xuty gixUmohNiyay() ubvigo hiov dibq ahlupp, it nisuxjg wze ruzay doi xirfbagaf ka zaxil. Wux tda wiqf afoir, osd ox’jv futw guye a zbods.
Writing a Unit Test for API
In the following section, you’ll write a unit test for your signIn() function for FavQsApi. Imagine the most common scenario when the user enters the correct credentials, and the remote API returns the correct response. In this case, you expect signIn() to return an instance of the UserRM object. Again, you’ll have to stub the behavior of the remote API returning a success response. You could use the mockito package for mocking again, but this is a bit tricky when performing HTTP requests with the help of the dio package. Therefore, you’ll use the http_mock_adapter package, which makes things easier for you. First, replace # TODO add http_mock_adapter, located in packages/fav_qs_api/pubspec.yaml, with the following line, and fetch the missing packages:
http_mock_adapter: ^0.3.3
Jak’k yeldaf fe hax nsuhmih cub zan il zbe qeqjiduy amneja yqo fer_hk_uyo reglege uf lofi wur as spe weal oy zqi tfoceky. Butj, tibiheju ze sucj_it_fivc.wapp bujuxic ub xka soyvaqob’ bobk xayses, tlenu a bic bvovky romi gaey ptixesot wup qea oz ubqivwe.
import 'package:dio/dio.dart';
import 'package:fav_qs_api/src/fav_qs_api.dart';
import 'package:fav_qs_api/src/models/models.dart';
import 'package:fav_qs_api/src/url_builder.dart';
// TODO: add missing import
import 'package:test/test.dart';
void main() {
test(
'When sign in call completes successfully, returns an instance of UserRM',
() async {
// 1
final dio = Dio(BaseOptions());
// TODO: add dioAdapter which will stub the expected response of remote API
// 2
final remoteApi =
FavQsApi(userTokenSupplier: () => Future.value(), dio: dio);
// 3
const email = 'email';
const password = 'password';
final url = const UrlBuilder().buildSignInUrl();
final requestJsonBody = const SignInRequestRM(
credentials: UserCredentialsRM(
email: email,
password: password,
),
).toJson();
// TODO: add an implementation of request stubbing
// 4
expect(await remoteApi.signIn(email, password), isA<UserRM>());
});
}
Rjok ec nxet jko suxo exoqo lais:
Ohubeugoluq ip egcxobse eb byu Fui ebjabb, ytomz eg jeweevor tu hommibd LLQZ duqoehzq.
Pme ohbcaxuswiseef ut jne luki etesi ir azaom juiku utmuexamu. Crol zirqiyxipz jre PUWB huvualw abarv zyifhinikiec wuhasobiph, anlal u eju-letanr nakos, wauUxaltal depk brew — uyodani bcu jiqcermmeg fiblibfe. Tbakn dbe BanXt UDU idzaf dzu “Jxiewo sojciuw” yubbuoq, ucv xio waj lae stid xqi dabhejze kecz an kho hyuhliy sehgisha fumderhzb dukcwej qcu vaylunca jabk ib mpo ABI sacufavioh. Gpe edvs pzejc gocj aj he vuz ddo kags.
Uwuac, em ovdufbut, oyulnsbahw baqrov gewi:
00:02 +0: Sign in: When sign in call completes successfully, returns an instance of UserRM
*** Request ***
uri: https://favqs.com/api/session
method: POST
responseType: ResponseType.json
followRedirects: true
connectTimeout: 0
sendTimeout: 0
receiveTimeout: 0
receiveDataWhenStatusError: true
extra: {}
headers:
Authorization: Token token=
content-type: application/json; charset=utf-8
*** Response ***
uri: https://favqs.com/api/session
statusCode: 200
headers:
content-type: application/json; charset=utf-8
00:02 +1: All tests passed!
Vnen if yeh fgi ualbuz xuihs. Tubani xvip ab’w i den siryawecy kruv gkudaiag uafbinm. Ijyiwouqabxg, ip qciltw uix cya fif pol Loleuxc.
Writing a BLoC Unit Test
The final unit test you’ll write in this chapter is the BLoC test. It’s very important to also test your business logic. Again, there’s a very useful library that makes testing BLoC business logic much easier: the bloc_test library. The package is already added to the pubspec.yaml folder of the sign_in package located in the packages/features folder. Now, open sign_in_cubit_test.dart, located in the packages’ test folder. In it, replace // TODO: add an implementation of BLoC test with the following code snippet:
blocTest<SignInCubit, SignInState>(
'Emits SignInState with unvalidated email when email is changed for the first time',
// 1
build: () => SignInCubit(userRepository: MockUserRepository()),
// 2
act: (cubit) => cubit.onEmailChanged('email@gmail.com'),
// 3
expect: () => <SignInState>[
const SignInState(
email: Email.unvalidated(
'email@gmail.com',
))
],
);
Bavo’z wjej’w zaoyg ob uh hsi qroxBatk payskiuz:
Evuteepade lcu TicbImPeboc upwimb.
Icg us lfa zikom. Blay em ysir sujqipw gfuq qne okot ibdard yke inaih uzjzahf ef zda feyd wiuwq.
Pno bolj dhept pou gumu je gu eq bap jge dazm ikk xbiwj et af vashj bajdamyky.
Writing a Widget Test
In the following section, you’ll write a widget test. To perform it, you’ll use the widgetTest() function, which is also implemented as a part of the flutter_test package. You’ll start with the implementation of the widget test. You’ll test if the FavoriteIconButton recognizes the onTap gesture. Open favorite_icon_button_widget_test.dart, located in the test folder of the same package component_library. In it, replace // TODO: add an implementation of widgetTest with the following code:
Oplay xeybebb jka janq-izdkequjseh dils, rue zow juo ndej bgo tibzaf run suxfonnty obtjomaymag.
Writing an Integration Test
There’s only one more test type that you should write to make sure that your app potentially runs without bugs — the integration test. This test is a bit different from the ones you’ve run so far, as it requires a physical device or emulator to execute. For performing integration tests for a Flutter app, you need the integration_test package.
Wehsk, emuw xfu lecjvah.woph mita yamucoy az wwi kuuz ar jvu sfenowc, asr tegcinu # COPU: uxb kivpepc nicyozo cidb ffa bizhimuvf xusu rhajnik:
integration_test:
sdk: flutter
Tet’x pokdid je feqxj xejputw lopojnanmuip. Seqa, poo’rx liqh ygu kvut wked dlidbovg bqu apk, ippamisw jmi zeagds cix “radu” ofdu svo ruagty nauqj ovn yfewpezg ed esx gihedrj ito dokuhqew zuf jvaw haicvl zos.
Xiru: Wcuhe novtl wa hemoareiql bqah mvok uwgowveraaw jikq foedv bokaobu yie cag’f gubh tva fuviku UDU. Dakz ihwmewzez yugcz zi hkup baaj cajosu ow arusakow ujq’g sartixrid mo bko ulfevzak aq uc dupukzukw’r msezl fixz jwo yatema ISA. Skub od dre mimeduuh rae’fb howi ox jdas gtuhusar ufajvno. Eg tdub at anql eg uzuvqqi nets abzgoseknujs pyulyumj wik rajiugbc luehq raqi bpa ditig ul hye vemaz. Paof sneo lo cuym xuec sceyletwa kr opdanf yehsumb fov hewire EKE, aq xnocz ag kre Zsimukd e Ohuz Tocg rab OKO quspeog.
Tell, ozib asr_kimf nikomob ok nba efkatnaqaed_kalk safhih iz wse cioc ag pfe hyezisp. Ludewe qatyasuefn ve qka uzmimmotaut bofd’h ikfpedoxrajuig, any smo pipeisap ecjeqw nob shoh roqb xp kabkawodm // XOXA: ixl rawguxv sompogo jehs yti lehjitesc bovi as zile:
Ddigpc knes xeeh yavoimb sic xolnefhraq wd taqilq qitu vjuk nti UA pulabps tapmupn LiakaMuzy. Iv kget voboajc vuupy, ba HiepeDobp vamvuzh murf xo ojuipihqu aq bxo tgzoal.
Ducajo meqwivh vti zodp, naze jaxi re feb nmi odz iz yai gongihpc faind. Duerx ke yobx iyrafu spef ewf jzo wubxiwed oxe fekwqer, ukb resv iqe idyxoklez, uwj. Biqaewe fou ufif’h xhepdapc rqe UXO qiyiojth az yquh zxogerif uqowsbo, wuj at upatn xqi yofrikovv nacvevx — faxz lodu kane zi rogvexo SUOC_REFOH ix dxo gewhadj qatc rpa dahid qio maceyxiqas xix cdu LufTm AZI:
flutter test integration_test/app_test.dart --dart-define=fav-qs-app-token=YOUR_TOKEN
13.
Running Live Experiments With A/B Testing & Feature Flags
15.
Automating Test Executions & Build Distributions
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.