visit
High unit test code coverage is often viewed as a key indicator of code quality, and for good reason. It demonstrates that a significant portion of the codebase has been tested and is less likely to contain bugs. However, if you just see the numbers, how can you be sure that your business logic is covered? Or that your code is easy to maintain?
To avoid these pitfalls, it’s important to focus on the quality of the unit tests, not just the quantity. Here are a few best practices to follow:
The new password must be at least 8 characters long, and have at least 1 lowercase letter, 1 uppercase letter, 1 digit and a special character.
function validateNewPassword(newPassword) {
let passwordRegex = new RegExp(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
)
return passwordRegex.test(newPassword)
}
test('valid password', () => {
expect(validateNewPassword('Abcdefg1!')).toBe(true)
})
test('invalid password', () => {
expect(validateNewPassword('Abcdefgh1')).toBe(false)
})
test('password minimum length', () => {
expect(validateNewPassword('a'.repeat(7))).toBe(false)
})
function validateNewPassword(newPassword) {
if (newPassword.length < 8) {
return false
}
return true
}
test('password must contain at least one uppercase letter', () => {
expect(validateNewPassword('abcdefgh1!')).toBe(false)
})
function validateNewPassword(newPassword) {
if (newPassword.length < 8) {
return false
}
if (!newPassword.match(/[A-Z]/)) {
return false
}
return true
}
test('password must contain at least one lowercase letter', () => {
expect(validateNewPassword('ABCDEFGH1!')).toBe(false)
})
function validateNewPassword(newPassword) {
if (newPassword.length < 8) {
return false
}
if (!newPassword.match(/[A-Z]/)) {
return false
}
if (!newPassword.match(/[a-z]/)) {
return false
}
return true
}
test('password must contain at least one digit', () => {
expect(validateNewPassword('Abcdefgh!')).toBe(false)
})
function validateNewPassword(newPassword) {
if (newPassword.length < 8) {
return false
}
if (!newPassword.match(/[A-Z]/)) {
return false
}
if (!newPassword.match(/[a-z]/)) {
return false
}
if (!newPassword.match(/\d/)) {
return false
}
return true
}
test('password must contain at least one special symbol', () => {
expect(validateNewPassword('Abcdefgh1')).toBe(false)
})
function validateNewPassword(newPassword) {
if (newPassword.length < 8) {
return false
}
if (!newPassword.match(/[A-Z]/)) {
return false
}
if (!newPassword.match(/[a-z]/)) {
return false
}
if (!newPassword.match(/\d/)) {
return false
}
if (!newPassword.match(/[@$!%*?&]/)) {
return false
}
return true
}
const LOWERCASE_REGEX = /[a-z]/
const UPPERCASE_REGEX = /[A-Z]/
const DIGIT_REGEX = /\d/
const SPECIAL_CHAR_REGEX = /[@$!%*?&]/
function validateNewPassword(newPassword) {
return (
newPassword.length >= 8 &&
LOWERCASE_REGEX.test(newPassword) &&
UPPERCASE_REGEX.test(newPassword) &&
DIGIT_REGEX.test(newPassword) &&
SPECIAL_CHAR_REGEX.test(newPassword)
)
}
describe('Password validation', () => {
test('password minimum length is 8 characters', () => {
// refactored after the first example to make sure the only reason for the test to fail is the length
expect(validateNewPassword('Abcde1!')).toBe(false)
expect(validateNewPassword('Abcdef1!')).toBe(true)
})
test('password must contain at least 1 uppercase letter', () => {
expect(validateNewPassword('abcdefgh1!')).toBe(false)
expect(validateNewPassword('Abcdefgh1!')).toBe(true)
})
test('password must contain at least 1 lowercase letter', () => {
expect(validateNewPassword('ABCDEFGH1!')).toBe(false)
expect(validateNewPassword('AbCdefgh1!')).toBe(true)
})
test('password must contain at least 1 digit', () => {
expect(validateNewPassword('Abcdefgh!')).toBe(false)
expect(validateNewPassword('Abcdefgh1!')).toBe(true)
})
test('password must contain at least 1 special symbol', () => {
expect(validateNewPassword('Abcdefgh1')).toBe(false)
expect(validateNewPassword('Abcdefgh1!')).toBe(true)
})
})
Also published here.