Rant: de ce nu se practică testarea codului?

Probabil veți fi tentați să ziceți: „e greu să scrii teste (bune)!”. Ia fiți atenți aici.

De la prânz stau să-mi setez un env de test pentru povestea de care am zis aici. Cam prin ce am trecut:

  • Instalat gulp-jasmine (pentru a-l rula în consolă);
  • Plugin-ul ăsta nu știe să încarce și vendori (nu pot face bundle și la backbone, jquery și underscore pentru că sunt bundled de altcineva)
  • Am găsit gulp-jasmine-ceva, care știe să încarce vendori dar nu știe alte căcaturi;
  • Răscolit internetul și am găsit cazuri asemănătoare cu ce vreau eu. Am nevoie de karma! Yay.
  • Instalez și Karma, fac un karma.conf, și pierd vreo jumătate de oră să-mi dau seama că frameworks: ['jasmine'] ar trebui să fie, de fapt, frameworks: ['karma-jasmine'];
  • Totul e minunat, runnerul funcționează, intru pe http://localhost:9876/ șiii… Uncaught TypeError: Cannot read property 'extend' of undefined (doar nu credeam că va funcționa așa repede!)

În acest moment sunt pe punctul de a renunța la teste rulate în consolă și mă gândesc serios să le rulez în jasmine în browser…

Mai demult voiam să fac set-up pentru testele de WP. Și acolo era o încurcătură atât de încurcată încât aproape renunțasem după câteva ore bune (în final reușisem, dar la următorul proiect, când am avut nevoie… n-am reușit să-l fac rapid, deci iar m-am chinuit…).

PHPUnit? Pe versiunea veche a documentației nu scria nicăieri că bootstrap === autoload.php. Am pierdut și acolo câteva ore pentru a-mi da seama de asta. Când am reușit, cel mai simplu test rula în vreo trei secunde și am avut nevoie de mai bine de un an să-mi dau seama că problema era de la xdebug.


Doar mie mi se pare obositor (și un pic arcane) tot procesul de set-up?


Când sunteți nervoși că nici un coleg nu testează codul, încercați să-i întrebați: „ai reușit să faci runnerul să meargă?”

8 Likes

Paștele mă-sii de treabă, azi a fost o zi productivă de nu s-a putut! Am avut nevoie de doar 8h pentru a face un rahat de set-up pentru un test-runner. Yay me!

Versiunea 0.0.1 a aplicației are 50 linii și am avut nevoie de un pic peste o oră de la momentul New File până când i-am dat-o clientului la testat.

Versiunea 1.0.0 am decis să o fac „ca la carte”: rafactor cu module, testată etc, mai ales că mă aștept să vină modificări și adăugiri în viitorul apropiat. Opt ore mai târziu nu am scris nici măcar un caracter la refactor, în schimb m-am distrat de minune cu Karma. Pentru curioși, iată karma.conf:

module.exports = function(karma) {
  karma.set({
    files: [
      'bower_components/jquery/dist/jquery.min.js',
      'bower_components/underscore/underscore.js',
      'bower_components/backbone/backbone.js',
      'src/**/*.js',
      'specs/**.js'
    ],

    browsers: ['PhantomJS'],

    // logLevel: karma.LOG_DEBUG,

    singleRun: false,
    autoWatch: true,
    colors: true,

    frameworks: ['jasmine', 'browserify', 'commonjs'],

    plugins: [
      require('karma-jasmine'),
      require('karma-browserify'),
      require('karma-commonjs'),
      require('karma-phantomjs-launcher'),
      require('karma-beep-reporter'),
    ],
    reporters: ['beep', 'dots'],
    preprocessors: {
      'src/**/*.js': ['commonjs'],
      'specs/**/*.js': ['browserify'],
    }
  });
};

Și ce e în package.json:

"devDependencies": {
  "browserify": "^13.0.0",
  "commonjs": "0.0.1",
  "gulp": "^3.9.1",
  "gulp-livereload": "^3.8.1",
  "gulp-rimraf": "^0.2.0",
  "gulp-util": "^3.0.7",
  "jasmine": "^2.4.1",
  "jasmine-core": "^2.4.1",
  "karma": "^0.13.22",
  "karma-beep-reporter": "^0.1.4",
  "karma-browserify": "^5.0.3",
  "karma-commonjs": "0.0.13",
  "karma-coverage": "^0.5.5",
  "karma-jasmine": "^0.3.8",
  "karma-phantomjs-launcher": "^1.0.0",
  "phantomjs": "^2.1.3",
  "phantomjs-prebuilt": "^2.1.7",
  "vinyl-source-stream": "^1.1.0",
  "watchify": "^3.7.0"
}
4 Likes

Credeam că am scris, dar se pare că am uitat. Deh…

Problema a fost la modul în care Karma se pupă cu NPM 3 și anume că nu găsea plugin-urile. În toate documentațiile, array-ul plugins constă în string-uri; se folosește require doar dacă vrei să încarci un plugin custom.

Și a durat ceva până m-am prins de toată povestea asta :slight_smile:

2 Likes

Daca programezi in javascript si codul poate fi citit, respectiv ruleaza cu node e un test destul de solid. Pentru orice mai complex iti recomand un tester full-time sau cel putin un sistem de Continous Integration cu testare integrata.

Păl eu nu vreau să știu dacă rulează ci dacă rulează bine.

Pentru a putea rula un ci trebuie să scriu teste. Pentru a scrie teste trebuie să am… Ai ghicit, un un sistem de rulat teste funcțional :slight_smile:

2 Likes

Asta cu testele trebuie observată în context. Dacă contextul îți permite timp de teste, poate merită să treci prin tot procesul asta de setup, dacă nu, s-ar putea să fie doar o frustrare care îți taie din entuziasm și prelungește durata de livrare.

Mie mi-ar plăcea să scriu mai multe teste, dar clientul vrea chestia ce mi-o cere repede, pentru că a promis-o mai departe către clienții lui și oricât i-ai explica și ar înțelege valoarea ideii de testare, cineva pe lanțul ăsta developer - client - client final va dori ceva repede care să meargă și nu îl va interesa cum ai ajuns acolo.

De-aia e bine, ca din când in când, să mai ne punem o pălărie de client/user final pe cap, ca să luăm anumite decizii.

1 Like

@iamntz Te inteleg perfect, acceasi problema o am si eu. Cu PHPUnit, Behat & Co parca ai sanse sa o scoti la capat ceva mai usor. Cand vine vorba de Node parca tot ecosistemul e impotriva ta cand esti la inceput (eu m-am chinuit jumatate de zi sa instalez dependintele pentru un proiect facut de cineva acum 6 luni). Cu testarea aparent e si mai rau.
Tot ce pot sa zic e ca repetitia e mama invatarii. Cel mai relevant exemplu din experienta e folosirea Xdebug - local, cu vagrant, remote, etc) in loc de var_dump/die.
Despre teste o sa vorbesc cand o sa fac TDD pe bune, din pacate e inca la stadiul de nice-to-have.

3 Likes

Orice setup de infrastructura este complicata daca nu ai mai facut-o in prealabil. Dar odata facut si documentat - sau de ce nu automatizat - cele opt ore de acum iti vor fi 8 minute data viitoare.
Can privesti lucrurile in perspectiva, un setup de infrastructura de teste care dureaza 8 zile (da, am zis zile) este o investitie nesemnificativa daca datile viitoare va costa doar 8 minute. Desigur scot cifre din burta acum…
Si chiar sa dureze 8 zile… Sa zicem ai un proiect care are o viata de 2 ani. 2 ani inseamna vreo 730 zile. 8 zile din 730 sunt aprox 1%. Pai nu merita o investitie de 1% pentru a avea o infrastructura solida de teste? WTF? Si fie 10-20% din proiect, tot merita! Siguranta ce iti aduce o suita de teste extinse este atata de mare, incat sacrificiul mentionat de tine este neglijabil.

6 Likes

Umm, nu.

Este o problema a JS-ului si comunitatii node care a interpretat complet gresit the unix philosophy

1 Like

Oh come on… please just stop…

Nu este vina comunitatii ca unele companii si-au promovat modulele JS si acum toata lumea le foloseste ca sunt bine indexate pe google sau o gramada de fanboys au scris articole “cum sa lingi inghetata lu’ [google/facebook/dropbox/airbnb/etc]”.

Step 1 - install good modules:

$ npm install tape tape-run browserify --save-dev

Step 2 - write a fucking test:

var test = require('tape');

test('a test', function (t) {
  t.ok(true);
  t.end();
});

Step 3 - run the fucking test:

$ browserify specs/**/*.js | tape-run

Daca vrei si autorun on save:

$ npm install nodemon --save-dev
$ nodemon --exec "browserify specs/**/*.js | tape-run" --watch specs/**/*.js  --watch src/**/*.js

De ce sa folosesti tape.

E usor sa critici din exterior, partea dificila este sa construiesti o solutie viabila cu o gramada de constrangeri.

Actions have reactions, don’t be quick to judge
You may not know the harships people don’t speak of
It’s best to step back, and observe with couth
For we all must meet our moment of truth

3 Likes

E o problemă aici, pentru că dacă azi e bun asta nu înseamnă că e bun și mâine. Ieri a fost bun mocha, azi e de rahat.

Ceea ce nu face decât să agraveze și mai mult problema uneltelor :slight_smile:

mocha a devenit popular pt. ca a fost folosit in express cel mai popular framework, tape era o alegere mai buna, dar “convenience over correctness”.

tape implementeaza conceptul Test Anything Protocol, care nu este deloc nou.

Originally developed for unit testing of the Perl interpreter in 1987.

Unele module sunt mai bune daca intelegi de ce fac ceea ce fac. Asta este o problema de perceptie, nu alocam timp ci cautam repede o solutie care consideram ca ne rezolva problema si dupa ii invatam si pe altii ca asa se face, cu toate ca uneori nu e cea mai buna optiune.

Ca titlul articolului “Do not learn the framework learn the architecture” => “Don’t learn karma / jasmine, learn how to test the code”.

dacă azi e bun asta nu înseamnă că e bun și mâine

Asta este un lucru bun daca tool-urile evolueaza, “change can be hard, but progress is always the best choice”.

3 Likes

toata lumea, o gramada de fanboys, unele companii ⊂ comunitate

Inteleg, folosesti node, insa unele lucruri sunt evidente, nu incerc sa trolez, just stating a fact.

1 Like