Money 1st. Онлайн программирование.

Я начинаю новый проект, о котором уже упомянул в прошлом сообщении и, на первых порах, собираюсь весть достаточно подробное описание процесса программирования. В первую очередь для того, чтобы самому разбораться в новых технологиях (TDD & XP), во-вторых - создать полезный артефакт, для коллег.

Кроме того, я надеюсь, что кому-то моя писанина поможет лучше понять, что происходит в голове программиста при написании программы.

2012.07.10 23:51

Итак, у меня есть задача и небольшой список пожеланий (User Stories)

  • Как пользователь, я хочу добавлять новые счета, чтобы получить их полный список
  • Как пользователь, я хочу фиксировать поступление денег на счета, чтобы понять сколько я зарабатываю.
  • Как пользователь, я хочу отмечать источник получения денег, чтобы понять как я их зарабатываю.
  • Как пользователь, я хочу фиксировать расходы, чтобы знать сколько я трачу.
  • Как пользователь, я хочу отмечать расходы разными тегами, чтобы понять на что я трачу деньги.

Начать естественно лучше с первой.

Нужно создать счет (Acсount), который содержит информацию о собственном названии, некоторый комментарий, текущий остаток и валюту счета.

Требование к валюте может показаться преждевременным, но мне кажется, что очевидные шаги не стоит откладывать на потом. Лучше записать еще одно пожелание:

  • Как пользователь, я хочу использовать разные валюты, чтобы (здесь у меня проблема с формулировкой, надо воскликнуть что-то вроде: "Это же очевидно!")

К моменту, когда я дописал этот комментарий наступила полночь.

2012.07.11 00:08

Я прочитал первую часть книги о TDD - Test Driven Development: By Example by Kent Beck и теперь хочу проделать аналогичный путь, для того, чтобы самому разобраться в методике и потом рассказать о ней своим коллегам на родном языке и на примере конкретного приложения.

Мой первый тест выглядит так

  1. module("Account tests");
  2.  
  3. test("Account constructor", function()
  4. {
  5. var a = new Account();
  6. ok(true); //без этой строки qUnit не пройдет тест даже если класс определен
  7. });

И он естественно не проходит по причине того, что класс Account не определен. В данном случае код для исправления ошибки очевиден, как собственно и должно быть в большинсте случаев при использовании TDD.

  1. function Account(){}

Теперь можно понемногу наполнять класс, для чего надо создать следующий тест, точнее изменить уже существующий.

  1. test("Account constructor", function()
  2. {
  3. expect(4);
  4. var a = new Account();
  5. equal(a.hasOwnProperty('name'), true, 'Check property "name"');
  6. equal(a.hasOwnProperty('note'), true, 'Check property "note"');
  7. equal(a.hasOwnProperty('amount'), true, 'Check property "amount"');
  8. equal(a.hasOwnProperty('currency'), true, 'Check property "currency"');
  9. });

В этот момент в моей голове возникает примерно такой поток мыслей
- мне нужен уникальный идентификатор для каждого счета
- в качестве ключей я традиционно использую md5-hash getKey()
- надо написать тест, который проверяет работу getKey() - является ли возвращяемое значение md5-хешем?
- для проверки была бы полезна функция isMd5(), которая проверят строку с помощью регулярного выражения
- для нее тоже надо написать тест
- это все дальше уводит меня от решаемой в настоящее время задачи, что конечно не соответсвует концепции TDD. или я ошибаюсь и TDD работает именно так?
- описание процесса программирования - это отличный генератор контента

Надо вернуться к той задаче, которая делает невалидным мой последний тест.

  1. function Account()
  2. {
  3. var self = this;
  4. var options = {name: 'Новый счет', note: '', amount: 0.0, currency:'RUR'};
  5. $.extend(this, options);
  6. }

Теперь буду разбираться с генератором уникального идентификатора. Но шаги сделаю чуть крупнее, потому как для меня они очевидны.

  1. test("MD5", function()
  2. {
  3. var key = getKey();
  4. ok(true);
  5. });
  1. function getKey()
  2. {
  3. return $.md5('' + new Date() + Math.random());
  4. }

Вторая итерация

  1. test("MD5", function()
  2. {
  3. expect(4);
  4. equal(ismd5('not md5 hash'), false, "wrong md5 hash");
  5. equal(ismd5('0123456789abcdef0123456789abcdef'), true, "right md5 hash");
  6. equal(ismd5(getKey()), true, "getKey() return value");
  7. notEqual(getKey(), getKey(), "getKey() unique test");
  8. });
  1. function ismd5(hash)
  2. {
  3. return /^[0-9a-f]{32}$/i.test(hash);
  4. }

Теперь надо добавить пару тестов для генерации уникального id у счета

  1. ...
  2. equal(a.hasOwnProperty('id'), true, 'Check property "id"');
  3. ok(ismd5(a.id), "Account id is md5 hash");
  4. ...

и поправить класс, чтобы пройти их

function Account()
{
  var self = this;
  var options = {name: 'Новый счет', note: '', amount: 0.0, currency:'RUR'};
  $.extend(this, options);
  self.id = getKey();
}

На этой мажорной ноте (она же зелёная!) я хочу закончит на сегодня и как следует обдумать вопрос насколько глубоким долно быть юнит-тестирование?

2012.07.11 01:19

Версия на GitHub

Читайте в блоге

Python. Рекурсивное копирование папки с заменой поддиректорий
Funky Cache
PHP. Преобразование таблицы в картинку. Создание информеров.

Комментарии:

Войдите на сайт, чтобы оставить комментарий