TDD Development Cost Estimate

    A modest discussion based on my yesterday's publication on the topic of forecasting development time, once again awakened in me a feeling of some kind of incorrectness on the topic of using a purely speculative approach to breaking up history into tasks. In my opinion, when we write tasks in the list, even when we use object or functional terminology, we do not quite imagine all the modules with code that we need to develop or refine.


    Then an idea occurred to me, after dividing a user story into tasks, try to draft drafts of unit tests for the classes or methods I mention in the tasks. I don't even need to invent a user story, I can take one of my current work. For example:


    As a system, I want to send my personal data to the KYC service for verification.


    And a list of tasks for her:


    1. Implement getting personal user data from the local database
    2. Implement the creation of a folder in the KYC service with the user's personal data in the metadata folder
    3. Implement the creation of a request to check the folder data in the KYC service
    4. Implement saving information about the request for checking personal data in a local database

    If the duration of one iteration of a team is two weeks, then one or two days may well be spent on its planning, but not in the form of a meeting with speculative reasoning. and poker, but mainly in the form of ordinary programming activities in the form of writing tests in a certain minimum form. With the subsequent assessment of the time to implement the functionality is already in full scale.


    In the first approximation, it looks like a profit from all sides. We write code and do not waste time on collective reasoning. And we build estimates on the basis of at least the minimum amount of code, feeling the customer’s requirements, as it were.


    Since for the first task of the above list, I have already tested a working implementation, I proceed to the second task and begin to make a test draft for the method that uploads data to the KYC service:


    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();
      });
      functioncheckExportResult(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();
      }
    });

    The modular test of the second task decomposed as much as 100 lines of code, and it took me about an hour to implement it. At the same time, the first five lines for a while plunged me into thinking on the topic "how would I implement an imitation of sending http requests?" Until I remembered that I already had some kind of псевдо-httpimplementation imitating just sending the POSTrequests I needed . Good. Here I have a test. Has it become clearer to me how long it may take to implement the necessary functionality?


    In fact, yes. This task in my opinion is very similar to the task of requesting data from the database, and I have already decided that one working day would be enough for me to implement in the same approach sending a POSTrequest while storing the results in a state container. And since I already have a successful experience with a separate implementation of data processing rules within the framework of a query, I decided that I would implement a new set of rules that I would use when sending POSTrequests.


    The next two tasks from the list seem to me very similar, so I don’t see much point in writing tests for them right now, because the brain has already taken it as an assessment:


    1. Implement getting personal user data from the local database
    2. Implement the creation of a folder in the KYC service with indication of the user's personal data in the metadata folder - 8 hours
    3. Implement the creation of a request to check the folder data in the KYC service - 8h
    4. Implement saving information about a request for checking personal data in a local database - 8h

    Well, since the following user stories in my list are from the same opera, it’s just that the POSTqueries will not JSONhave binary data, I automatically accept that I can implement three user stories for a two-week iteration.


    Also popular now: