Testing – Testing javascript – We are ignorant



Testing – Testing javascript – We are ignorant

0 0


js-testing


On Github dawehner / js-testing

Testing

  • Who tests stuff?
  • Manual testing?
  • Simpletest?
  • PHPUnit?
  • Behat?
  • Why do you not do it?

Testing javascript

Daniel Wehner

  • Drupal Core contributor
  • Chapter Three, Tag1 Consulting ...
  • Curios person

We are ignorant

* The daily life is hard as we are incredible stupid.
It worked when I tested it Things work on one computer but not on the other, maybe some additional stuff has to be installed / build?
It worked last month Things that used to work break at some point. We want to reduce the amount of them ...
The code is too slow, let's fix that We often write really slow code, which is sort of fine, as most of the time we don't need to scale. At some point though we potentially need to scale/fix that code. How do we ensure that things still work?

More problems

  • Sites get more complex
  • New members comes into the team
  • Everyone wants to be able to sleep at night
* Sites get more and more complex over time * Not a single person knows everything ... how do you document how stuff is supposed to work? ... for when members come into a team there should be a way for them to figure it out. * Finally we want to not worry about the state, everything should be nice. * Other points: You should be able to iterate more quickly when you no, nothing breaks.

Let's test

End-to-end testing

Unit testing

End-to-end testing tests the entire system, not just a small aspect of it.

End-to-end testing

  • Behat + Selenium
  • CasperJS
  • Drupal BrowserTestBase | JavascriptTestBase (new in Drupal 8.1)
Behat: documentation of the test, client language => tests for free ;;; CasperJS: in JS => easier testing of JS ;;; There is plenty of documentation out there for the other ones. BrowserTestBase|JavscripTestBase: Tools by Drupal ... written in PHP; Sets up the complete Drupal + the module you want to test. Focus on JTB, as it will be useful when you write modules; port stuff.

Browser Test

  • Based upon PHPUnit / Mink
  • New since Drupal 8
  • Execute via command line or PHPStorm
* Installs a fresh drupal * Installs some modules * advantage over simpletest: you can run it via phpstorm ...
Browser Test
// modules/example/tests/src/Function/ExampleTest.php

class ExampleTest extends BrowserTestBase {

  public static $modules = ['example'];

  /**
   * Tests basic page test.
   */
  public function testGoTo() {
    $account = $this->drupalCreateUser();
    $this->drupalLogin($account);

    // Visit a Drupal page that requires login.
    $this->drupalGet('test-page');
    $this->assertSession()->statusCodeEquals(200);

    // Test page contains some text.
    $this->assertSession()->pageTextContains('Test page text.');
  }
}

Basic actions

  • ::setup()
  • drupalGet
  • drupalPostForm
  • clickLink

More useful stuff

  • drupalCreateUser drupalLogin drupalLogout
  • drupalCreateNode
use \Behat\Mink\WebAssert;

$this->webAssert = new WebAssert($this->getSession());
$this->webAssert->statusCodeEquals(200);
$this->webAssert->pageTextContains('The content was saved.');
$this->webAssert->elementsCount('css', 'div.views ul li', 3);
$this->webAssert->fieldExists('title[0][value]');
$this->webAssert->checkboxNotChecked('published');

JavascriptTestBase

Static sites so far ;; Want to test javascript ;; You need sort of a browser ;; We use phantomjs ;; based upon webkit, is headless for itself ;; Still take screenshots

JavascriptTestBase

// modules/toolbar/tests/src/
//   FunctionalJavascript/ToolbarIntegrationTest.php

class ToolbarIntegrationTest extends JavascriptTestBase {
  public static $modules = ['toolbar', 'node'];

  public function testToolbarToggling() {
    $this->drupalLogin($admin);
    $this->drupalGet('< front>');
    $this->assertElementVisible('#toolbar-link-admin_content');
    $this->click('#toolbar-item-administration');
    $this->assertElementNotVisible('#toolbar-link-admin_content');
  }
}
Blog post about running javascript tests

Run them

phantomjs --ssl-protocol=any --ignore-ssl-errors=true \\
  vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768
SIMPLETEST_BASE_URL="http://drupal.loc"
SIMPLETEST_DB="sqlite://localhost/sites/default/files/.ht.sqlite"
$ sudo -u _www ./vendor/bin/phpunit -c core core/modules/toolbar/\\
tests/src/FunctionalJavascript/ToolbarIntegrationTest.php
Time: 10.25 seconds, Memory: 5.50Mb

Run them all

sudo -u _www ./vendor/bin/phpunit -c core modules/example/tests/src

Problems with end to end testing

Problems with end to end testing

  • Tests too much
  • Slow
  • Error prone
  • Feedback cycle

Unit testing

For a given input expect a given output.

Tools

  • Qunit
  • Jasmine
  • Mocha
  • Karma
  • Chai
  • Tape
  • more ...
  • even more ... ?

Step 0: Think about the problem

TodoTxt
x 2016-04-18 Finish JS testing presentation @dcampEs +js +testing

Step 1: Define a test

// test/todo-parser.js
var assert = require('chai').assert;
var TodoParser = require('../todo-parser');

describe('todo-parser', function() {
  describe('parse', function() {
    it('parses a simple string', function() {
      var todo = TodoParser.parse('hello');
      assert.isOk(todo);
      assert.equal('hello', todo.text);
    });
  });
});

Step 2: Make the test pass

// todo-parser.js
TodoParser = {
  parse(string) {
    var text = string;
    return new Todo(text);
  }
};

// todo.js
Todo = function(text) {
  this.text = text;
};
  

Step 3: Write another test

    it('parse string with priority', function() {
      var todo = TodoParser.parse('(A) hello');
      assert.isOk(todo);
      assert.equal('hello', todo.text);
      assert.equal('A', todo.priority);
    });

Step 4: Fix the code

Step 5: Refactor

Test driven development (TDD)

This kind of testin gis called TDD ...

Test driven development (TDD)

  • Code is testable
  • Code is tested
  • Code is easy to use
  • Less premature optimization
  • Uncle Bob

Mocha

  • Testing framework
  • No assertions/mocking
  • Runs in the shell
{
  "name": "My project",
  "devDependencies": {
    "mocha": "^2.4.5",
    "chai": "^3.5.0"
  },
  "scripts": {
    "test": "node_modules/mocha/bin/mocha",
    "test-watch": "node_modules/mocha/bin/mocha --watch"
  }
}
--watch
-R --reporter min,json,xunit,nyan

Chai

  • Assertion library
  • Different flavours:
  • Expect
    expect(todo.text).to.equal('hello');
    expect(todo.priority)
      .to.not.equal('A');
    expect(todo)
      .to.have.property('text')
      .and.not.equal('hola');
    
  • Should
    todo.text.should.equal('hello');
    todo.priority.should.not.equal(A');
    todo.should.have.property('text');
    
  • Assert
    assert.equal('hello', todo.text);
    assert.notEqual('A', todo.priority);
    assert.property(todo, 'text');
    

Mocking

  • Fake external code (libraries, databases, etc.)
  • Just test your code
  • Shows code with too many dependencies
  • Sinon is a good library for that

Your projects

  • Start with testing now
Start with testing now, there is no excuse. Behat/CasperJS are good tools. Module authors should use BTB/JTB for their stuff.

Drupal

  • You can start using it now. Just add a package.json with the dependencies, run npm install and do it.
  • There is a core issue ...
  • Many open questions:
    • Do we want those testing libraries?
    • Do we want to run them in the browser?
    • Other ideas

¡Gracias!

Questions?

Testing Who tests stuff? Manual testing? Simpletest? PHPUnit? Behat? Why do you not do it?