这篇文章主要介绍“Python中如何自定义密码验证”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中如何自定义密码验证”文章能帮助大家解决问题。

下面是重构后的代码:

fromstringimport(ascii_lowercase,ascii_uppercase,digits,punctuation,whitespace)defcontains_character(password:str="",sack:str="")->bool:has_char=Falseforcharinpassword:ifcharinsack:has_char=Truebreakreturnhas_chardefis_valid_size(password:str="")->bool:MIN_SIZE=6MAX_SIZE=20password_size=len(password)returnMIN_SIZE<=password_size<=MAX_SIZEdefget_invalid_chars():valid_chars={'-','_','.','!','@','#','$','^','&','(',')'}invalid_chars=set(punctuation+whitespace)-valid_charsreturn"".join(invalid_chars)defis_valid_password(password:str="")->bool:try:ifnotpassword:returnFalsenew_password=password.strip()ifnotis_valid_size(new_password):returnFalseinvalid_chars=get_invalid_chars()ifcontains_character(new_password,invalid_chars):returnFalseifnotcontains_character(new_password,digits):returnFalseifnotcontains_character(new_password,ascii_lowercase):returnFalseifnotcontains_character(new_password,ascii_uppercase):returnFalsereturnTrueexcept:returnFalse

我们的目标是为上面的代码片段编写单元测试。我们可以捕捉隐藏的错误,并在修复代码以通过测试时继续重构。

在测试:nut_and_bolt:️之前

有些事你应该知道:

这将是一个单元测试

我们将利用python的内置测试模块,unittest

我们将测试,contains_character , is_valid_size和is_valid_password整齐

测试将在test.py所以上面的片段可能在app.py(你选择你想要的名字)

我们将参考

试验contains_character

contains_character返回bool,要么True或者False。所以我们可以使用assertTrue还有assertFalse方法。

我们将测试:

如果既没有传递密码也没有传递sack(无参数)

为了角色"i"在字符串中,"python"

为了角色"py"在字符串中,"python"

为了角色"python"在字符串中,"python"

有些情况下,比如int作为传递password或者当一个list作为传递sack。我们不会测试这种情况。(您应该为此进行测试)

TestContainsCharacter字符

importunittestfromappimportcontains_characterclassTestContainsCharacter(unittest.TestCase):deftest_empty_password_or_and_empty_sack(self):self.assertFalse(contains_character())deftest_char_i_in_str_python(self):self.assertFalse(contains_character("i","python"))deftest_str_py_in_str_python(self):self.assertTrue(contains_character("py","python"))deftest_str_python_in_str_python(self):self.assertTrue(contains_character("python","python"))if__name__=="__main__":unittest.main()

我们能击中ctrl + F5运行此脚本(test.py)无需调试。我们可以像下面这样运行这个脚本python3 test.py或者python3 -m unittest test.py。所有这些测试都应该通过。

试验is_valid_size

is_valid_size返回bool,要么True或者False。所以我们可以使用assertTrue还有assertFalse方法。

我们将测试:

对于空密码或没有传递参数时

四个字符的密码

六个字符的密码

十六个字符的密码

二十个字符的密码

21个字符的密码

TestIsValidSize

importunittestfromappimportis_valid_sizeclassTestIsValidSize(unittest.TestCase):deftest_empty_password(self):self.assertFalse(is_valid_size(""))deftest_4_char_password(self):self.assertFalse(is_valid_size("pass"))deftest_6_char_password(self):self.assertTrue(is_valid_size("passwd"))deftest_16_char_password(self):self.assertTrue(is_valid_size("ThisIs1Password!"))deftest_20_char_password(self):self.assertTrue(is_valid_size("ThisIs1Password!+20"))deftest_21_char_password(self):self.assertFalse(is_valid_size("ThisIs1Password!+20&"))if__name__=="__main__":unittest.main()

所有这些测试都应该通过。

试验is_valid_password

is_valid_password返回bool,要么True或者False。所以我们可以使用assertTrue还有assertFalse方法。

我们将测试:

1.对于空密码

2.三个字符的密码

3.十个字符的密码

4.二十个字符的密码

5.对于包含无效特殊字符(如分号)的密码

6.对于没有数字的密码

7.对于没有小写字母的密码

8.对于没有大写字母的密码

9.对于没有有效特殊字符的密码

10.对于有效的密码

一个尺寸以内,[6-20]

至少一个小写和大写字符

至少一个数字

没有无效的特殊字符

TestIsValidPassword

classTestIsValidPassword(unittest.TestCase):deftest_empty_password(self):self.assertFalse(is_valid_password())deftest_password_of_size_three(self):self.assertFalse(is_valid_password("pas"))deftest_password_of_size_ten(self):self.assertFalse(is_valid_password("Password12"))self.assertTrue(is_valid_password("Password1_"))deftest_password_of_size_twenty(self):self.assertFalse(is_valid_password("Password12Password_$"))deftest_password_with_invalid_special_character_semicolon(self):self.assertFalse(is_valid_password("Password1_;"))self.assertFalse(is_valid_password("Password1;"))deftest_password_with_no_digit(self):self.assertFalse(is_valid_password("Password_"))deftest_password_with_no_lowercase(self):self.assertFalse(is_valid_password("PASSWORD1_"))deftest_password_with_no_uppercase(self):self.assertFalse(is_valid_password("password1_"))deftest_password_without_valid_special_character(self):self.assertFalse(is_valid_password("Password1"))deftest_valid_password(self):self.assertTrue(is_valid_password("Password1_"))self.assertTrue(is_valid_password("PassWord34$"))if__name__=="__main__":unittest.main()

不是所有的测试都通过了。这些测试用例不应该通过&mdash;&mdash;我们期望它们不会通过。所以当我们期待False我们得到True。某处存在缺陷或错误。

这些测试没有通过:

test_password_of_size_ten : self.assertFalse(is_valid_password("Password12"))应该是False因为即使大小有效,它也没有特殊字符。

test_password_without_valid_special_character : self.assertFalse(is_valid_password("Password1"))应该是False因为没有有效的特殊字符。

这is_valid_password函数不检查是否存在有效的特殊字符。它检查无效字符,但不检查有效字符。这是由有缺陷的假设造成的,即只要密码不包含无效字符,它就包含有效字符(包括有效的特殊字符)。

重构is_valid_password

既然我们已经指出了我们的bug,我们应该做出改变并重新运行测试。

要进行的更改:

在&hellip;里get_invalid_chars,我们有set有效的特殊字符,valid_chars。让我们让它对所有函数都是全局的(例如,把它从get_invalid_chars函数并将其放在函数的顶部)。为了确保某处没有损坏,运行测试(我们预计有两种情况会失败)。请注意,即使我们移动valid_chars由于get_invalid_chars , get_invalid_chars应该还能正常工作。

这valid_chars是一个set,它可以用作中的一组get_invalid_chars . contains_character需要一段时间string sack作为论据。我们必须解析valid_chars如同string。让我们在下面创建一个函数get_invalid_chars返回一个string版本valid_chars

defget_valid_chars():return"".join(valid_chars)

进行测试。

让我们检查中的有效字符is_valid_password通过在return True中的语句try封锁。

ifnotcontains_character(new_password,get_valid_chars()):returnFalse

进行测试。现在,所有的测试都通过了。万岁!!:clap:️:clap:️:clap:️

这更多的是重新排列代码is_valid_password在另一种环境中自然运行良好。我们将重新排列代码is_valid_password按此顺序分别为:size, lower case, upper case, digit, invalid special character and valid special character进行测试。

结论

这is_valid_password会在app.py类似于下面的代码片段:

fromstringimport(ascii_lowercase,ascii_uppercase,digits,punctuation,whitespace)valid_chars={'-','_','.','!','@','#','$','^','&','(',')'}defcontains_character(password:str="",sack:str="")->bool:has_char=Falseforcharinpassword:ifcharinsack:has_char=Truebreakreturnhas_chardefis_valid_size(password:str="")->bool:MIN_SIZE=6MAX_SIZE=20password_size=len(password)returnMIN_SIZE<=password_size<=MAX_SIZEdefget_invalid_chars():invalid_chars=set(punctuation+whitespace)-valid_charsreturn"".join(invalid_chars)defget_valid_chars():return"".join(valid_chars)defis_valid_password(password:str="")->bool:try:ifnotpassword:returnFalsenew_password=password.strip()ifnotis_valid_size(new_password):returnFalseifnotcontains_character(new_password,ascii_lowercase):returnFalseifnotcontains_character(new_password,ascii_uppercase):returnFalseifnotcontains_character(new_password,digits):returnFalseifcontains_character(new_password,get_invalid_chars()):returnFalseifnotcontains_character(new_password,get_valid_chars()):returnFalsereturnTrueexcept:returnFalse

单元测试将会在test.py类似于下面的代码片段:

importunittestfromappimport(contains_character,is_valid_size,is_valid_password)classTestContainsCharacter(unittest.TestCase):deftest_empty_password_or_and_empty_sack(self):self.assertFalse(contains_character())deftest_char_i_in_str_python(self):self.assertFalse(contains_character("i","python"))deftest_str_py_in_str_python(self):self.assertTrue(contains_character("py","python"))deftest_str_python_in_str_python(self):self.assertTrue(contains_character("python","python"))classTestIsValidSize(unittest.TestCase):deftest_empty_password(self):self.assertFalse(is_valid_size(""))deftest_4_char_password(self):self.assertFalse(is_valid_size("pass"))deftest_6_char_password(self):self.assertTrue(is_valid_size("passwd"))deftest_16_char_password(self):self.assertTrue(is_valid_size("ThisIs1Password!"))deftest_20_char_password(self):self.assertTrue(is_valid_size("ThisIs1Password!/+20"))deftest_21_char_password(self):self.assertFalse(is_valid_size("ThisIs1Password!/+20&"))classTestIsValidPassword(unittest.TestCase):deftest_empty_password(self):self.assertFalse(is_valid_password())deftest_password_of_size_three(self):self.assertFalse(is_valid_password("pas"))deftest_password_of_size_ten(self):self.assertFalse(is_valid_password("Password12"))self.assertTrue(is_valid_password("Password1_"))deftest_password_of_size_twenty(self):self.assertTrue(is_valid_password("Password12Password_$"))deftest_password_with_invalid_special_character_semicolon(self):self.assertFalse(is_valid_password("Password1_;"))self.assertFalse(is_valid_password("Password1;"))deftest_password_with_no_digit(self):self.assertFalse(is_valid_password("Password_"))deftest_password_with_no_lowercase(self):self.assertFalse(is_valid_password("PASSWORD1_"))deftest_password_with_no_uppercase(self):self.assertFalse(is_valid_password("password1_"))deftest_password_without_valid_special_character(self):self.assertFalse(is_valid_password("Password1"))deftest_valid_password(self):self.assertTrue(is_valid_password("Password1_"))self.assertTrue(is_valid_password("PassWord34$"))if__name__=="__main__":unittest.main()

关于“Python中如何自定义密码验证”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。