IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Python中的自定义密码验证对密码验证功能进行单元测试. -> 正文阅读

[开发测试]Python中的自定义密码验证对密码验证功能进行单元测试.

这些帖子将分为三个部分。

  1. 密码验证功能
  2. 重构密码验证函数
  3. 对密码验证功能进行单元测试

这是Python系列中自定义密码验证的第三部分,也是最后一部分。我们将看看对密码验证功能进行单元测试?.

下面是重构后的代码:

from string import (
    ascii_lowercase, ascii_uppercase,
    digits, punctuation, whitespace)


def contains_character(password: str = "", sack: str = "") -> bool:
    has_char = False

    for char in password:
        if char in sack:
            has_char = True
            break

    return has_char


def is_valid_size(password: str = "") -> bool:
    MIN_SIZE = 6
    MAX_SIZE = 20
    password_size = len(password)

    return MIN_SIZE <= password_size <= MAX_SIZE


def get_invalid_chars():
    valid_chars = {'-', '_', '.', '!', '@', '#', '$', '^', '&', '(', ')'}
    invalid_chars = set(punctuation + whitespace) - valid_chars

    return "".join(invalid_chars)


def is_valid_password(password: str = "") -> bool:
    try:
        if not password:
            return False

        new_password = password.strip()

        if not is_valid_size(new_password):
            return False

        invalid_chars = get_invalid_chars()

        if contains_character(new_password, invalid_chars):
            return False

        if not contains_character(new_password, digits):
            return False

        if not contains_character(new_password, ascii_lowercase):
            return False

        if not contains_character(new_password, ascii_uppercase):
            return False

        return True
    except:
        return False

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

在测试:nut_and_bolt:?之前

有些事你应该知道:

  • 这将是一个单元测试
  • 我们将利用python的内置测试模块,unittest
  • 我们将测试,contains_character?,?is_valid_sizeis_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字符

import unittest
from app import contains_character


class TestContainsCharacter(unittest.TestCase):
    def test_empty_password_or_and_empty_sack(self):
        self.assertFalse(contains_character())

    def test_char_i_in_str_python(self):
        self.assertFalse(contains_character("i", "python"))

    def test_str_py_in_str_python(self):
        self.assertTrue(contains_character("py", "python"))

    def test_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

import unittest
from app import is_valid_size


class TestIsValidSize(unittest.TestCase):
    def test_empty_password(self):
        self.assertFalse(is_valid_size(""))

    def test_4_char_password(self):
        self.assertFalse(is_valid_size("pass"))

    def test_6_char_password(self):
        self.assertTrue(is_valid_size("passwd"))

    def test_16_char_password(self):
        self.assertTrue(is_valid_size("ThisIs1Password!"))

    def test_20_char_password(self):
        self.assertTrue(is_valid_size("ThisIs1Password!+20"))

    def test_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方法。

我们将测试:

  • 对于空密码
  • 三个字符的密码
  • 十个字符的密码
  • 二十个字符的密码
  • 对于包含无效特殊字符(如分号)的密码
  • 对于没有数字的密码
  • 对于没有小写字母的密码
  • 对于没有大写字母的密码
  • 对于没有有效特殊字符的密码
  • 对于有效的密码
    • 一个尺寸以内,[6-20]
    • 至少一个小写和大写字符
    • 至少一个数字
    • 没有无效的特殊字符

TestIsValidPassword

class TestIsValidPassword(unittest.TestCase):
    def test_empty_password(self):
        self.assertFalse(is_valid_password())

    def test_password_of_size_three(self):
        self.assertFalse(is_valid_password("pas"))

    def test_password_of_size_ten(self):
        self.assertFalse(is_valid_password("Password12"))
        self.assertTrue(is_valid_password("Password1_"))

    def test_password_of_size_twenty(self):
        self.assertFalse(is_valid_password("Password12Password_$"))

    def test_password_with_invalid_special_character_semicolon(self):
        self.assertFalse(is_valid_password("Password1_;"))
        self.assertFalse(is_valid_password("Password1;"))

    def test_password_with_no_digit(self):
        self.assertFalse(is_valid_password("Password_"))

    def test_password_with_no_lowercase(self):
        self.assertFalse(is_valid_password("PASSWORD1_"))

    def test_password_with_no_uppercase(self):
        self.assertFalse(is_valid_password("password1_"))

    def test_password_without_valid_special_character(self):
        self.assertFalse(is_valid_password("Password1"))

    def test_valid_password(self):
        self.assertTrue(is_valid_password("Password1_"))
        self.assertTrue(is_valid_password("PassWord34$"))


if __name__ == "__main__":
    unittest.main()

不是所有的测试都通过了。这些测试用例不应该通过——我们期望它们不会通过。所以当我们期待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,我们应该做出改变并重新运行测试。

要进行的更改:

  • 在…里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?

    def get_valid_chars():
        return "".join(valid_chars)

    进行测试。

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

    if not contains_character(new_password, get_valid_chars()):
        return False

    进行测试。现在,所有的测试都通过了。万岁!!: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类似于下面的代码片段:

from string import (ascii_lowercase, ascii_uppercase, digits, punctuation,
                    whitespace)
valid_chars = {'-', '_', '.', '!', '@', '#', '$', '^', '&', '(', ')'}


def contains_character(password: str = "", sack: str = "") -> bool:
    has_char = False

    for char in password:
        if char in sack:
            has_char = True
            break

    return has_char


def is_valid_size(password: str = "") -> bool:
    MIN_SIZE = 6
    MAX_SIZE = 20
    password_size = len(password)

    return MIN_SIZE <= password_size <= MAX_SIZE


def get_invalid_chars():
    invalid_chars = set(punctuation + whitespace) - valid_chars
    return "".join(invalid_chars)


def get_valid_chars():
    return "".join(valid_chars)


def is_valid_password(password: str = "") -> bool:
    try:
        if not password:
            return False

        new_password = password.strip()

        if not is_valid_size(new_password):
            return False

        if not contains_character(new_password, ascii_lowercase):
            return False

        if not contains_character(new_password, ascii_uppercase):
            return False

        if not contains_character(new_password, digits):
            return False

        if contains_character(new_password, get_invalid_chars()):
            return False

        if not contains_character(new_password, get_valid_chars()):
            return False

        return True
    except:
        return False

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

import unittest
from app import (contains_character, is_valid_size, is_valid_password)


class TestContainsCharacter(unittest.TestCase):
    def test_empty_password_or_and_empty_sack(self):
        self.assertFalse(contains_character())

    def test_char_i_in_str_python(self):
        self.assertFalse(contains_character("i", "python"))

    def test_str_py_in_str_python(self):
        self.assertTrue(contains_character("py", "python"))

    def test_str_python_in_str_python(self):
        self.assertTrue(contains_character("python", "python"))


class TestIsValidSize(unittest.TestCase):
    def test_empty_password(self):
        self.assertFalse(is_valid_size(""))

    def test_4_char_password(self):
        self.assertFalse(is_valid_size("pass"))

    def test_6_char_password(self):
        self.assertTrue(is_valid_size("passwd"))

    def test_16_char_password(self):
        self.assertTrue(is_valid_size("ThisIs1Password!"))

    def test_20_char_password(self):
        self.assertTrue(is_valid_size("ThisIs1Password!/+20"))

    def test_21_char_password(self):
        self.assertFalse(is_valid_size("ThisIs1Password!/+20&"))


class TestIsValidPassword(unittest.TestCase):
    def test_empty_password(self):
        self.assertFalse(is_valid_password())

    def test_password_of_size_three(self):
        self.assertFalse(is_valid_password("pas"))

    def test_password_of_size_ten(self):
        self.assertFalse(is_valid_password("Password12"))
        self.assertTrue(is_valid_password("Password1_"))

    def test_password_of_size_twenty(self):
        self.assertTrue(is_valid_password("Password12Password_$"))

    def test_password_with_invalid_special_character_semicolon(self):
        self.assertFalse(is_valid_password("Password1_;"))
        self.assertFalse(is_valid_password("Password1;"))

    def test_password_with_no_digit(self):
        self.assertFalse(is_valid_password("Password_"))

    def test_password_with_no_lowercase(self):
        self.assertFalse(is_valid_password("PASSWORD1_"))

    def test_password_with_no_uppercase(self):
        self.assertFalse(is_valid_password("password1_"))

    def test_password_without_valid_special_character(self):
        self.assertFalse(is_valid_password("Password1"))

    def test_valid_password(self):
        self.assertTrue(is_valid_password("Password1_"))
        self.assertTrue(is_valid_password("PassWord34$"))


if __name__ == "__main__":
    unittest.main()

请随意表达你的观点,如果你觉得有什么不足,请告诉我如何改进。

关注下方公众号领取完整代码

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章           查看所有文章
加:2022-02-26 12:01:59  更:2022-02-26 12:03:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:42:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码