«Если у вас нету тестов ...» – Часть I – Тестирование модулей



«Если у вас нету тестов ...» – Часть I – Тестирование модулей

1 0


dump-tests-slides

Слайды доклада про тестирование приложений на DUMP

On Github Zhigalov / dump-tests-slides

«Если у вас нету тестов ...»

Сергей Жигалов

function(words) {
    return '#' + words
        .split(/\s+/)
        .map(normalizeWord)
        .join('');
}

Это тоже удовольствие!

function() {
    var actual = hashTag('hello DUMP');

    actual.should.be.equal('#HelloDump');
}

Тесты - это продуктивно

Придает уверенности

Тесты - это продуктивно

Придает уверенности

Тесты - это продуктивно

Придает уверенности

Помогает рефакторить

Обновлять зависимости

Быть командой

Живая документация

Часть I

Тестирование модулей

Билдер хештегов

DUMP 2016              -> #Dump2016
Тестов много не бывает -> #ТестовМногоНеБывает
function hashTagGenerator(words) {
    return '#' + words
            .split(/\s+/)
            .map(normalizeWord)
            .join('');
}
function normalizeWord(word) {
    return word.charAt(0).toUpperCase() +
        word.toLowerCase().slice(1);
}
module.exports = hashTagGenerator;

nodejs.org

$ npm install mocha

app/
└── src
    └── hashTagGenerator.js
    └── ...
└── test
    └── hashTagGenerator-test.js
    └── ...
        
var hashTag = require('../src/hashTagGenerator.js');
 
describe('Hash tag generator', function () {
    it('should normalize words', function () {
        var actual = hashTag('hello DUMP');
 
        actual.should.be.equal('#HelloDump');
    });
});

chaijs

$ npm install chai
var chai = require('chai');
chai.should();
$ mocha test
  Hash tag generator
    ✓ should normalize words

1 passing (3ms)

как ребенок

А что, если...

it('should clean extra symbols', function () {
    var actual = hashTag('    #@mu-ha-ha!!!');

    actual.should.be.equal('#MuHaHa');
});
  Hash tag generator
    ✓ should start with #
    ✓ should concat words
    ✓ should normalize words
    1) should clean extra symbols

3 passing (13ms)
1 failing

1) Hash tag generator should clean extra symbols:

    AssertionError: expected '##@%mu-ha-ha!'
                    to equal '#MuHaHa'
    + expected - actual

    -##@%mu-ha-ha!
    +#MuHaHa
    
function hashTagGenerator(words) {
    return '#' + words
            .split(/\s+/)
            .map(normalizeWord)
            .join('');
}
function hashTagGenerator(words) {
    return '#' + words
            .split(/[^\wа-яё]/i)
            .map(normalizeWord)
            .join('');
}

... под другим углом

Часть II

Тетирование клиентского кода

DEMO

describe('Twitter signup', function () {
    it('should alert when enter `twitterok`', function () {
        inputTextTo($('#full-name'), 'twitterok');

        $('.notwitter').is(':visible').should.be.true;
    });
});
function inputTextTo($el, text) {
    $el.val(text).trigger('input');
}
function inputTextTo($el, text) {
    $el.focus();
    document.execCommand(
        'insertText', false, text);
}

<head>

<!-- подключаем стили Mocha -->
<link
    rel="stylesheet"
    href="./node_modules/mocha/mocha.css">

<body>

<!-- подключаем библиотеки -->
<script src="./node_modules/mocha/mocha.js"></script>
<script src="./node_modules/chai/chai.js"></script>
<!-- настраиваем Mocha -->
<script> mocha.setup('bdd'); </script>
<!-- подключаем файл с тестами -->
<script src="/form-test.js"></script>
<!-- элемент в котором будут результаты тестов -->
<div id="mocha"></div>
<!-- запускаем Mocha -->
<script> mocha.run(); </script>

DEMO

Автоматизировать?

PhantomJS

PhantomJS is a headless WebKit scriptable with a JavaScript API.

mocha-phantomjs

$ npm install -g mocha-phantomjs

Адаптируем запуск

<!-- запускаем Mocha -->
<script>
    window.mochaPhantomJS ?
        mochaPhantomJS.run() :
        mocha.run();
</script>
$ mocha-phantomjs twitter-signup.html
  Twitter signup
    ✓ should no error when input is empty
    ✓ should no error when input `teremok`
    ✓ should show error when input `twitterok`

  3 passing (14ms)
    

Часть III

Тестирование сценариев

Перейти на главную страницу https://github.com

⬇ В строке поиска набрать "Слайды тестирование DUMP"

⬇ Проверить что репозиторий есть в списке

WebdriverIO

$ npm install webdriverio
$ wdio config

⬇ wdio.conf.js

describe('GitHub', function () {
   it('search', function () {
      browser.url('http://github.com');
      browser.setValue('input[name="q"]',
                       'Слайды тестирование DUMP');
      browser.submitForm('form[action="/search"]');
      var repoName = browser.getText('h3.repo-list-name');
 
      repoName.should.be.equal('Zhigalov/dump-tests-slides');
   });
});
            wdio wdio.conf.js
        

DEMO

Запускайте чаще

В IDE

При сохранении файла

Перед коммитом и пушем (husky)

CI сервер ( TeamCity, drone.io, Travis CI, ...)

Travis CI

# .travis.yml

language: node_js
node_js:
    - "4.1"
// package.json

{
    "scripts": {
        "test": "mocha test"
    }
}

DEMO

Информировать команду

  • Письмо
  • SMS сообщение
  • Или как-то еще... ;)

Первый шаг

Пишите тесты сразу

Не убедил?

nock

var nock = require('nock');

nock('https://api.github.com')
    .get('/users/zhigalov')
    .query(true)
    .reply(200, {
        "name": "Sergey Zhigalov",
        "company": "Яндекс",
        "email": "sergey.zhigalov@gmail.com"
    });
var request = require('request');
var url = 'https://api.github.com/users/zhigalov';

request(url, function (error, res, body) {
    console.log(body);
});
{
    "name": "Sergey Zhigalov",
    "company": "Яндекс",
    "email": "sergey.zhigalov@gmail.com"
}

Тестирование - это:

приятно

удобно

рабочий код

удовольствие

уверенность

Спасибо!

speaker.should.deep.equal({
    face: ,
    name: 'Сергей',
    twitter: '@sergey_zhigalov',
    email: 'zhigalov@yandex-team.ru'
});
1
«Если у вас нету тестов ...» Сергей Жигалов