Pepita73 / webproghu_dev

Webprog.hu apache-php7.2, Drupal 8.5.5
1 stars 1 forks source link

Tesztelés #10

Open ghost opened 6 years ago

ghost commented 6 years ago

Jó lenne eldönteni, hogy akarunk e tesztelni, illetve, hogy milyen stílusban tesszük mindezt, TDD, BDD, esetleg utólagos tesztelés, illetve hogy legyenek e integrációs tesztek, amikkel az SQL-eket, esetleg e2e teszttel a GUI-t ellenőrizzük. Ha valamelyikre igen a válasz, akkor ezekre is fel kell lőni valami automatizmust. A dolognak annyi előnye van, hogy a review-ot könnyebbé teszi, mert elég csak megnézni, hogy megvan e minden teszt az adott feature-höz, és hogy azokon átmegy e a kód.

ghost commented 6 years ago

Gondolom a teszt keretrendszer phpunit, legalábbis én nem tudok róla, hogy lenne más.

A github a Travis-el meg tudja oldani, hogy a feltöltött dolgokra automatikusan lefussanak a tesztek, aztán kapjunk egy szép build passing/failing logót a readme-be. Erről már volt szó a #9 -ben érintőlegesen. A dolog hátulütője, hogy egyrészt látja a Travis a kódunkat, másrészt egy ilyesmi log lesz a végeredmény: https://travis-ci.org/inf3rno/error-polyfill/jobs/346107396 , amit szerintem mindenki lát privát repo esetében is, tehát bár nem vagyok benne biztos, de valószínűleg szivárogtat valamennyi információt a kódunkról. Kérdés, hogy bevállaljuk e ezt a kockázatot.

Én személy szerint valamilyen BDD jellegű megoldást javasolnék az én stílusomban. Szóval hogy ne menjünk annyira részletekbe, mint a TDD-nél, hanem nézzük meg, hogy az adott kód nagyjából úgy működik, ahogy elvárjuk, vagy sem. Szerintem mindenki tud annyira figyelni a kódjára, hogy a fejlesztés közben esetleg előforduló hibákat kigyomlálja, és így a végeredmény is rugalmasabb lesz a változtatásra. Ez persze csak egy vélemény.

Pepita73 commented 6 years ago
ghost commented 6 years ago

Ezekről lemaradtam, nyaralni voltam. Ha nem igazán fejlesztünk bele kódot, akkor max az e2e teszteknek van értelme, amit te is írsz, hogy Seleniummal megnyomkodni. Egyébként van olyan is, aminél képfelismeréssel csinálják mindezt: http://www.sikuli.org/ tehát még a HTML-t sem kell ismerni hozzá, amit az oldal visszadob. Pl flash-nél szoktak ilyesmit használni. A BDD más, az csak annyiban különbözik a TDD-től, hogy milyen absztrakciós szinten adod meg a tesztet. A TDD nagyon alacsony szintű 1-1 osztályt tesztel. A BDD lehet jóval magasabb szinten is. Én azt szeretem, ha csak magasabb szintre írok tesztet, aztán úgyis látom néhány ilyen tesztből, ha az alacsony szintű kóddal baj van. Valamivel nehezebb így megtalálni a hiba okát, de nem kell minden apró módosításnál hozzányúlni a tesztekhez, mint a TDD esetében. Jó, nekem végülis ráér, kezdetnek elég pár e2e teszt, aztán ha esetleg lesz saját kód benne, akkor meg lehet csinálni keményebben. Nem tudom, hogy a phpunit, a bdd és a selenium mennyire férnek össze, majd utánajárok. Ahogy látom még bőven ráér.

Pepita73 commented 6 years ago

Egyébként meg csak build és teszt fog menni minden commit-nál

Ez nem gond szerintem, deploy lehet "nyomkodós".

Nem tudom, hogy a phpunit, a bdd és a selenium mennyire férnek össze

phpunitot és seleniumot használtunk már egyszerre egy projekten. Elvileg szerintem bdd is simán megfér mellettük, mert önmagában az nem baj, ha ugyanazt a dolgot többféleképp teszteled. Mondjuk phpunit gyakorlatilag csak BE-t tesztel, selenium meg csak FE-t (de ezen keresztül némiképp BE működést is), szóval ezeknél kisebb a káros átfedés lehetősége.

Szerintem maradjunk a "Seleniummal megnyomkodni", itt is a konkrét tesztet meg kell előzze, hogy legalább valami alap setup legyen Drupal-ban. Ha a #9 deploy-ban meg tudod csinálni a helyét (hogy már "csak" teszteket kelljen írni), az nagyon jó és egyelőre elég lenne szerintem.

ghost commented 6 years ago

@Pepita73 Oké, holnap ráállok, mára elég volt ennyi.

ghost commented 6 years ago

Átgondoltam ezt az e2e tesztelést, és szerintem Karma-val fogom megcsinálni. Már régóta kacérkodok a gondolattal, hogy Karma-val kellene e2e tesztelést csinálni, és nem Seleniummal, és így, hogy átgondoltam, elég egyszerűnek tűnik a megvalósítása. Csak annyi kell hozzá, hogy berántom egy iframe-be az oldalt és CORS header-el hozzáférést adok neki a Karma-val kiszolgált teszt script-jeimhez. Kipróbálom egyelőre egy külön repo-ban nodejs-el, hogy ez így életképes e, aztán utána hozzáigazítom majd a Drupal-hoz. Az még nem világos, hogy a github-os Travis-el hogyan fogom fellőni a Drupal-t, majd elindítani hozzá a Karma-t, de Seleniummal úgy láttam, hogy sikerült már valakinek, úgyhogy gondolom akkor Karma-val sem fog gondot okozni.

Még arra vagyok kíváncsi, hogy akkor elég lesz e tesztelésre ez az e2e megoldás, vagy akartok phpunit-os unit/integrációs teszteket is?

Pepita73 commented 6 years ago

Phpunit szerintem csak akkor, ha fejlesztünk is saját BE-t. Az nekem nem világos, hogy miért kell külön Drupal telepítés, ha egyszer ott van.  De lehet, hogy csak én tudok túl keveset.  :) 

Üdvözlettel: Horváth Péter

(Mobilról)

ghost commented 6 years ago

Úgy szeretném megoldani, hogy amikor push-olsz githubra, akkor a github küldje át a travis-nek a kódot, aztán menjen le a teszt automatikusan az ő szerverükön is. Igy ha valaki olyat akar push-olni, ami nem megy át a teszteken, akkor a pull request-nél látszani fog, hogy piros, és kukázhatjuk vagy javíthatjuk. Nagyjából valami hasonlót kell összeszórnom egy Travis config fájlban hozzá, mint ami a DockerFile-ban van, talán egy kicsit többet, de elvileg megoldható, bár ilyen e2e tesztet még tényleg sosem csináltam githubon.

ghost commented 6 years ago

Sikerült közben eljutni addig, hogy ez megy localhoston:

var client = new E2EClient("http://localhost:3333");

describe("test", function() {
    it("does some tests on the remote web application", function(next) {
        client.load("/", function (contentWindow, path){
            expect(path).to.be("/");
            expect(contentWindow.document.body.innerHTML).to.be("hello world");
            next();
        });
    });
});

a szervert így indítom, de lehet php vagy bármi egyéb is.

var express = require("express");
var app = express();

app.get("/", function(req, res){
  res.send("hello world");
});

app.listen(3333);

Igazából még CORS-ra sem volt szükség, tehát nem kell belenyúlni a kódjába az oldalnak. Elég kikapcsolni a security-t a Chrome-ban egy flag-el.

Egyelőre nem tudom, hogy hogyan tudok 2 process-t indítani Travis-el, szóval nem biztos, hogy meg tudom oldani, hogy a github is futtassa a tesztet amikor push-olja a commit-et valaki. Localhost-ban megpróbáltam bash-el server & test -et, de a szerver nem exit-el, és nem vagyok benne biztos, hogy lefut e egyáltalán a teszt vele párhuzamosan. Ha igen, akkor csak le kell lőni az express-t, ha végzett a teszt, és egyébként php + apache-al talán nem lesz ilyen gond.

ghost commented 6 years ago

Egyelőre kivittem az ezzel kapcsolatos munkát külön repo-ba: https://github.com/inf3rno/e2e-client Amennyire kell, menni fog a hétvégére. A Travis-t egyelőre hanyagolom, fontosabb, hogy menjen stabilan a cucc localhost-on külön szerver és külön teszt indítással. API szempontjából valami ilyesmire kell számítani, de még alakul:

describe("Google", function() {
    it("finds a wikipedia page for the Rembrandt keyword", async function() {
        const doc = await client.load("http://www.google.com");
        await client.gettingVisible("body");
        expect(doc.title).to.be("Google");
        const input = client.find("input[type=text]");
        expect(client.isVisible(input)).to.be.ok(); 
        client.fill(input, "rembrandt van rijn");
        await client.gettingVisible("button[name=btnG]");
        await client.tick(1000);
        expect(client.containsText("ol#rso li:first-child", "Rembrandt - Wikipedia");
    });
});

Valszeg az alap rendszer csak néhány dolgot fog tartalmazni, aztán lehet majd jquery-vel vagy ilyesmivel megoldani a selectorokat és az "is visible", stb. jellegű dolgokat. Tulképp csak navigation és polling/mutationObserver (a "getting visible"-höz), ami máshol még nem lett megoldva, minden más mehet külső libből hozzá valami pluginnel.

ghost commented 6 years ago

Közben iframe-ről váltottam child window-ra, mert az iframe-re annyi féle clickjacking védelem van, hogy jobb kerülni, ha hosszú távon valami általános teszt rendszert akarok csinálni. Egyelőre Chrome-ban működik --disable-web-security-vel a navigáció. Kipróbáltam egy teszt szerverrel a Firefox-ot, hogy CORS header-el megoldható e, de valamiért nem alkalmazza a kiküldött header-eket a böngésző, és sír a cross-origin hozzáférés miatt. Azt hiszem megyek Chrome-al tovább, valszeg ebben a projektben elég lesz csak egy böngészőre tesztelni, ha nem AJAX-os jellegű lesz a fórum, hanem sima HTML, és csak űrlapokat kell küldeni a tesztekben, meg linkeket követni. A kérdőjeles részek a navigációban és a linkek követésénél vannak, szóval ha azok megvannak, onnantól már biztosan tudom, hogy minden más működni fog, és szinte csak sugar syntax-ot kell csinálni. Ezeket igyekszem ma és holnap letudni. Onnantól, hogy megvannak, gyakorlatilag már lehet e2e tesztelni, bár még elég rondák lesznek a tesztek sugar syntax nélkül.

Nem tudom, hogy írtam e már, de a klasszikus cucumber/gherkin-es feature fájl írásos BDD-t inkább hanyagolnám, és szerintem helyette írjuk majd úgy a tesztjeinket, hogy egy-egy feature meglétére és egy-egy scenario-ra koncentráljanak, amit a mocha describe és it függvényeinél a labelbe írunk majd bele röviden. Esetleg lehet commentben issue számra hivatkozni vagy hosszabban kitárgyalni, hogy mit tesztelünk. Egy másik lehetőség, hogy csinálunk wiki paget a feature-ökről és arra hivatkozunk a tesztnél. Majd ha megvagyok a test lib-el, akkor utána ezt megtárgyalhatjuk, hogy hogy legyen, esetleg akár elkezdhetjük itt és most.

ghost commented 5 years ago

Alakul a teszt rendszer. Egyelőre valami ilyesmi a low level API:

const expect = require("chai").expect;
const e2e = require("e2e-testing");

describe("an e2e test", function () {

    let window, navigator, interactor;

    before(function () {
        ({window, navigator, interactor} = e2e.openWindow());
    });

    it("should load google.com", async function () {
        await navigator.load("https://www.google.com");
        const searchButtonLegend = window.document.forms["f"]["btnK"].value;
        const isGoogleInTheLegend = searchButtonLegend.indexOf("Google") != -1;
        expect(isGoogleInTheLegend).to.equal(true);
    });

    it ("should throw navigation error by an unregistered domain", async function (){
        let wasErrorThrown = false;
        try {
            await navigator.load("http://www.qqqqqqqqqqq.net/");
        }
        catch (error){
            wasErrorThrown = true;
        }
        expect(wasErrorThrown).to.equal(true);
    });

    after(function () {
        e2e.closeWindow(window);
    });
});

Holnap még agyalok rajta egy sort, hogy hogyan lehetne megcsinálni az interactor részét, ami a linkre kattintást, ilyesmit köti össze a navigációval, de valószínűleg pár órás munka lesz. Szóval elvileg holnap este kijön a v0.1 a teszt rendszerből, ami ilyen viszonylag alacsony szintű lesz, aztán onnantól lehet használni. A fenti magas szintű API-hoz még sok munka kellene, de ha arra várunk, akkor sosem leszünk kész az oldallal. Később majd lehet upgradelni a függőségeket, meg esetleg egyszerűsíteni a meglévő teszteket, ahogy fejlődik majd a teszt rendszer, de még egy jó darabig visszafele kompatibilis lesz, úgyhogy az sem lesz annyira fontos.

Az assertion lib egyelőre chai + expect, de tőlem lehet bármi más is, lényegtelen. Amihez most ragaszkodok az a mocha és a karma.

ghost commented 5 years ago

Felszórtam a tesztes repoba a v0.1.0-t. https://github.com/inf3rno/e2e-testing A Travis nem akarja az igazságot, küldtem be nekik issue-t, hátha sikerül megjavítani, és lesz kint ilyen build passing felirat. Egyelőre még pre-alfa vagy minek mondjam, biztosan lesznek még módosítások rajta. Viszont ahhoz, hogy elkezdjek vagy elkezdjünk tesztet írni az oldalhoz, már kezdésnek jó. Holnap ránézek erre a repo-ra, hogy hogyan tudnám beletenni a tesztelést.

ghost commented 5 years ago

Az e2e teszt rendszerrel kapcsolatban már közelít a v0.2, amivel már hagyományos HTML oldalakat űrlap küldéssel meg link követéssel egész könnyen lehet tesztelni:

const expect = require("chai").expect;
const e2e = require("./e2e");
const navigator = e2e.openWindow({
    silent: true
});

describe("cross-origin, cross-frame communication", function () {

    it("should search using google", async function () {
        const searchPage = await navigator.load("https://www.google.com");
        const searchInput = searchPage.querySelector("input[type=text]");
        expect(searchInput != null).to.equal(true);
        searchInput.value = "rembrandt van rijn";
        const searchForm = searchInput.closest("form");
        const resultsPage = await navigator.submit(searchForm);
        expect(resultsPage.documentElement.innerHTML.indexOf("Rembrandt - Wikipedia") !== -1).to.equal(true);
    });

    after(function () {
        navigator.closeWindow();
    });
});

Az előző teszt példa egyébként geolocation függő, pl Travis-nál nem ment át, mert Koreában nincs Google a keresés gombon, meg az űrlap küldéssel nem is próbálkoztam benne, mert nagyon fapados lett volna. Azóta már stabil ez a része is a dolognak, egyedül a fájl csatolás nincs még meg, de megoldható az is. A github repo az aktuálisat mutatja, az npm repo majd 0.2-nél frissül. Van még vagy 30 nyitott issue fejlesztésre, de a 0.2-höz már csak könnyebbek, a nehezebbek későbbi milestone-ban vannak. Ha megvan a release, akkor lassítok azzal a projekttel, hogy több energiát tudja erre fordítani, mert ahogy látom nagyon belassultak a dolgok itt.

ghost commented 5 years ago

Szerintem ezzel az lesz, hogy átrakom a nem annyira fontos issue-k egy részét a 0.2.1-be, és kihozom korábban a 0.2.0-t, hogy tudjunk teszteket írni az npm-ről telepített változattal. Nem szívesen másolnám a forrást github-ról csak azért, hogy tudjuk használni a friss kódot.