// add.js
module.exports = function add(a, b) {
  return a + b;
};npm install --save-dev gtgt --bdd *-spec.js// add-spec.js
var add = require('./add');
describe('addition', function () {
  it('adds 2 numbers', function () {
    console.assert(add(2, 3) === 5);
  });
});gt --bdd add-spec.jsgt --bdd -t "add 2 numbers" *-spec.jsрезультаты тестов
покрытие кода
npm install --save-dev pre-git"pre-commit": "npm test"npm install --save-dev karma-coveragepreprocessors: {
    '*.js': 'coverage'
},
reporters: ['progres', 'coverage']покрытие кода тестами в GT по умолчанию
code-coverage / index.html
{
  "/Users/kensho/git/quick-testing/add.js": {
    "path": "/Users/kensho/git/quick-testing/add.js",
    "s": {
      "1": 1,
      "2": 1
    },
    "b": {},
    "f": {
      "1": 1
    },
...каждая строка кода
каждое условие
каждая функция
code-coverage.json
Данные для документации, простой код,
автоматический апгрейд версий
1 пример "стоит" 10 страниц текста
/**
 * Creates an array with all falsey values removed. 
 * The values `false`, `null`,
 * `0`, `""`, `undefined`, and `NaN` are falsey.
 *
 * @static
 * @memberOf _
 * @category Array
 * @param {Array} array The array to compact.
 * @returns {Array} Returns the new array of filtered values.
 * @example
 *
 * _.compact([0, 1, false, 2, '', 3]);
 * // => [1, 2, 3]
 */
function compact(array) { ... }/**
 * Creates an array with all falsey values removed. 
 * The values `false`, `null`,
 * `0`, `""`, `undefined`, and `NaN` are falsey.
 *
 * @static
 * @memberOf _
 * @category Array
 * @param {Array} array The array to compact.
 * @returns {Array} Returns the new array of filtered values.
 */
function compact(array) { ... }lodash.js
/**
 * Creates an array with all falsey values removed. 
 ...
 */
function compact(array) { ... }lodash.js
/**
 * @example compact
 */
it('removes falsy values', function () {
  assert(_.compact([0, 1, false, 2, '', 3]) === [1, 3, 3]);
});compact-spec.js
/**
 * @example compact
 */
it('removes falsy values', function () {
  assert(_.compact([0, 1, false, 2, '', 3]) === [1, 3, 3]);
});compact-spec.js
xplain lodash.js lodash-spec.js_.compact([0, 1, false, 2, '', 3]); // [1, 3, 3]/**
 * @example compact
 */
it('removes falsy values', function () {
  assert(_.compact([0, 1, false, 2, '', 3]) === [1, 3, 3]);
});compact-spec.js
xplain lodash.js lodash-spec.js -o README.md`_.compact` removes ...
### removes falsy values
    _.compact([0, 1, false, 2, '', 3]); // [1, 2, 3]README.md
(function foo(a, b) {
  if (a === 42 && b === 20) {
    return baz(a) || 100;
  } else {
    doSomething(a, b);
    doSomethingElse(a + b, b - a);
  }
}(100, 40));function isCondition(a, b) {
  return a === 42 && b === 20;
}
function compute(a) {
  return baz(a) || 100;
}
function foo(a, b) {
  if (isCondition(a, b)) {
    return compute(a);
  }
  doSomething(a, b);
  doSomethingElse(a + b, b - a);
}
foo(100, 40);function add(a, b) { return a + b }
// cyclomatic = 1
// halstead volume = 2function abs(a) {
  return a >= 0 ? a : -a
}
// cyclomatic = 2
// halstead volume = 3CodeClimate.com
плохо
хорошо
{
  "name": "my app",
  "version": "1.0.0",
  "dependencies": {
    "foo": "0.5.0",
    "bar": "0.1.0"
  }
}{
  "name": "my app",
  "version": "1.0.0",
  "dependencies": {
    "foo": "0.5.0",
    "bar": "0.1.0"
  }
}foo: 0.5.1, 0.5.2, 0.6.0
bar: 0.2.0, 0.2.1, 1.0.0,
1.0.1
Можно ли перейти на foo@0.6.0 и bar@1.0.1 ?
Никто не знает ...
Установить каждую новую версию
Прогнать все наши тесты
Если
Все тесты работают - использовать новую версию
Что-то перестало работать - оставаться на той же версии
Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)Что дальше?
npm install --save ravenvar client = new raven.Client(
    'https://<key>:<secret>@app.getsentry.com/<project>');// typical AngularJS unit test
describe('typical test', function () {
    var $rootScope, foo;
    beforeEach(function () {
        angular.mock.module('A');
        // other modules
    });
    beforeEach(inject(function (_$rootScope_, _foo_) {
        $rootScope = _$rootScope_;
        foo = _foo_;
    }));
    it('finally a test', function () {
        $rootScope.$apply(); // for example
        expect(foo).toEqual('bar');
    });
});ngDescribe({
    modules: 'A',
    inject: ['$rootScope', 'foo'],
    tests: function (deps) {
        it('finally a test', function () {
            deps.$rootScope.$apply();
            expect(deps.foo).toEqual('bar');
        });
    });
});AngularJS testing library kensho/ng-describe
+ 1000 downloads / month
слайды: slides.com/bahmutov
блог: glebbahmutov.com/blog/tags/testing
код: github.com/bahmutov
твиттер: @bahmutov