Today is Sunday, 22nd September 2019

Archive for the ‘XP’ Category


My Bookshelf: SOA, Spring, Hibernate, GWT, TDD/JUnit, Agile, Scrum, Continuous Integration

Here’s a snapshot of my bookshelf. Just a snippet of a much larger library. Nice collection of books on SOA, Spring, Hibernate, GWT, TDD/JUnit, Agile, Scrum, Continuous Integration



Unit Testing a Password Utility

In this post, we are going to develop a password utility. The utility has to support password validation.

Here are the password security rules for the application:

  • at least 8 characters, max of 12
  • at least one uppercase
  • at least one lowercase
  • at least one number
  • at least one symbol @#$%=:?

In regular TDD fashion, we’ll first set out to develop unit tests that will test the functionality of the application. Based on the security rules above, we will develop unit tests for the following conditions:

  • Test for null string
  • Test for empty string
  • Test for max of 12 characters
  • Test for at least one uppercase
  • Test for at least one lowercase
  • Test for at lest one number
  • Test for at least one symbol

There a number of ways to perform the validation on the password. However, the best solution for this is a regular expression. Agreed that it takes a bit of time to develop the regular expression, but the test cases will help drive us to the correct solution.

So let’s get started with the unit tests. Based on the information above, we have the following unit tests.

package com.luv2code.password.util;

import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Chad Darby, darby@luv2code.com
 */
public class PasswordUtilsTest {

    @Test
    public void validatePassword_Null() {
       // setup
        String password = null;

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_EmptyString() {
       // setup
        String password = "";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_Missing_OneNumber() {
       // setup
        String password = "Abcdefg#";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_Missing_OneUpperCaseLetter() {
       // setup
        String password = "abcdefg5#";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_Missing_OneLowerCaseLetter() {
       // setup
        String password = "ABCDEFG5#";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_Missing_OneSymbol() {
       // setup
        String password = "Abcdefg5";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

    @Test
    public void validatePassword_AllRulesMet() {
       // setup
        String password = "Abcdefg5#";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertTrue(actual);
    }

    @Test
    public void validatePassword_LengthTooLong() {
       // setup
        String password = "Abcdefg5#abcdefgabcd";

        // execute
        boolean actual = PasswordUtils.validatePassword(password);

        // assert
        assertFalse(actual);
    }

}

Now, we can move forward to the implementation. Essentially, we need to develop a method with the following signature:

    /**
     * Returns true if password matches the validation rules
     *
     * @param password
     * @return
     */
    public static boolean validatePassword(String password) {
      return true;
    }

Failing Tests

In true TDD fashion, this implementation will cause the majority of our tests to fail. It will fail for all invalid passwords. Our first run of the test cases will generate failures. Now, we can update the implementation to return the correct results. As I mentioned earlier, we’ll make use of a regular expression to validate the password.


package com.luv2code.password.util;

/**
 *
 * @author Chad Darby, darby@luv2code.com
 */
public class PasswordUtils {

    private static final String VALID_PASSWORD_REGEX = "((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%=:\?]).{8,12})";

    /**
     * Returns true if password matches the validation rules
     *
     * @param password
     * @return
     */
    public static boolean validatePassword(String password) {
        return (password != null && password.matches(VALID_PASSWORD_REGEX));
    }
}

Passing Tests

As you can see in the validatePassword method, the conditional checks to make sure the password is not null. This supports one of the first test cases. Now, to meet the validation rules, we make use of the regular expression:

((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%=:\\?]).{8,12})

Now, I know that looks like a really gnarly piece of gibberish, but let’s break it down one section at a time.

ExpressionDescription
(?=.*\\d)at least one digit
(?=.*[a-z])at least one lowercase
(?=.*[A-Z])at least one uppercase
(?=.*[@#$%=:\\?])at least one symbol @#$%=:?
{8,12}minimum of 8 characters, max of 12

That’s pretty much it. The regular expression is the bulk of development for this validation routine. It is nice that we were able to minimize the implementation to just a couple of lines of code. The unit tests provide coverage for the happy path, error conditions (null strings) and the edge cases.

The source code is available here.

Enjoy!



Continuous Integration: Technical Practices

In software engineering, continuous integration (CI) implements continuous processes of applying quality control — small pieces of effort, applied frequently. Continuous integration aims to improve the quality of software, and to reduce the time taken to deliver it, by replacing the traditional practice of applying quality control after completing all development.

– Source: Wikipedia

Build Software At Every Change

  • Automate builds
  • Separate build scripts from IDE
  • Centralize software assets
  • Use consistent directory structure
  • Use a dedicated build machine
  • Use a CI server
  • Run integration builds
  • Stage builds

Continuous Database Integration

  • Automate database integration
  • Use a local database sandbox
  • Use version control for db assets
  • Give developers access to modify db
  • Make DBA part of dev team

Continuous Inspection

  • Reduce code complexity
  • Perform design reviews continuously
  • Maintain code standards with code audits
  • Reduce duplicate code
  • Assess code coverage

Continuous Testing

  • Automate tests: unit, component, functional
  • Run faster tests first
  • Write test for defects
  • Make component tests repeatable

Continuous Deployment

  • Release working software, any time
  • Produce a clean environment
  • Label each build
  • Run all tests
  • Create feedback reports
  • Possess capability to roll back release

Book Recommendation

If you are interested in continuous integration, then I would highly recommend the book.