Gleb Bahmutov PRO
JavaScript ninja, image processing expert, software quality fanatic
// add.js
module.exports = function add(a, b) {
return a + b;
};
npm install --save-dev gt
gt --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.js
gt --bdd -t "add 2 numbers" *-spec.js
результаты тестов
покрытие кода
npm install --save-dev pre-git
"pre-commit": "npm test"
npm install --save-dev karma-coverage
preprocessors: {
'*.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 = 2
function abs(a) {
return a >= 0 ? a : -a
}
// cyclomatic = 2
// halstead volume = 3
CodeClimate.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 raven
var 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
By Gleb Bahmutov
В этом докладе я покажу самые последнии идеи для достижения надежного программного обеспечения для веб: от data-coverage (вместо code-coverage) до тестирования недоступого кода (например, внутри private JavaScript closures), от минимизации boilerplate до тестирования веб-приложений без помощи браузеров; эти решения помогут быстро и дешево достичь высокого уровня качества.
JavaScript ninja, image processing expert, software quality fanatic