Jump to content
php.lv forumi

Recommended Posts

Varu padalīties nelielā pieredzē.

Vide - phpstorm, git, laravel, pie projekta strādāju viens.
Projekts: http://pointsback.lv
Projekta neliels aprakts: ir divi useru tipi - pircēji, pārdevēji. Pircējs iepērkas pie pārdevējiem, saņem par to punktus no pārdevēja konta savā. Pircējs var arī tērēt savus punktus. Pamatā vienkāršas punktu transakcijas, viss notiek caur API.

Testos esmu galīgs iesācējs, unittestus vēl īsti nemāku rakstīt (kods pārāk līks, lai normāli testētu), bet mēģinu vismaz integrācijas testus rakstīt. Ja kāds nezina, tad integrācijas tests ir, kad testē jau kaut kādas sistēmas daļas kopumā, vai tās funkcionē pareizi, vai tās strādā korekti. Unittesta gadījumā tiek testēta kaut kāda maza vienība, pilnībā izolējot to no ārējiem apstākļiem (datubāzes, modeļiem, api, utt utt).

Es parasti uzrakstu kaut kādu funckionalitāti un uzreiz mēģinu uzrakstīt arī pāris testus.

Testa gaita ir apmēram šāda - palaižot testu, man katru reizi tiek uzbūvēta jauna datubāze, visas tabulas, tiek ievietoti kaut kādi pamata dati (useru grupas, permisiju tipi, whatever). Tad es uzkodēju kaut kādus scenārijus.

Piemēram,
1. Ieskaitam veikala kontā 100 punktus
2. Piereģistrējam lietotāju
3. Pārskaitam no veikala konta 60 punktus
4. Pārbaudam vai lietotājam kontā ir 60 punkti
5. Pārbaudam vai veikalam kontā atlikuši 40 punkti

Tādā garā ir arī visi testi.

Testi mani izglābuši vairākkārt. Viens spilgs gadījums atmiņā - vajag ieviest nosacījumu, ka pārskaitot no veikala pircējam punktus, tiek ieturēta komisija. Ok, domu gaita sekojoša - papildus kolonna veikalu tabulai ar komisijas %. Attiecīgi, rodas nosacījums, ka tagad veikala konta atlikums ir jāglabā kā decimāla daļa, jo, 50% no 1 punkta ir 0.5 punkti, attiecīgi, pārskaitot no veikala pircējam punktus, veikalam paliek par 1.5 punktiem mazzāk. Turpmākās darbības galvā vienkāršas - pieliekam komisijas kolonnu, pielabojam funkciju kas pārskaita punktus (pieskaita/atņem no veikala konta), lai tiktu atrēķināta komisija. Viss it kā vienkārši, kļūdām nevajadzētu būt - laižu testus, un - kļūda! Nesakrīt summas.

Rokos dziļāk, un atrodu vienā metodē, ka palicis - $shop->points = (int)$points;
Ahā, notiek decimāldaļas atmešana! Pielabojam uz (float), viss rullē!

Šādu kļūdu, es visdrīzāk nebūtu atradis ar roku, ja vien neuztrāpītu uz konkrētā robežgadījuma. Paietu labs laiks, kamēr saprastu, kas noticis un, kur nu vēl savest visu kārtībā - izsekot, kuram veikalam cik tagad ir pazudis, cik jāpieskaita klāt. Karoč, produkcijā viss slikti.

Līdzīgi testēju arī API izsaukumus - veicu izsaukumus kontrolierim, padodu derīgus/nederīgus datus, pārbaudu rezultātu, utt utt. API tomēr ir tāda lieta, kas nedrīkst vispār mainīties (vismaz tā pēkšņi), ja to jau produkcijā lieto N cilvēki. Viena kļūda var maksāt dārgi, kaut vai programmētāja laika resursā.

Piemēram, vajag API notestēt, vai strādā autorizācija:
A7SIxi5.png

Šeit apskatāms viss test case priekš API: http://pastebin.com/b6X77uaZ

Šādi ~ izskatās punktu došanas tests:
JesMh01.png


Mans secinājums pēc šī projekta noteikti ir tāds, ka vismaz kaut kādus testus vajag rakstīt. Nevar salīdzināt, kā ir refactorēt ar testiem, un bez testiem. Tas ir tā, kā pieregulēt lidmašīnai aerodinamiku, un mēģināt lidot (produkcijā), nemaz nepamēģinot kā viņa uzvedas gaisa tunelī.

Tiem, kas vēl neraksta testus - noteikti pamēģiniet. Vismaz uzsākot kādu jaunu projektu, jo no 0 vienmēr ir vieglāk + ar katru nākamo projektu, spējas noteikti uzlabosies. Vēlams izmantot kādu frameworku, piemēram, laravel, kas daudzkārtīgi atvieglo visu šo procesu.

Testēšana ir ļoti overwhelming, kad paklausās, ko runā - unittesti, intergrācijas testi, end to end testing, model testing, functional testing, mocking, un vēl bonusā, viena komūna uzskata integrācijas testus par unittestiem, cita otrādāk. Nemaz nesākšu runāt par interfeisa testiem, selenium... To visu paklausoties rokas nolaižas, bez šaubām. Bet, kamēr nespersi pirmo soli, neuzrakstīsi savu pirmo, nepareizo testu, nekādu izgausmi negūsi... Tā kā novēlu - nevajag baidīties, vajag tikai pamēģināt.

 

Oj, eseja sanāca :D
 

Link to comment
Share on other sites

  • Replies 228
  • Created
  • Last Reply

Top Posters In This Topic

Labs, briedis! Tikai nevajag tik garus testus un iesaku padomāt, vai tiešām gribi glabāt punktus kā float.

 

> Tiem, kam ir pieredze ar testēšanu - kad jūs tos testus rakstāt? Tiešām piekopjat "testi vispirms, kods pēc tam"? Jo varbūt, ka man ir līkas rokas un es nespēju pats sevi paredzēt, bet bieži vien mēnesi pēc projekta sākšanas tā struktūra ir tik atšķirīga no sākotnēji iecerētās, ka pirms tam rakstītie testi vnk ir bezjēdzīgi.

 

Nevajag to visu tik ļoti nodalīt — koda rakstīšanu un testu rakstīšanu. Uzraksti testu, kas pierāda, ka simple case vienkārši strādā. Tad uzraksti jaunu testu, kas pieliek jaunu, (nedaudz) sarežģītāku testu. Tas nofeilos. Pamaini implementāciju tā, ka abi testi ir zaļi. Bieži vien būs jāparaksta visa metode, un nebūs jāuztraucas, ka kkas tiek salauzts — iepriekšējie testi tev pierāda, ka rezultāts ir tāds pats. Rinse and repeat.

 

Zinu, ka jūs heitojat citas valodas, bet kad rakstīju savu Lisp dialektu, testi bija tieši tādi, kā es tikko stāstīju.

 

https://github.com/daGrevis/diy-lisp/tree/master/tests

 

Tie ir totāli unit-testi.

 

Šeit, piemēram, ir integrācijas testi manam blogam.

 

https://github.com/daGrevis/daGrevis.lv/blob/master/dagrevis_lv/blog/tests.py

 

Oh, un vēl viena doma, kas papildina šo:

 

> Nevajag to visu tik ļoti nodalīt — koda rakstīšanu un testu rakstīšanu.

 

Testi tiek mainīti non-stop, ar kodu rakstīšanu tu raksti jaunus un maini vacos, jo tie lūzīs un that's the point.

Link to comment
Share on other sites

Float glabājas decimal kolonnā. Protams, varētu glabāt veselu skaitli, un dalīt php pusē, bet baigo ieguvumu es neredzu (naudu es tāpat glabāju veselos centos, bet ja vajag glabāt arī pus centu?)

Testi ir pagari, jo viens tāds tests ietver veselu scenāriji no sākuma līdz galam. Pieļauju, ka, ja rakstītu true unittestus, tad tie būtu tiešām stipri īsāki. Līdz tam vēl ceru nonākt.

Kad rakstu testus? Kad rakstu kaut kādu libu, parasti uzrakstu vispirms basic funkcionalitāti, un, kad jau teorētiski varētu sākt būvēt UI, testēt caur to, sāku rakstīt testu scenārijus. Jo uzrakstīt vienu testu ar konkrētu scenāriju, un pēc tam labot loģiku ir daudz patīkamāk, nekā to pašu scenāriju realizēt spaidot UI, kas ir vienkārši garlaicīgs un repetatīvs uzdevums.

Šeit vēl viens tests sociālo tīklu pasēm: http://pastebin.com/SSNe318Z

Tiek pārbaudīti dažādi scenāriji, brīdī, kad lietotājs ir/nav ielogojies ar savu pamatkontu, tad mēgīna pieslēgties ar soc kontu:

Sākumā uzrakstīju scenārijus uz lapiņas, un mēģināju arī uzrakstīt testus.

1. Ja useris ielogojies
   1.1. Soc konts nav iepriekš reģistrēts - piesaistam userim soc kontu
   1.2. Soc konts ir reģistrēts sistēmā - kļūda
2. Nav ielogojies
   2.1. Soc konts nav iepriekš reģistrēts - izveidojam jaunu useri, savienojam, ielogojam
   2.2. Soc konts ir reģistrēts - ielogojam lietotāju
   
Šos visus, principā pat vienkāršos, scenārijus mēģināt ar roku, vairākkārt, un katru reiz kā tiek veikts kāds labojums? Ehhh

Link to comment
Share on other sites

Jāpiekrīt būs daGrevim. Tā pat kā vēlams būtu rakstīt mazus objektus/metodes, tam arī testu būs krietni īsāki.

Tava testa gadījumā es personīgi noteikti dažas lietas ekstraktētu ārā no paša testa konkrēti. Piemēram, paša veikala izveidi. Tas noteikti noderētu arī citur, tamdēļ izveidot A) Privātu metodi B) Helpers klasi, kas attiecīgi izveido pašu veikalu. Testam, kas pārbauda vai iedod punktus, nevajadzētu iekļaut arī pilnas darbības ar veikala izveidi.

 

Nenoliedzami tie termini čakarē prātu, un liek domāt, ka nefiga nekas no tā visa nav vajadzīgs, bet sākot ar vienkāršiem unit testiem savā lapā, ar laiku iemācīsies rakstīt mazus/vienkāršus testus, kas beigās iemācīs Tev rakstīt mazas un vienkāršas funkcijas/metodes un iemācīs rakstīt krietni lasāmāku kodu.

 

Lielākā problēma šajā visā manuprāt ir tas, ka ir jāiemācās šo testu rakstīšana, kas aizņem tomēr zināmu laiku, nevis kā parasti cilvēki mēdz darīt, ja kaut kas nestrādā, tad nogooglē un viss.

Link to comment
Share on other sites

sanāk, ka es pieturos pie unittest, nosacīti uzrakstītai inkapsulētai entītijai/objektam saraksta notepad/balta lapa iespējamos scenārijus. Protams, ka tie objekti, entītijas jāliek kopā relācijās un jāraksta jauni scenāriji ... Jautājums - testēšana tiek iekļauta izmaksu tāmē vai to pierēķina pie tīra development? :)

 

Komandas projektos, ja nav atsevišķa testētāja, tur tad sanāk vislielākie strīdi, es uzskatu, ja tu repozitorijā esi ielicis jau kodu, tad tas pēc noklusējuma ir "done" - notestēts un nelauz galvu vairāk par to ... laiks, laiks un izmaksas!

Edited by vbz
Link to comment
Share on other sites

Es reti kad rakstu unit testus, jo reti būvēju atsevišķas bibliotēkās. Praktiski tikai produktus un līdz ar to testēju viņus ar integrācijas un funkcionālajiem testiem. Tos pašus modeļus netestēju ar mock objektiem, bet ar reālu testa db. Es personīgi uzskatu, ka svarīgākais ir tas, lai gala funkcionalitāte lietotājam strādātu, tāpēc lielākā daļa testu ir funkcionālie testi, kuri tad arī parasti nofeilo, ja feilo kāda atsevišķa komponente.

Vēl šeit nav pieminēta tāda lieta kā performances testi:

- testēt konkrētas aplikācijas ceļus uz paralēliem pieprasījumiem,

- testēt konkrētu pieprasījumu atbildes laikus,

- testēt, lai konkrētos pieprasījumos kveriju skaits nepārsniegtu N,

- testēt datubāzi uz lielu datu skaitu.

utml.

Lielākā daļa no šiem testiem var tikt veidoti vienreiz un automātiski palaisti uz visām atbilstošajām līdzīgajām aplikācijas daļām.

 

Vēl viena lieta ir lietojamības testēšana. Tā tiek veikta jau ejošam produktam, vācot datus par to, kādus ceļus lietotājs izvēlas, lai navigētu pa aplikāciju. Tādā veidā atklājot lietojamības bugus, ja lietotājs nesasniedz kādu noteiktu funkcionalitāti, kura pati par sevi strādā, bet ir vai nu neintuitīva, vai nesasniedzama.

Edited by codez
Link to comment
Share on other sites

...Es personīgi uzskatu, ka svarīgākais ir tas, lai gala funkcionalitāte lietotājam strādātu, tāpēc lielākā daļa testu ir funkcionālie testi, kuri tad arī parasti nofeilo, ja feilo kāda atsevišķa komponente. ...

Agile filozofija, nav vērts pieslīpēt atsevišķu moduli, bibliotēku, lai tas būtu ideāls, pie nosacījuma, ka tas jau ir produkcijā. Vēl vairāk, nav vērts atgriezties pagātnē un rakstīt sev notes - šito pieslīpēšu, utt. Tu jau par to esi saņēmis naudu. Kā programmētājs es tam nepiekrītu, kā komersants piekrītu. Kā programmētājs mācos visu laiku pārstartēt savas smadzenes uz agile - pašās beigās tāpat nonāk līdz funkcionālajam testam pie klienta :)

Link to comment
Share on other sites

> Nuu unit-testus arī var rakstīt unit-testu unit-testiem, kas testē skatus. Jautājums ir, vai no tā ir kāda jēga un LEAN.

 

Atkarībā no tā, kā projekts ir strukturizēts, un kas, kāda veida kods un cik daudz, ir kontrolerī, bet es domāju, ka _unit_-testi kontrolerim arī ir diezgan svarīgi. Protams, testi testiem ir absurds.

Link to comment
Share on other sites

Mani ar Agile iepazīstināja cilvēks, kas darbojas ar TDD un pair-programming, tāpēc man kaut kā automātiski tas saistās kopā, bet vispār agile pēc idejas jau neko tev tā strikti nenorāda - dari tā vai šitā. Tā ir tikai filozofija, ko dzīvē katrs var uztvert citādāk.

Link to comment
Share on other sites

>Testi tiek mainīti non-stop, ar kodu rakstīšanu tu raksti jaunus un maini vacos, jo tie lūzīs un that's the point.

Tieši tā, tāpēc agile nosaka iterācijas ciklu - vai uz šo konkrēto brīdi kods strādā vai nē, nestrādā - reject, strādā - accept

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...