Скромная дискуссия по мотивам моей вчерашней публикации на тему прогнозирования времени на разработку, в очередной раз пробудила во мне ощущение некоей неправильности на тему использования чисто умозрительного подхода к разбиению истории на задачи. На мой взгляд, когда мы пишем задачи в списке, даже когда мы используем объектную или функциональную терминологию, мы не вполне представляем себе все модули с кодом, которые нам потребуется разработать или доработать.


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


Как система, я хочу отправить на проверку KYC сервису персональные данные пользователя


И список задач к ней:


  1. Реализовать получение персональных данных пользователя из локальной базы
  2. Реализовать создание папки в KYC сервисе с указанием в метаданных папки персональных данных пользователя
  3. Реализовать создание запроса на проверку данных папки в KYC сервисе
  4. Реализовать сохранение информации о запросе на проверку персональных данных в локальной базе

Если за продолжительность одной итерации команды считать две недели, то один-два дня вполне можно потратить на ее планирование, но не в виде совещания с умозрительными рассуждениями и покером, а в основном в виде обычной программистской деятельности в виде написания тестов в некоем минимальном виде. С последующей оценкой времени на реализацию функциональности уже в полном масштабе.


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


Поскольку для первой задачи из вышеозначенного списка у меня есть уже оттестированная рабочая реализация, то перехожу ко второй задаче и начинаю делать черновик теста для метода, выгружающего данные в KYC сервис:


describe('upload personal info', () => {

  const HttpFake = require('HttpFake');
  const http = new HttpFake();
  const store = require('../../src/store');
  const handler = require('../../src/kyc/createFolder');
  const rules = require('../../src/importRules');
  const httpOptions = {
    hostname: 'http://kycservice',
    port: 80,
    path: '/api/folder',
    body: {
      meta_data: {
        firstName: 'Jack',
        lastName: 'Sparrow',
        birthDate: '06/01/1740'
      }
    },
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    }
  };
  const httpResponse = {
    statusCode: 200,
    body: {
      folder_id: '0x382974',
      meta_data: {
        firstName: 'Jack',
        lastName: 'Sparrow',
        birthDate: '06/01/1740'
      }
    },
    headers: {
        'Content-Type': 'application/json'
    }
  };

  let context = null,
      handle = null;

  beforeEach(() => {
    context = {
      http,
      store,
      rules
    };

    handle = handler.bind(context, ['folder']);

    const person = {
      firstName: 'Jack',
      lastName: 'Sparrow',
      birthDate: '06/01/1740'
    };
    store.dispatch({ type: 'PERSON', person });
  });

  it('should assign store folder state value', () => {

    http.expect(httpOptions);
    http.returns(httpResponse);

    const assert = checkExportResult.bind(context, [done]);
    store.subscribe(assert);

    handle();
  });

  function checkExportResult(args){

    const folder = store.getState().folder;

    if(folder === null)
      return;

    expect(folder.folder_id).toEqual('0x382974');
    expect(folder.meta_data.firstName).toEqual('Jack');
    expect(folder.meta_data.lastName).toEqual('Sparrow');
    expect(folder.meta_data.birthDate).toEqual('06/01/1740');

    const checkIsCompleted = args[0];
    checkIsCompleted();
  }
});

Модульный тест второй задачи разложился аж в 100 строчек кода, и на его реализацию у меня ушло около часа времени. При этом первые пять строчек на некоторое время погрузили меня в размышления на тему "как бы мне реализовать имитацию отправки http запросов?", пока я не вспомнил что у меня уже есть некая псевдо-http реализация, имитирующая как раз отправку нужных мне POST запросов. Хорошо. Вот у меня есть тест. Стало ли мне понятнее сколько может потребоваться времени на реализацию нужной функциональности?


На самом деле да. Эта задача на мой взгляд очень похожа на задачу с запросом данных из базы, и я уже принял решение что одного рабочего дня мне вполне хватит чтобы реализовать в таком же подходе отправку POST запроса с сохранением результатов в контейнер состояния. А поскольку у меня уже есть успешный опыт с отдельной реализацией правил обработки данных в рамках выполнения запроса, то я решил что реализую новый набор правил, которые я буду использовать при отправке POST запросов.


Две последующие задачи из списка кажутся мне очень похожими, так что писать тесты для них прямо сейчас я не вижу особого смысла, потому что мозг уже принял в качестве оценки:


  1. Реализовать получение персональных данных пользователя из локальной базы
  2. Реализовать создание папки в KYC сервисе с указанием в метаданных папки персональных данных пользователя —
  3. Реализовать создание запроса на проверку данных папки в KYC сервисе —
  4. Реализовать сохранение информации о запросе на проверку персональных данных в локальной базе —

Ну и поскольку следующие пользовательские истории в списке у меня из этой же оперы, просто в POST запросах будет не JSON, а бинарные данные, то я автоматически принимаю что могу за двухнедельную итерацию реализовать три пользовательских истории.

Комментарии (1)


  1. funca
    21.01.2019 00:39

    "- Какие стадии проходят задачи на вашем проекте? — Отрицание, гнев, торг, депрессия и принятие." ?
    Оценки как и цену надо называть в конце, когда вы уверены в сделке. Для начала определите две штуки: definition of ready — что вам нужно, чтобы взять задачу в работу и definition of done — что должно быть, чтобы считать её завершенной. Пока, вы не уверены, не давайте ни каких эстимаций. Запросите время на spike для согласований, исследований, прототипирования и самообразования. Для эстимаций существует куча техник, разной степени замороченности www.tutorialspoint.com/estimation_techniques/index.htm. TDD может помочь найти недостающие требования (чисто по дедукции). Но вообще говоря TDD это инструмент кодинга и поэтому на эстимации влияет лишь косвенно.