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.

[code]
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);
}

}

[/code]

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

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

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.

[code]

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));
}
}
[/code]

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.

[table id=5 /]

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!