Main target of tests is to remove the difference between how it was designed and how it was developed.
Must performs its functions within an acceptable time
Must be useful
Nobody cares... But this cost to much - $60 billions in 2002 in USA
50% code coverage is really good
30% bugs can be fixed by tests
Must be readable as docs
Facts:
- You design your code
- You test your code
- You refactor your code
- Other people use your code
- It has bugs
Let's make life easier and write tests?
White box tests use internal structures
Black box tests check functionality without any knowledge of internal implementation
When you make screenshots or video recording of process it calls visual testing
Try to use code analyzers/linters:
- JSHint/JSLint
- Plato (complexity, sloc, errors and etc)
- Closuer Compiler
- CSS Dig
- ESPrima + ESTraverse
- Any code standarts
NB: use hooks to prevent adding legacy code
jQuery leaks watcher
var tmplCache = {};
function loadTemplate (name) {
if (!tmplCache[name]) {
tmplCache[name] = $.get('/templates/' + name);
}
return tmplCache[name];
}
$(function () {
var resultsList = $('#results');
var liked = $('#liked');
var pending = false;
$('#searchForm').on('submit', function (e) {
e.preventDefault();
if (pending) { return; }
var form = $(this);
var query = $.trim( form.find('input[name="q"]').val() );
if (!query) { return; }
pending = true;
$.ajax('/data/search.json', {
data : { q: query },
dataType : 'json',
success : function (data) {
loadTemplate('people-detailed.tmpl').then(function (t) {
var tmpl = _.template(t);
resultsList.html( tmpl({ people : data.results }) );
pending = false;
});
}
});
$('<li>', {
'class' : 'pending',
html : 'Идёт поиск…'
}).appendTo( resultsList.empty() );
});
resultsList.on('click', '.like', function (e) {
e.preventDefault();
var name = $(this).closest('li').find('h2').text();
liked.find('.no-results').remove();
$('<li>', { text: name }).appendTo(liked);
});
});Choose
your
adventure!
Large function
Change state
Wrong access
Organize your code before tests.
- Unit tests
- Functional testing
- Integration testing
- TDD
- BDD
Undestand this
Win this man inside you
Unit tests tell a developer that the code is doing things right; functional tests tell a developer that the code is doing the right things.
TDD and BDD are practices. TDD is about how it was developed and BDD is about how it was designed.
TDD is about how it was developed
BDD is about how it was designed
assertEquals(count, 42)it(count).should.be(42)QUnit tests results example:
Use frameworks? Well done. You got it!
Use the power, Look!
Use ES2015 module and classes abstraction
phantom.create(function (ph) {
ph.createPage(function (page) {
page.open('http://yahoo.com', function (status) {
page.evaluate(function () {
var el =
document.querySelector('input[title="Search"]');
el.value = 'github nightmare';
}, function (result) {
page.evaluate(function () {
var el = document.querySelector('.searchsubmit');
var event = document.createEvent('MouseEvent');
event.initEvent('click', true, false);
el.dispatchEvent(event);
}, function (result) {
ph.exit();
});
});
});
});
});yield Nightmare()
.goto('http://yahoo.com')
.type('input[title="Search"]', 'github nightmare')
.click('.searchsubmit');PhantomJS
NightmareJS
var $ = require('jquerygo');
// Add some default configs.
$.config.site = 'http://www.whitehouse.gov';
$.config.addJQuery = false;
// Go to the presidents page.
$.visit('/about/presidents', function() {
$.waitForPage(function() {
// Iterate through each span.field-content.
$('span.field-content').each(function(index, element, done) {
// Get the text of this element.
element.text(function(name) {
// Print the presidents name.
console.log(name);
done();
});
}, function() {
// We are done.
console.log('Presidents loaded!');
$.close();
});
});
})var async = require('async');
var $ = require('../lib/jquery.go.js');
// Add some default configs.
$.config.site = 'http://localhost';
$.config.addJQuery = false;
// Using the async.series with jQuery.go.
async.series([
$.go('visit', '/user'),
$('#edit-name').go('val', 'admin'),
$('#edit-pass').go('val', '123testing'),
$('#edit-submit').go('click'),
$.go('waitForPage'),
function(done) {
$('a[href="/user/logout"]').text(function(text) {
console.log(text);
done();
});
}
], function() {
console.log('You are logged in!');
$.close();
});- Travis
- Jenkins
- Teamcity
- Webpack
- Wraith
- Gemini
- GremlinsJS
before_capture: "javascript/global.js"
domains:
english: "http://www.bbc.co.uk/news"
screen_widths:
- 320
- 600
- 768
- 1024
- 1280
paths:
clickable_guide:
path: /entertainment-arts-27221191
selector: '.idt__news'
clickable_guide__after_click:
path: /entertainment-arts-27221191
selector: '.idt__news'
before_capture: 'javascript/local.js'rootUrl: http://yandex.com
gridUrl: http://selenium.example.com:4444/wd/hub
browsers:
chrome:
desiredCapabilities:
browserName: chrome
version: "45.0"
firefox:
desiredCapabilities:
browserName: firefox
version: "39.0"var gemini = require('gemini');
gemini.suite('yandex-search', function(suite) {
suite.setUrl('/')
.setCaptureElements('.main-table')
.capture('plain')
.capture('with text', function(actions, find) {
actions.sendKeys(find('.input__control'), 'hello gemini');
});
});<script src="path/to/gremlins.min.js"></script>
<script>
gremlins.createHorde().unleash();
</script>- XSSMe (Firefox)
- SQLMe (Firefox)
- DevTools
- PageSpeed
- PageTest
- YSlow