Toetsing van einde tot einde met Joomla! en Cypress - My eerste stappe en gedagtes

Outomatiese toetse is nie 'n spesiale hulpmiddel vir sagteware-ontwikkelaars in groot projekte nie. Veral vir uitbreidings is outomatiese toetse 'n hulp om probleme vinnig te identifiseer. Dit help om te verseker dat uitbreidings glad werk in nuwer Joomla-weergawes.

Die Joomla Core-ontwikkelaars wil hê derdeparty-sagteware-ontwikkelaars moet hul uitbreidings toets, om foute te vind voordat 'n gebruiker dit kry. Dit verg baie tyd en is vervelige werk. Daarom word dit dikwels nie gedoen nie. Veral nie as dit gedoen moet word nie. handmatig deur mense vir elke nuwe vrystelling. Outomatiese toetsing maak dit moontlik om die handstappe vir elke vrystelling te herhaal sonder dat 'n mens self die stappe uitvoer. Op hierdie manier word foute gevind voordat 'n gebruiker hulle teëkom wanneer hy toegang tot die regstreekse stelsel verkry.

Terloops, enigiemand wat Cypress wil gaan kyk, sal hierdie teks 'n goeie plek vind om te begin. Jy kan probleme toets sonder om alles self te installeer en op te stel. In die Github-bewaarplek van die Joomla-projek is alles gereed om te gaan.

Inleiding

"Alhoewel dit waar is dat kwaliteit nie in getoets kan word nie, is dit ewe duidelik dat sonder toetsing dit onmoontlik is om enigiets van kwaliteit te ontwikkel." - [James A. Whittaker]

Voordat ek die eerste keer op Cypress afgekom het, kon ek nie dink dat die hindernisse wat dikwels in die pad van my toetsing staan, eintlik ietwat opsy geskuif sou word nie.Ek het baie tyd spandeer om sagteware te toets - en vroeër selfs meer tyd om die probleme te hanteer wat ontstaan ​​het weens 'n gebrek aan toetsing! Nou is ek oortuig dat toetse wat:

  • so na as moontlik aan die programmering,
  • outomaties,
  • gereeld - ideaal na elke programverandering,

    bring meer in as wat dit kos En wat meer is: toetsing kan selfs pret wees.

Dit is die moeite werd om toetsmetodes aan te leer! Toetsmetodes is langdurig, want dit kan nie net met enige programmeertaal gebruik word nie, dit kan op byna enige menslike werk toegepas word. Jy moet af en toe amper alles wat belangrik is in die lewe toets. Toetsmetodes is onafhanklik van spesifieke sagteware-instrumente.Anders as programmeringstegnieke of programmeertale, wat dikwels in en uit die mode is, is die kennis van hoe om goeie toetse op te stel tydloos.

Wie moet hierdie teks lees?

Enigiemand wat dink dat sagteware-toetsing 'n mors van tyd is, moet na hierdie artikel kyk. Ek wil veral daardie ontwikkelaars nooi om hierdie te lees wat nog altyd toetse vir hul sagteware wou skryf - maar nog nooit vir 'n verskeidenheid gedoen het nie. Sipres kan 'n manier wees om sulke hindernisse te verwyder.

Een of ander teorie

Die Magiese Driehoek

Die Magic Triangle beskryf die verhouding tussen die koste, die vereiste tyd en die haalbare kwaliteit. Oorspronklik is hierdie verhouding erken en beskryf in projekbestuur. Jy het egter seker al gehoor van hierdie spanning op ander gebiede ook. kwessie in byna alle operasionele prosesse in 'n maatskappy.

Daar word byvoorbeeld algemeen aanvaar dat 'n hoër koste 'n positiewe impak op kwaliteit en/of voltooiingsdatum het - dit wil sê tyd.

 

The Magic Triangle in Project Management - As meer geld in die projek belê word, het dit 'n positiewe impak op kwaliteit of tyd.

Omgekeerd, 'n kostebesparing sal kwaliteit dwing om af te neem en/of voltooiing vertraag te word.

The Magic Triangle in Project Management - As minder geld in die projek belê word, het dit 'n negatiewe impak op kwaliteit of tyd.

Nou kom die towerkrag ter sprake: Ons oorkom die korrelasie tussen tyd, koste en kwaliteit, want op die lang termyn kan dit eintlik oorkom word.

Die verband tussen tyd, koste en kwaliteit kan op die lange duur oorkom word.

Miskien het jy ook in die praktyk ervaar dat 'n vermindering in kwaliteit nie op lang termyn kostebesparings tot gevolg het nie.Die tegniese skuld wat dit skep, lei dikwels selfs tot kostestygings en bykomende tyd.

Op die lang termyn kan die korrelasie tussen koste, tyd en kwaliteit eintlik oorkom word.

Tegniese skuld verwys na die ekstra moeite verbonde aan die maak van veranderinge en verbeterings aan nie-goed geprogrammeerde sagteware in vergelyking met goedgeskrewe sagteware.Martin Fowler onderskei die volgende tipes tegniese skuld: Die wat mens opsetlik aangegaan het en dié wat jy per abuis aangegaan het. Hy onderskei ook tussen verstandige en roekelose tegniese skuld.

Tegniese skuld

Koste en voordele

In die literatuur sal jy verwoestende statistiek vind oor die kanse op sukses van sagtewareprojekte. Min het verander in die negatiewe prentjie wat reeds in die 1990's in 'n studie deur AW Feyhl aangeteken is. Hier, in 'n ontleding van 162 projekte in 50 organisasies , is die koste-afwyking in vergelyking met die oorspronklike beplanning bepaal: 70% van die projekte het 'n koste-afwyking van minstens 50% getoon!Iets is nie korrek nie!Jy kan dit tog nie net aanvaar nie?

Een oplossing sou wees om heeltemal van kosteberamings af te sien en die argumentasie van die #NoEstimates-beweging te volg.Hierdie beweging is van mening dat kosteberamings in 'n sagtewareprojek onsinnig is.'n Sagtewareprojek bevat volgens mening van #NoEstimates altyd die produksie van iets nuuts Die nuwe is nie vergelykbaar met reeds bestaande ervarings nie en dus nie voorspelbaar nie.

Hoe meer ervaring ek kry, hoe meer kom ek tot die gevolgtrekking dat ekstreme sienings nie goed is nie. Die oplossing is amper altyd in die middel. Vermy uiterstes in sagtewareprojekte ook en soek 'n middel. 'n hoef nie 'n 100% te hê nie. seker plan. Maar jy moet ook nie 'n nuwe projek naïef begin nie. Alhoewel sagteware projekbestuur en veral kosteberaming 'n belangrike onderwerp is, sal ek jou nie langer daarmee verveel in hierdie teks nie. Die fokus van hierdie artikel is om te wys hoe E2E toetsing kan geïntegreer word in die praktiese werkvloei van sagteware-ontwikkeling.

Integreer sagtewaretoetsing in jou werkvloei

Jy het besluit om jou sagteware te toets. Wonderlik! Wanneer is die beste tyd om dit te doen? Kom ons kyk na die koste om 'n fout in die verskillende projekfases reg te stel. Hoe vroeër jy 'n fout vind, hoe laer is die koste om dit reg te maak .

Relatiewe koste vir die oplos van probleme in verskeie projekstadia

Toets en ontfouting: Daar is woorde wat dikwels in dieselfde asem genoem word en waarvan die betekenisse dus gelyk is. By nadere ondersoek staan ​​die terme egter vir verskillende interpretasies. Toetsing en ontfouting behoort tot hierdie woorde. Die twee terme het in gemeen dat hulle wanfunksies opspoor, maar daar is ook verskille in die betekenis.

  • Toetse vind onbekende wanfunksies tydens ontwikkeling.Om die wanfunksie op te spoor is en duur, terwyl die lokalisering en uitskakeling van die fout goedkoop is.
  • Ontfouters herstel wanfunksies wat gevind word nadat die produk klaar is. Om die wanfunksie op te spoor is gratis, maar om die fout op te spoor en reg te stel is duur.

Gevolgtrekking: Dit maak die meeste sin om so vroeg as moontlik met die integrasie van toetse te begin. Ongelukkig is dit moeilik om te implementeer in 'n oopbronprojek soos Joomla met meestal vrywillige bydraers.

Deurlopende integrasie (CI)
Deurlopende integrasie van toetse

Stel jou die volgende scenario voor. 'n Nuwe weergawe van 'n gewilde inhoudbestuurstelsel is op die punt om vrygestel te word. Alles wat die ontwikkelaars in die span sedert die laaste vrystelling bygedra het, word nou vir die eerste keer saam gebruik. Die spanning styg! werk? Sal alle toetse suksesvol wees - as die projek hoegenaamd toetse integreer. Of sal die vrystelling van die nuwe weergawe weer uitgestel moet word en senutergende ure se foutregstelling voorlê? Terloops, die uitstel van die vrystellingsdatum is ook nie goed vir die beeld van die sagtewareproduk! Geen ontwikkelaar hou daarvan om hierdie scenario te ervaar nie. Dit is baie beter om te eniger tyd te weet in watter toestand die sagtewareprojek tans is? Kode wat nie by die bestaande inpas nie, moet eers geïntegreer word na hulle is "gemaak om te pas".Veral in tye wanneer dit meer en meer algemeen is dat 'n sekuriteitsgaping reggemaak moet word, moet 'n projek altyd 'n vrystelling kan skep!En dit is waar deurlopende integrasie ter sprake kom.

By deurlopende integrasie word individuele elemente van die sagteware permanent geïntegreer. Die sagteware word in klein siklusse geskep en getoets. Sodoende kom jy probleme tydens integrasie of foutiewe toetse op 'n vroeë stadium teë en nie dae of weke later nie. Met suksesvolle integrasie, Foutsporing is baie makliker omdat foute naby aan die tyd van programmering ontdek word en gewoonlik word net 'n klein deel van die program geraak. Joomla integreer nuwe kode deur deurlopende integrasie te gebruik. Nuwe kode word eers geïntegreer wanneer alle toetse geslaag is.

Met 'n deurlopende integrasie van nuwe sagteware, is die oplos van probleme baie makliker omdat die foute naby aan die tyd van programmering ontdek word en gewoonlik word slegs 'n klein deel van die program geraak.

Om te verseker dat jy te alle tye toetse vir alle programonderdele beskikbaar het tydens deurlopende integrasie, moet jy toetsgedrewe sagteware ontwikkel.

Toetsgedrewe ontwikkeling (TDD)

Toetsgedrewe ontwikkeling is 'n programmeringstegniek wat gebruik maak van ontwikkeling in klein stappe. Eers skryf jy die toetskode. Eers dan skep jy wel die programkode wat getoets moet word. Enige verandering aan die program word eers gemaak nadat die toetskode vir daardie verandering geskep. Jou toetse misluk dus onmiddellik na skepping. Die vereiste funksie is nog nie in die program geïmplementeer nie. Eers dan skep jy die werklike programkode - dit wil sê die programkode wat aan die toets voldoen.

Die TDD-toetse help jou om die program korrek te skryf .

Wanneer jy die eerste keer van hierdie tegniek hoor, is jy dalk nie gemaklik met die konsep nie. ""Mens"" wil tog altyd eers iets produktiefs doen. En toetse skryf lyk nie met die eerste oogopslag produktief nie. Probeer dit uit. Soms jy word vriende met 'n nuwe tegniek eers nadat jy dit leer ken het!In projekte met hoë toetsdekking voel ek gemakliker wanneer ek nuwe kenmerke byvoeg.

As jy deur die oefeninggedeelte aan die einde van die teks gaan, kan jy dit probeer. Skep eers die toets en skryf dan die kode vir Joomla Core. Dien dan alles saam as 'n PR op Github in. As almal dit sou doen , Joomla sou ideale toetsdekking hê.

Gedragsgedrewe ontwikkeling (BDD)

BDD is nie 'n ander programmeringstegniek of toetstegniek nie, maar 'n soort beste praktyk vir sagteware-ontwikkeling. BDD word ideaal saam met TDD gebruik. In beginsel staan ​​Behaviour-Driven-Development vir toetsing nie die implementering van die programkode nie, maar die uitvoering - dws die gedrag van die program 'n Toets kontroleer of die spesifikasie, dit wil sê die kliënt se vereiste, nagekom word.

Wanneer jy sagteware op 'n gedragsgedrewe manier ontwikkel, help toetse jou nie net om die program korrek te skryf nie. Toetse help jou ook om die regte program te skryf .

Wat bedoel ek daarmee: "Skryf die regte program"? Dit gebeur dat gebruikers dinge anders sien as ontwikkelaars. Die werkvloei om 'n artikel in Joomla uit te vee is 'n voorbeeld. Keer en weer ontmoet ek gebruikers wat op die statusikoon in die asblik en word verras. Die gebruiker neem gewoonlik intuïtief aan dat die item nou permanent uitgevee is, maar dit word van asblik geskakel na geaktiveer. Vir die ontwikkelaar is om op die statusikoon te klik 'n verandering van status, 'n skakelaar in alle ander aansigte. Hoekom moet dit anders wees in die asblik? Vir die ontwikkelaar word die funksie sonder foute geïmplementeer. Joomla werk reg. Maar in my oë is die funksie nie die regte een op daardie plek nie, want die meeste gebruikers sal dit heel anders beskryf/versoek .

In gedragsgedrewe ontwikkeling word die vereistes vir die sagteware beskryf deur voorbeelde genaamd scenario's of gebruikersstories Kenmerke van gedragsgedrewe ontwikkeling is

  • 'n sterk betrokkenheid van die eindgebruiker in die ontwikkelingsproses van die sagteware,
  • die dokumentasie van alle projekfases met gebruikersstories/gevallevoorbeelde in teksvorm - gewoonlik in die beskrywingstaal in die beskrywingstaal Augurk,
  • outomatiese toetsing van hierdie gebruikersstories/gevallestudies,
  • opeenvolgende implementering Dus kan 'n beskrywing van die sagteware wat geïmplementeer moet word enige tyd verkry word Met behulp van hierdie beskrywing kan jy voortdurend die korrektheid van die reeds geïmplementeerde programkode verseker.

Die Joomla-projek het BDD in 'n Google Summer of Code-projek bekendgestel . Daar is gehoop dat gebruikers sonder programmeringskennis makliker sou kon deelneem deur gebruik te maak van Augurk ). Die benadering is nie konsekwent opgevolg nie. Destyds het Joomla Codeception as 'n Met Cypress is BDD-ontwikkeling ook moontlik om op die BDD-manier te ontwikkel.

Beplanning

Toets tipes
  • Eenheidstoetse: 'n Eenheidstoets is 'n toets wat die kleinste programeenhede onafhanklik toets.
  • Integrasietoetse: 'n Integrasietoets is 'n toets wat die interaksie van individuele eenhede toets.
  • E2E Toetse of Aanvaardingstoetse: 'n Aanvaardingstoets kontroleer of die program die taak vervul wat aan die begin gedefinieer is.
Strategieë

As jy 'n nuwe funksie in Joomla wil byvoeg en dit met toetse wil beveilig, kan jy op twee maniere voortgaan.

Top-down en bottom-up is twee fundamenteel verskillende benaderings tot die verstaan ​​en aanbieding van komplekse kwessies. Top-down gaan stap vir stap van die abstrakte en algemene na die konkrete en spesifieke. Om dit met 'n voorbeeld te illustreer: 'n Inhoudbestuurstelsel soos Joomla bied gewoonlik webwerwe in 'n blaaier aan. Konkreet is daar egter 'n aantal klein subtake in hierdie proses. Een daarvan is die taak om 'n spesifieke teks in 'n opskrif te vertoon.

Bottom-up beskryf die teenoorgestelde rigting: op hierdie punt is dit die moeite werd om weereens te onthou dat een element van gedragsgedrewe ontwikkeling die skep van 'n tekstuele beskrywing van die sagteware se gedrag is.Hierdie beskrywing van aanvaardingskriteria help om toetse te skep - veral die top -vlak end-tot-end toetse of aanvaardingstoetse.

Die gewone benadering tot die skep van toetse vandag is van onder. As jy gedragsgedrewe sagteware-ontwikkeling verkies, moet jy die teenoorgestelde strategie gebruik. Jy moet die bo-na-onder-strategie gebruik. Met 'n bo-na-onder-strategie word 'n misverstand vroeg geïdentifiseer in die ontwerpfase.

Toetsstrategieë: Top-down-toetsing en Bottom-up-toetsing

  • Top-down-toetsing: Wanneer die top-down-strategie toegepas word, begin 'n mens met die aanvaardingstoetse – dit wil sê met die deel van die stelsel wat die nouste gekoppel is aan die gebruikersvereistes.Vir sagteware wat vir menslike gebruikers geskryf is, is dit gewoonlik die gebruikerskoppelvlak Die fokus is om te toets hoe 'n gebruiker met die stelsel omgaan. 'n Nadeel van top-down toetsing is dat baie tyd bestee moet word aan die skep van toetsduplikate. Komponente wat nog nie geïntegreer is nie, moet vervang word deur plekhouers. is geen werklike programkode aan die begin nie. Daarom moet ontbrekende dele kunsmatig geskep word. Geleidelik word hierdie kunsmatige data dan vervang deur werklik berekende data.

  • Onder-na-bo-toetsing: As jy die onder-na-bo-strategie volg, begin jy met eenheidstoetse. Aan die begin het die ontwikkelaar die teikentoestand in gedagte. Hy breek egter dan eers hierdie teiken in individuele komponente af. Die probleem met die Die bottom-up-benadering is dat dit moeilik is om te toets hoe 'n komponent later in werklike situasies gebruik gaan word.Die voordeel van bottom-up-toetsing is dat ons sagteware-onderdele baie vinnig klaargemaak het. Hierdie dele moet egter met omsigtigheid gebruik word. Hulle werk wel korrek. Dit is wat die eenheidstoetse verseker. Maar of die eindresultaat werklik is wat die kliënt voorstel die sagteware is, is nie verseker nie.

Die toetspiramide deur Mike Cohn

Hoeveel toetse moet geïmplementeer word van watter toetstipe? Die toetspiramide van Mike Cohn beskryf 'n konsep vir die gebruik van die outomatiese sagtewaretoetse. Die piramide bestaan ​​uit drie vlakke, gestruktureer volgens frekwensie van gebruik en relevansie. ‍

Ideaal gesproke word die basis van die toetspiramide gevorm deur baie vinnige en maklik-om-te-onderhoude eenheidstoetse.Op hierdie manier kan die meeste foute vinnig opgespoor word.

Op die middelvlak is die integrasietoetse Hulle verskaf dienste vir die geteikende toetsing van kritieke koppelvlakke Die uitvoeringstye van integrasietoetse is langer en die instandhouding daarvan is ook meer kompleks as dié van eenheidstoetse.

Die bokant van die piramide bestaan ​​uit stadige E2E-toetse, wat soms baie instandhouding verg.E2E-toetse is baie nuttig om die toepassing as 'n volledige stelsel te toets.

Vereistes

Watter toerusting het jy nodig om aan die volgende praktiese deel te werk?

Watter vereistes het jy om aktief aan die volgende praktiese deel te werk? Jy hoef nie aan baie vereistes te voldoen om aan die inhoud van hierdie handleiding te kan werk nie. Jy moet natuurlik 'n rekenaar hê. 'n Ontwikkelingsomgewing met Git, NodeJS en Composer en 'n plaaslike webbediener moet daarop geïnstalleer of installeerbaar wees.

Watter kennis moet jy persoonlik hê?

Jy behoort basiese programmeringstegnieke te ken. Ideaal gesproke het jy reeds 'n klein webtoepassing geprogrammeer. In elk geval moet jy weet waar om lêers op jou ontwikkelingsrekenaar te stoor en hoe om dit in jou internetblaaier te laai. nuwe dinge uit.

Probeer dit. Integreer toetse in jou volgende projek. Miskien sal jou eerste ervaring van 'n toets jou 'n vervelige ontfoutingsessie of 'n verleentheid fout in die regte stelsel bespaar. Met 'n veiligheidsnet van toetse kan jy immers sagteware met minder ontwikkel spanning.

Opstel

Stel Cypress op met Joomla!

In die ontwikkelaarweergawe wat op Github beskikbaar is, is Joomla Cypress-gereed gekonfigureer. Daar is reeds toetse wat jy as 'n gids kan gebruik. Dit is dus nie nodig om alles self op te stel om 'n eerste oorsig te kry nie. Op hierdie manier kan jy met Cypress eksperimenteer , leer oor die voordele en nadele daarvan, en besluit self of jy die toetsinstrument wil gebruik.

Stappe om die plaaslike omgewing op te stel:

Kloon die bewaarplek na die wortel van u plaaslike webbediener:

$ git clone https://github.com/joomla/joomla-cms.git

Navigeer na die joomla-cms-lêergids:

$ cd joomla-cms

Volgens Joomla Roadmap sal die volgende groot weergawe 5.0 in Oktober 2023 vrygestel word. Om op datum te wees, gebruik ek hierdie ontwikkelingsweergawe hier.

Verander na die tak 5.0-dev :

$ git checkout 5.0-dev

Installeer al die nodige komponispakkette:

$ composer install

Installeer al die nodige npm-pakkette:

$ npm install

Vir meer inligting en hulp oor die opstel van jou werkstasie, sien die Joomla-dokumentasie-artikel "Opstel van jou werkstasie vir Joomla-ontwikkeling" . Vir Cypress is daar inligting by cypress.io . Maar dit is nie op hierdie stadium nodig nie. Joomla stel alles op vir jou. Jy hoef net jou individuele data op te stel via die konfigurasielêer joomla-cms/cypress.config.js.

Stel jou individuele data op. Hiervoor kan jy die sjabloon joomla-cms/cypress.config.dist.jsas oriëntasie gebruik. In my geval lyk hierdie lêer soos volg:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  fixturesFolder: 'tests/cypress/fixtures',
  videosFolder: 'tests/cypress/output/videos',
  screenshotsFolder: 'tests/cypress/output/screenshots',
  viewportHeight: 1000,
  viewportWidth: 1200,
  e2e: {
    setupNodeEvents(on, config) {},
    baseUrl: 'http://localhost/joomla-cms',
    specPattern: [
      'tests/cypress/integration/install/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/administrator/**/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/module/**/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/site/**/*.cy.{js,jsx,ts,tsx}'
    ],
    supportFile: 'tests/cypress/support/index.js',
    scrollBehavior: 'center',
    browser: 'firefox',
    screenshotOnRunFailure: true,
    video: false
  },
  env: {
    sitename: 'Joomla CMS Test',
    name: 'admin',
    email: Hierdie e-posadres word teen spambots beskerm. Jy benodig JavaScript geaktiveer om dit te bekyk.',
    username: 'admin',
    password: 'adminadminadmin',
    db_type: 'MySQLi',
    db_host: 'mysql',
    db_name: 'test_joomla',
    db_user: 'root',
    db_password: 'root',
    db_prefix: 'j4_',
  },
})

Konkreet het ek die gids tests/cypress/integration/module/**/*.cy.{js,jsx,ts,tsx}by die specPattern Array gevoeg, want ek wil later toets vir modules daar stoor. Toe verander ek die gebruikersnaam en wagwoorde want ek wil ook die installasie handmatig toets en die selftoegewysdes beter onthou. Ek gebruik 'n Docker-houer as databasis. Daarom het ek die databasisbediener en die toegangsdata verander. En uiteindelik moes ek die root-URL http://localhost/joomla-cmsvan my Joomla-installasie stel.

Gebruik Cypress

Via webblaaier

Bel npm run cypress:openvia CLI in jou Joomla-wortelgids. 'n Kort rukkie later sal die Cypress-toepassing oopmaak. Ons het die lêer voorheen geskep. joomla-cms/cypress.config.dist.jsDat dit bespeur word, kan gesien word uit die feit dat E2E-toetsing gespesifiseer is soos opgestel.

Cypress App maak oop nadat jy 96 gebel het;npm run cypress:open96;.

Hier kan jy kies of jy die E2E-toetse wil laat loop en watter blaaier jy wil gebruik.Vir die voorbeeld het ek die "Begin toets in Firefox" opsie gekies.

E2E-toetse in die Cypress-toepassing: kies die blaaier om te gebruik.

Alle beskikbare toetssuites sal gelys word en jy kan op die een klik wat jy wil hardloop.Wanneer jy 'n toetssuite kies, sal die toetse loop en jy kan die loop van die toetse intyds in die blaaier bekyk.

Joomla-toetssuite in Firefox via Cypress App.

Terwyl die toetse aan die gang is, kan jy die uitgevoerde skrif aan die een kant sien en die resultaat in die blaaier aan die regterkant. Dit is nie net skermkiekies nie, maar regte kiekies van die blaaier op daardie oomblik, sodat jy die werklike HTML-kode kan sien Skermkiekies en selfs video's van die toetse is ook moontlik.

Joomla-installasietoets aan die gang.

Probeer dit uit. As jy gebruik soos db_host: 'localhost',jy kan die installasie toets en dus Joomla korrek gekonfigureer het vir die werk op die volgende deel van hierdie teks.

As jy, soos ek, 'n eksterne bron (nie lcoalhost nie; ek gebruik 'n docker-houer) as gebruik db_host, is die toets vir hierdie soort installasie nog nie gereed nie. In daardie geval is daar 'n vraag vir sekuriteit in die installeringsroetine, wat is nog nie in die toetse oorweeg nie. In hierdie geval, installeer Joomla handmatig met die inligting wat in die lêer ingevoer is joomla-cms/cypress.config.js. Die volgende toetse sal die instellings van hierdie konfigurasielêer gebruik, byvoorbeeld om by die Joomla-administrasie-area aan te meld. Op hierdie manier doen die toetsontwikkelaar hoef nie omgee om die aanmelddata in te voer nie. Die ooreenstemmende gebruiker en wagwoord word altyd outomaties vanaf die konfigurasielêer gebruik.

Koploos

By verstek, cypress runloop alle toetse koploos . Die volgende opdrag voer alle reeds gekodeerde toetse uit en stoor skermkiekies in die gids /joomla-cms/tests/cypress/output/screenshotsin geval van 'n fout. Die uitvoergids is in die cypress.config.jslêer gestel.

$ npm run cypress:run

Ander CLI-opdragte

Daar is ander nuttige opdragte wat nie as skrifte in package.jsondie Joomla-projek geïmplementeer word nie. Ek voer dit uit via npx [docs.npmjs.com/commands/npx].

sipres verifieer

Die cypress verifyopdrag verifieer dat Cypress korrek geïnstalleer is en uitgevoer kan word.

$ npx cypress verify

✔  Verified Cypress! /.../.cache/Cypress/12.8.1/Cypress
sipres inligting

Die cypress infoopdrag voer inligting uit oor Cypress en die huidige omgewing.

$ npx cypress info
Displaying Cypress info...

Detected 2 browsers installed:

1. Chromium
  - Name: chromium
  - Channel: stable
  - Version: 113.0.5672.126
  - Executable: chromium
  - Profile: /.../snap/chromium/current

2. Firefox
  - Name: firefox
  - Channel: stable
  - Version: 113.0.1
  - Executable: firefox
  - Profile: /.../snap/firefox/current/Cypress/firefox-stable

Note: to run these browsers, pass : to the '--browser' field

Examples:
- cypress run --browser chromium
- cypress run --browser firefox

Learn More: https://on.cypress.io/launching-browsers

Proxy Settings: none detected
Environment Variables: none detected

Application Data: /.../.config/cypress/cy/development
Browser Profiles: /.../.config/cypress/cy/development/browsers
Binary Caches: /.../.cache/Cypress

Cypress Version: 12.8.1 (stable)
System Platform: linux (Ubuntu - 22.04)
System Memory: 4.08 GB free 788 MB
sipres weergawe

Die cypress versionopdrag druk die geïnstalleerde Cypress-binêre weergawe, die weergawe van die Cypress-pakket, die weergawe van Electron wat gebruik word om Cypress te skep, en die gebundelde node-weergawe.

$ npx cypress version
Cypress package version: 12.8.1
Cypress binary version: 12.8.1
Electron version: 21.0.0
Bundled Node version: 16.16.0

Cypress se dokumentasie verskaf meer gedetailleerde inligting.

Die skryf van die eerste eie toets

As alles tot dusver gewerk het, kan ons ons eie toetse begin skep.

Kry 'n oorsig

Leer uit toetse wat reeds ontwikkel is

In die ontwikkelingsweergawe van die Joomla CMS is daar reeds Cypress-toetse. Dit is in die gids /tests/System/integration. Diegene wat daarvan hou om deur voorbeeld te leer, sal 'n geskikte inleiding hier vind.

Voer kode in vir herhalende take

Die Joomla-ontwikkelaars werk aan die NodeJs- projek joomla-cypress , wat toetskode vir algemene toetsgevalle verskaf. Dit word ingevoer tydens die installering van die ontwikkelaarweergawe van die CMS met behulp van npm installvia

  • package.jsonen via die
  • ondersteuningslêer /tests/System/support/index.jsDie ondersteuningslêer word in die konfigurasie gedefinieer cypress.config.js.
// package.json
{
  "name": "joomla",
  "version": "5.0.0",
  "description": "Joomla CMS",
  "license": "GPL-2.0-or-later",
  "repository": {
    "type": "git",
    "url": "https://github.com/joomla/joomla-cms.git"
  },
...
  "devDependencies": {
    ...
    "joomla-cypress": "^0.0.16",
    ...
  }
}

'n Voorbeeld is die klik op 'n nutsbalkknoppie. Cypress.Commands.add('clickToolbarButton', clickToolbarButton)Dit veroorsaak byvoorbeeld dat die opdrag clickToolbarButton()in die pasgemaakte toetse beskikbaar is en deur cy.clickToolbarButton('new')'n klik op die knoppie Newgesimuleer word. Die kode wat hiervoor benodig word, word in die kodesnit hieronder getoon.

// node_modules/joomla-cypress/src/common.js
...
const clickToolbarButton = (button, subselector = null) => {
  cy.log('**Click on a toolbar button**')
  cy.log('Button: ' + button)
  cy.log('Subselector: ' + subselector)

  switch (button.toLowerCase())
  {
    case "new":
      cy.get("#toolbar-new").click()
      break
    case "publish":
      cy.get("#status-group-children-publish").click()
      break
    case "unpublish":
      cy.get("#status-group-children-unpublish").click()
      break
    case "archive":
      cy.get("#status-group-children-archive").click();
      break
    case "check-in":
      cy.get("#status-group-children-checkin").click()
      break
    case "batch":
      cy.get("#status-group-children-batch").click()
      break
    case "rebuild":
      cy.get('#toolbar-refresh button').click()
      break
    case "trash":
      cy.get("#status-group-children-trash").click()
      break
    case "save":
      cy.get("#toolbar-apply").click()
      break
    case "save & close":
      cy.get(".button-save").contains('Save & Close').click()
      break
    case "save & new":
      cy.get("#save-group-children-save-new").click()
      break
    case "cancel":
      cy.get("#toolbar-cancel").click()
      break
    case "options":
      cy.get("#toolbar-options").click()
      break
    case "empty trash":
    case "delete":
      cy.get("#toolbar-delete").click()
      break
    case "feature":
      cy.get("#status-group-children-featured").click()
      break
    case "unfeature":
      cy.get("#status-group-children-unfeatured").click()
      break
    case "action":
      cy.get("#toolbar-status-group").click()
      break
    case "transition":
      cy.get(".button-transition.transition-" + subselector).click()
      break
  }

  cy.log('--Click on a toolbar button--')
}

Cypress.Commands.add('clickToolbarButton', clickToolbarButton)
...

Die volgende kode toon nog 'n voorbeeld, die aanmelding by die administrasie area.

// /node_modules/joomla-cypress/src/user.js
...
const doAdministratorLogin = (user, password, useSnapshot = true) => {
  cy.log('**Do administrator login**')
  cy.log('User: ' + user)
  cy.log('Password: ' + password)

  cy.visit('administrator/index.php')
  cy.get('#mod-login-username').type(user)
  cy.get('#mod-login-password').type(password)
  cy.get('#btn-login-submit').click()
  cy.get('h1.page-title').should('contain', 'Home Dashboard')

  cy.log('--Do administrator login--')
}

Cypress.Commands.add('doAdministratorLogin', doAdministratorLogin)

...
Algemene take in die individuele omgewing

In die gids /tests/System/supportsal jy algemene take in die individuele omgewing vind. Sodat dit maklik hergebruik kan word, word dit via die ondersteuningslêer ingevoer. 'n Voorbeeld /tests/System/support/index.jsvan 'n gereeld herhaalde taak is die aanmelding by die administrasie area, wat in die lêer hanteer word /tests/System/support/commands.jsmet behulp van die funksie doAdministratorLogin.

Die volgende kode wys ook hoe die inligting uit die cypress.config.jskonfigurasie in die toetse gebruik word. word die waarde van die eiendom binne die groep Cypress.env('username')toegeken .usernameenv

Ook, ons kan hier sien hoe om opdragte te oorskryf. Cypress.Commands.overwrite('doAdministratorLogin' ...),oorskryf die kode wat ons sopas in die pakket gesien het joomla-cypress. Die voordeel is dat gebruiker en wagwoord outomaties gebruik word vanaf die individuele konfigurasie.

// /tests/System/support/commands.js
...
Cypress.Commands.overwrite('doAdministratorLogin', (originalFn, username, password, useSnapshot = true) => {
  // Ensure there are valid credentials
  const user = username ?? Cypress.env('username');
  const pw = password ?? Cypress.env('password');

  // Do normal login when no snapshot should be used
  if (!useSnapshot) {
    // Clear the session data
    Cypress.session.clearAllSavedSessions();

    // Call the normal function
    return originalFn(user, pw);
  }

  // Do login through the session
  return cy.session([user, pw, 'back'], () => originalFn(user, pw), { cacheAcrossSpecs: true });
});
...

Installeer eie Joomla-uitbreiding

Om te sien hoe om jou eie kode te toets, sal ons 'n eenvoudige voorbeeld komponent installeer via die Joomla backend. Die lêer vir installasie kan afgelaai word vanaf Codeberg .

Installeer eie Joomla uitbreiding.

Na die installasie kan u 'n skakel vind na die aansig van die Foo-komponent in die linkerkantbalk van die Joomla-agterkant.

Aansig van die voorbeeld komponent in die Joomla backend.

Ons het nou 'n toetsomgewing opgestel en kode vir om te toets.

Die eerste eie toets

Hakies

Wanneer die backend getoets word, sal jy agterkom dat jy elke toets met 'n login moet begin. Ons kan hierdie oortollige kode voorkom deur die funksie te gebruik. beforeEach()Hierdie sogenaamde haak voer die kode uit wat ons intik voordat elke toets uitgevoer word. Vandaar die naam beforeEach().

Cypress verskaf verskeie tipes hake , insluitend beforeen afterhake wat voor of na die toetse in 'n toetsgroep loop, en beforeEachen afterEachhake wat loop voor of na elke individuele toets in die groep. Hake kan globaal of binne 'n spesifieke describedblok gedefinieer word. Die volgende kodevoorbeeld in die lêer tests/System/integration/administrator/components/com_foos/FoosList.cy.jsveroorsaak dat 'n aanmelding in die agterkant uitgevoer word voor elke toets binne die describedblok test com_foos features.

Ons begin nou met die praktiese deel en skep die lêer tests/System/integration/administrator/components/com_foos/FoosList.cy.jsmet die volgende codesnippted voordat ons die eerste produktiewe toets skryf. Ons eerste voorbeeld behoort ons suksesvol by die backend aan te meld voor enige toets! Ons sal dit toets nadat ons die eerste toets geskep het.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

})

Let wel: Hakies, wat binne lêer geïmplementeer word /tests/System/support/index.js, is van toepassing op elke toetslêer in die toetspak.

'n Suksesvolle toets

Die komponent wat ons vir toetsing geïnstalleer het, bevat die drie elemente Astrid, Ninaen ElmarEerstens toets ons of hierdie elemente suksesvol geskep is.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

  it('list view shows items', function () {
    cy.visit('administrator/index.php?option=com_foos')

    cy.get('main').should('contain.text', 'Astrid')
    cy.get('main').should('contain.text', 'Nina')
    cy.get('main').should('contain.text', 'Elmar')

    cy.checkForPhpNoticesOrWarnings()
  })
})

Let wel: Die funksie checkForPhpNoticesOrWarnings()wat jy in die lêer vind /node_modules/joomla-cypress/src/support.js.

Ons kry die DOM-element mainvia die Cypress-opdrag get

Jy behoort jou pasgeskepte toets FooList.cy.jsin die lys van die beskikbare toetse in die linkerkantbalk te vind. As dit nie die geval is nie, maak asseblief die blaaier toe en hardloop npm run cypress:openweer.

Joomla hardlooptoets vir eie uitbreiding.

Klik op die naam van die toets om dit te laat loop. Dit behoort suksesvol te eindig en jy sien groen boodskappe.

Die aansig na die toets het suksesvol uitgevoer.

'n Mislukte toets

Voeg die reël cy.get('main').should('contain.text', 'Sami')by die toetslêer sodat die lopie misluk. Daar is geen element met hierdie naam nie. Nadat die toetslêer gestoor is, merk Cypress die verandering op. Na elke verandering herloop Cypress outomaties al die toetse in die toetslêer.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js
describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

  it('list view shows items', function () {
    cy.visit('administrator/index.php?option=com_foos')

    cy.get('main').should('contain.text', 'Astrid')
    cy.get('main').should('contain.text', 'Nina')
    cy.get('main').should('contain.text', 'Elmar')
    cy.get('main').should('contain.text', 'Sami')

    cy.checkForPhpNoticesOrWarnings()
  })
})

Soos verwag, misluk die toets. Daar is rooi boodskappe. Jy kan die kode van elke toetsstap in die linkerkantbalk sien. Dit is dus moontlik om die rede vir die fout te vind. Vir elke stap is daar 'n momentopname van die HTML-dokument, sodat jy die opmaak enige tyd kan nagaan. Dit is nuttig, veral tydens ontwikkeling.

Die aansig na die toets het misluk.

Voer slegs een toets in 'n lêer uit

Ons demonstrasie-uitbreiding bevat meer as een uitleg. Voeg 'n toets by om die leë toestanduitleg te toets. Aangesien ons nou twee toetse in hierdie lêer het, sal Cypress altyd albei toetse laat loop elke keer as ons die lêer stoor. Ons kan so gebruik dat slegs een .only()toets word uitgevoer:

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
    beforeEach(() => {
        cy.doAdministratorLogin()
    })

    it('list view shows items', function () {
        cy.visit('administrator/index.php?option=com_foos')

        cy.get('main').should('contain.text', 'Astrid')
        cy.get('main').should('contain.text', 'Nina')
        cy.get('main').should('contain.text', 'Elmar')

        cy.checkForPhpNoticesOrWarnings()
    })

    it.only('emptystate layout', function () {
        cy.visit('administrator/index.php?option=com_foos&view=foos&layout=emptystate')
        cy.get('main').should('contain.text', 'No Foo have been created yet.')
    })
})

Tydens ontwikkeling is dit baie gerieflik.

Spesiale toetseienskappe

Nou wil ons graag die frontend vir ons komponent toets. Ons doen dit in 'n aparte lêer /tests/System/integration/site/components/com_foos/FooItem.cy.js.

Meeste van die tyd gebruik ons ​​'n CSS-klas om 'n element in Joomla-toetse te kry. Alhoewel dit heeltemal geldig is en sal werk, word dit nie eintlik aanbeveel nie. Hoekom nie? Wanneer jy CSS-klasse of ID's gebruik, bind jy jou toetse aan dinge wat sal heel waarskynlik met verloop van tyd verander. Klasse en ID's is vir ontwerp, uitleg en soms via JavaScript vir beheer, wat maklik kan verander. As iemand 'n klasnaam of ID verander, sal jou toetse nie meer werk nie. Om jou toetse minder bros en meer toekomsbestendig, Cypress beveel aan om spesiale data-kenmerke vir jou elemente spesifiek vir toetsdoeleindes te skep.

Ek sal die data-testkenmerk vir die elemente gebruik. Eers voeg ek die kenmerk data-test="foo-main"by die produksiekode.

// /components/com_foos/tmpl/foo/default.php

\defined('_JEXEC') or die;
?>
<div data-test="foo-main">
Hello Foos
</div>

Dan toets ek die produksiekode deur na die kenmerk te soek [data-test="foo-main"].

// tests/System/integration/site/components/com_foos/FooItem.cy.js
describe('Test com_foo frontend', () => {
  it('Show frondend via query in url', function () {
    cy.visit('index.php?option=com_foos&view=foo')

    cy.get('[data-test="foo-main"]').should('contain.text', 'Hello Foos')

    cy.checkForPhpNoticesOrWarnings()
  })
})
Toets 'n spyskaart-item en 'n paar gedagtes oor gebeure, wag en beste praktyk

Nou wil ek graag die skepping van 'n spyskaart-item vir ons komponent toets. Ek doen dit in 'n aparte lêer /tests/System/integration/administrator/components/com_foos/MenuItem.cy.js. Hierdie kode is kompleks en toon baie spesiale kenmerke.

Eerstens het ek 'n konstante gedefinieer waarin ek al die relevante eienskappe van die kieslys-item stel. Dit het die voordeel dat ek in geval van veranderinge van 'n relevante eienskap slegs op een plek moet aanpas:

const testMenuItem = {
  'title': 'Test MenuItem',
  'menuitemtype_title': 'COM_FOOS',
  'menuitemtype_entry': 'COM_FOOS_FOO_VIEW_DEFAULT_TITLE'
}

Volgende sien jy die hele kode van die lêer MenuItem.cy.js:

// tests/System/integration/administrator/components/com_foos/MenuItem.cy.js

describe('Test menu item', () => {
  beforeEach(() => {
    cy.doAdministratorLogin(Cypress.env('username'), Cypress.env('password'))
  })

  it('creates a new menu item', function () {
    const testMenuItem = {
      'title': 'Test MenuItem',
      'menuitemtype_title': 'COM_FOOS',
      'menuitemtype_entry': 'COM_FOOS_FOO_VIEW_DEFAULT_TITLE'
    }

    cy.visit('administrator/index.php?option=com_menus&view=item&client_id=0&menutype=mainmenu&layout=edit')
    cy.checkForPhpNoticesOrWarnings()
    cy.get('h1.page-title').should('contain', 'Menus: New Item')

    cy.get('#jform_title').clear().type(testMenuItem.title)

    cy.contains('Select').click()
    cy.get('.iframe').iframe('#collapse1-heading').contains(testMenuItem.menuitemtype_title).click()
    cy.get('.iframe').iframe('#collapse1-heading').contains(testMenuItem.menuitemtype_entry).click()

    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_list')
    cy.clickToolbarButton('Save & Close')
    cy.wait('@item_list')
    cy.get('#system-message-container').contains('Menu item saved.').should('exist')

    // Frontend
    cy.visit('index.php')
    cy.get('.sidebar-right').contains(testMenuItem.title).click()
    cy.get('[data-test="foo-main"]').should('contain.text', 'Hello Foos')
    cy.checkForPhpNoticesOrWarnings()

    // Trash
    cy.visit('administrator/index.php?option=com_menus&view=items&menutype=mainmenu')
    cy.searchForItem(testMenuItem.title)
    cy.checkAllResults()
    cy.clickToolbarButton('Action')
    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_trash')
    cy.clickToolbarButton('trash')
    cy.wait('@item_trash')
    cy.get('#system-message-container').contains('Menu item trashed.').should('exist')

    // Delete
    cy.visit('administrator/index.php?option=com_menus&view=items&menutype=mainmenu')
    cy.setFilter('published', 'Trashed')
    cy.searchForItem(testMenuItem.title)
    cy.checkAllResults()
    cy.on("window:confirm", (s) => {
      return true;
    });
    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_delete')
    cy.clickToolbarButton('empty trash');
    cy.wait('@item_delete')
    cy.get('#system-message-container').contains('Menu item deleted.').should('exist')
  })
})
  • In hierdie kode kan jy 'n voorbeeld sien van iets toets en dan alles uitvee - dus herstel die aanvanklike toestand. Op hierdie manier kan jy die toetse herhaal soveel keer as wat jy wil. Sonder om die aanvanklike toestand te herstel, sal die tweede toetslopie misluk omdat Joomla kan nie twee soortgelyke elemente stoor nie.

Let wel: 'n Toets moet wees:

  • herhaalbaar.
  • In konkrete terme beteken dit dat dit 'n beperkte probleem moet toets en die kode hiervoor moet nie te uitgebreid wees nie.
  • onafhanklik van ander toetse.
  • En jy kan sien hoe om 'n onderskepte roete te gebruik wat met cy.intercept()[^docs.cypress.io/api/commands/intercept] as 'n alias gedefinieer is, en dan wag vir die roete wat as 'n alias met cy.wait().

Wanneer toetse vir sulke toepassings geskryf word, kom 'n mens in die versoeking om ewekansige waardes soos cy.wait(2000);in die cy.waitopdrag te gebruik. Die probleem met hierdie benadering is dat hoewel dit goed kan werk in ontwikkeling. Dit is egter nie gewaarborg om altyd te werk nie. Hoekom? Omdat die onderliggende stelsel hang af van dinge wat moeilik is om te voorspel.Daarom is dit altyd beter om presies te definieer waarvoor jy wag.

  • Die kode wys ook hoe om te wag vir 'n waarskuwing en dit te bevestig .
cy.on("window:confirm", (s) => {
  return true;
});
  • Laastens, maar nie die minste nie, bevat die toetskode Cypress-ingeboude en Joomla-tipiese funksies wat deur uitbreidingsontwikkelaars hergebruik kan word, cy.setFilter('published', 'Trashed')of cy.clickToolbarButton('Save & Close')is funksies waarin oplossings vir individuele toetse in die algemeen gevind kan word en wat veral Joomla-ontwikkelaars dikwels benodig. .
Meng Async en Sync Kode

Cypress-opdragte is asinchronies, dit wil sê, hulle gee nie 'n waarde terug nie, maar generatedit. Wanneer ons Cypress begin, voer dit nie die opdragte dadelik uit nie, maar lees dit in 'n reeks en stel dit in tou. As jy asinchrone en sinchrone kode in toetse meng, sal jy kan onverwagte resultate kry. As jy die volgende kode hardloop, sal jy 'n fout kry teen verwagting. Jy sou sekerlik ook verwag het dat dit die waarde mainText = $main.text()verander mainText. Maar mainText === 'Initial'is steeds geldig aan die einde. Hoekom is dit? Cypress voer eers die sinchroniese kode uit by die begin en aan die einde Eers dan roep dit die asynchrone deel binne then(). Dit beteken die veranderlike mainTextword geïnisialiseer en onmiddellik daarna word dit gekontroleer as dit verander het - wat natuurlik nie die geval is nie.

let mainText = 'Initial';
cy.visit('administrator/index.php?option=com_foos&view=foos&layout=emptystate')
cy.get("main").then(
  ($main) => (mainText = $main.text())
);

if (mainText === 'Initial') {
  throw new Error(`Der Text hat sich nicht geändert. Er lautet: ${mainText}`);
}

Die verwerking van die tou word redelik duidelik en visueel as 'n mens die uitvoering van die volgende kode in die konsole van die blaaier waarneem. Die teks 'Cypress Test.' verskyn lank voordat die inhoud van die element gewys word, alhoewel die mainkodereëls in 'n ander volgorde.

cy.get('main').then(function(e){
  console.log(e.text())
})
console.log('Cypress Test.')
Stubs en Spies

A stubis 'n manier om die gedrag van die funksie waarvan die toetse afhanklik is te simuleer. In plaas daarvan om die werklike funksie te roep, vervang die stomp daardie funksie en gee 'n voorafbepaalde voorwerp terug. Dit word gewoonlik in eenheidstoetse gebruik, maar kan ook vir einde gebruik word -tot-einde toetsing.

A spyis soortgelyk aan die stub, maar nie presies dieselfde nie. Dit verander nie die gedrag van 'n funksie nie, maar laat dit soos dit is. Dit vang inligting vas oor hoe die funksie genoem word. Byvoorbeeld, om te kyk of die funksie genoem word met die korrekte parameters, of om te tel hoe gereeld die funksie geroep word.

Die volgende voorbeeld wys 'n spyen 'n stubin aksie. Via const stub = cy.stub()skep ons die stubelement en bepaal in die volgende stap wat falseteruggestuur word vir die eerste oproep en truevir die tweede. Deur gebruik te maak cy.on('window:confirm', stub)maak ons ​​die stubgebruik word vir window:confirm'. In die volgende stap skep ons met cy.spy(win, 'confirm').as('winConfirmSpy')die Spyelement , wat die oproep van waarneem 'window:confirm'. Nou toets ons dat op die eerste oproep die skrap van die kategorie verwerp word en op die tweede oproep word dit bevestig. Sodoende verseker die ons stubdat ons verseker kan verwag watter opbrengswaardes sal wees afgelewer. 'window:confirm'is ingekapsuleer. @winConfirmSpyhelp om te verseker dat die funksie werklik geroep is - en hoe gereeld dit geroep is.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js
...
const stub = cy.stub()

stub.onFirstCall().returns(false)
stub.onSecondCall().returns(true)

cy.on('window:confirm', stub)

cy.window().then(win => {
  cy.spy(win, 'confirm').as('winConfirmSpy')
})

cy.intercept('index.php?option=com_categories&view=categories&extension=com_foos').as('cat_delete')
cy.clickToolbarButton('empty trash');

cy.get('@winConfirmSpy').should('be.calledOnce')
cy.get('main').should('contain.text', testFoo.category)


cy.clickToolbarButton('empty trash');
cy.wait('@cat_delete')

cy.get('@winConfirmSpy').should('be.calledTwice')

cy.get('#system-message-container').contains('Category deleted.').should('exist')
...

As dit net 'n kwessie is om 'n vaste waarde vir die 'window:confirm'oproep te stel, sal die volgende kode die werk doen.

cy.on("window:confirm", (s) => {
  return true;
});

afsluiting

In hierdie artikel het jy basiese teorie en praktiese kenmerke van E2E-toetsing met Cypress gesien. Ek het die Joomla-installasie gebruik om te demonstreer hoe om verskillende toetse te skryf om te verseker dat 'n Joomla-komponent op 'n webwerf werk soos verwag word. Ek het ook gewys hoe om die Cypress aan te pas. Toets Runner in die cypress.json-lêer en hoe om gepasmaakte Cypress-opdragte te gebruik. Dit is gedoen met behulp van maklik om te volg voorbeelde.

Ek hoop jy het die toer deur Cypress geniet deur Joomla as voorbeeld te gebruik en dat jy baie kennis en inspirasie vir jouself kon wegneem.

An online collaborative community manual for Joomla! users, developers or anyone interested in learning more about Joomla! Currently, we have more than 9,000 articles written, maintained, and translated by our Joomla! community members. 

Neem asseblief kennis dat hierdie webwerf 'n outomatiese vertaalstelsel gebruik om te help met die vertaling vir die verskillende tale. Ons vra om verskoning vir enige fout of tikfoute wat in die verskillende tekste getoon kan word.