Skip to content

单元测试框架与自动化测试框架实战练习


实战需求

点击查看实战详情


实现思路

uml diagram


代码实现

# 定义一个图书类
class Book:

    def __init__(self, bid, name, price, summary):
        self.bid = bid
        self.name = name
        self.price = price
        self.summary = summary

    # 重写对象的显示格式 方法
    def __str__(self):
        return f"BID: {self.bid} --- Name: {self.name} --- Price: {self.price} --- Summary: {self.summary}"


# 封装管理类
class BookManagement:

    def __init__(self):
        # 定义一个全局变量,用来保存图书的信息,方法各个方法之间进行访问
        self.books = []

    # 菜单方法
    def __menu(self):
        print("****************************************")
        print("*                图书管理系统           *")
        print("*        1. 添加新图书信息              *")
        print("*        2. 通过图书编号修改图书信息        *")
        print("*        3. 通过图书编号删除图书信息        *")
        print("*        4. 通过名称删除图书信息        *")
        print("*        5. 通过图书编号查询图书信息          *")
        print("*        6. 通过名称查询图书信息          *")
        print("*        7. 显示所有图书信息             *")
        print("*        8. 退出系统                  *")
        print("****************************************")
        select_op = input("输入编号选择操作:")
        return select_op

    # 获取图书编号
    def __get_bid(self):
        bid = input("请输入图书ID:")
        return bid

    # 获取名称
    def __get_name(self):
        name = input("请输入图书名称:")
        return name

    # 获取价格
    def __get_price(self):
        while True:
            price = input("请输入图书价格:")
            if price.isdigit():
                return int(price)
            else:
                print("输入价格不合法,请输入数字")

    # 获取简介
    def __get_summary(self):
        summary = input("请输入图书简介:")
        return summary

    # 添加图书
    def add_book(self, bid, name, price, summary):
        for s in self.books:
            if s.bid == bid:
                print("图书编号已存在,添加失败")
                return "添加失败"
        else:
            book = Book(bid, name, price, summary)
            self.books.append(book)
            print("添加图书信息成功")
            return '添加成功'

    # 通过图书编号修改图书信息
    def modify_book_by_id(self, bid, name, price, summary):
        for s in self.books:
            if s.bid == bid:
                s.name = name
                s.price = price
                s.summary = summary
                print("修改成功")
                return "修改成功"
        else:
            print(f'没有 {bid} 对应的图书信息')
            return "修改失败"

    # 通过ID删除图书信息
    def delete_book_by_id(self, bid):
        for s in self.books:
            if s.bid == bid:
                self.books.remove(s)
                print("删除成功")
                return "删除成功"
        else:
            print(f'没有 {bid} 对应的图书信息')
            return "删除失败"

    # 通过图书名称 删除所有符合的图书
    def delete_book_by_name(self, name):
        exist_s = []
        # 找出所有要删除的图书
        for s in self.books:
            if s.name == name:
                exist_s.append(s)

        # 开始删除
        if len(exist_s) > 0:
            for s in exist_s:
                self.books.remove(s)
                print(f"名称为 { name } 的图书删除成功")
            else:
                print(f"成功删除 {len(exist_s)} 个图书")
                return "删除成功"
        else:
            print(f"图书【{name}】不存在,无法删除")
            return "删除失败"

    # 通过图书编号查询图书信息
    def query_book_by_id(self, bid):
        for s in self.books:
            if s.bid == bid:
                print(f"图书编号 {bid} 的图书信息如下:")
                print(s)
                return "查询成功"
        else:
            print(f"图书编号 {bid} 的图书不存在")
            return "查询失败"

    # 通过名称查询图书信息
    def query_book_by_name(self, name):
        result = []
        for s in self.books:
            if s.name == name:
                result.append(s)

        if len(result) > 0:
            print(f"名称为 {name} 的图书共 {len(result)} 名,信息如下:")
            for s in result:
                print(s)
            return "查询成功"
        else:
            print(f"名称为 {name} 的图书不存在")
            return "查询失败"

    # 显示所有图书信息
    def __show(self):
        print("所有图书信息如下:")
        for s in self.books:
            print(s)

    # 管理方法
    def manager(self):
        while True:
            select_op = self.__menu()
            if len(select_op) == 1 and select_op in "12345678":
                if select_op == "1":
                    bid = self.__get_bid()
                    name = self.__get_name()
                    price = self.__get_price()
                    summary = self.__get_summary()
                    self.add_book(bid, name, price, summary)
                elif select_op =="2":
                    bid = self.__get_bid()
                    name = self.__get_name()
                    price = self.__get_price()
                    summary = self.__get_summary()
                    self.modify_book_by_id(bid, name, price, summary)
                elif select_op =="3":
                    bid = self.__get_bid()
                    self.delete_book_by_id(bid)
                elif select_op =="4":
                    name = self.__get_name()
                    self.delete_book_by_name(name)
                elif select_op =="5":
                    bid = self.__get_bid()
                    self.query_book_by_id(bid)
                elif select_op =="6":
                    name = self.__get_name()
                    self.query_book_by_name(name)
                elif select_op =="7":
                    self.__show()
                else:
                    break
            else:
                print("输入的数据不合法,请输入在合法范围内的操作编号!!!")


# 程序入口
if __name__ == '__main__':
    BookManagement().manager()

自动化用例编写

  • 图书管理系统
    • 添加图书:bid, name, price, summary
    • 通过图书编号修改图书信息:bid, name, price, summary
    • 通过图书编号查询图书信息:bid
    • 通过名称查询图书信息:name
    • 通过 ID 删除图书信息:bid
    • 通过图书名称 删除所有符合的图书:name
# test_library.py

class TestLibrary:

    def setup_class(self):
        self.lib = BookManagement()

    # 添加图书
    def test_add_book(self):
        result = self.lib.add_book("b01", "python入门", 18.99, "python详解")
        assert result == "添加成功"

    # 通过图书编号修改图书信息
    def test_modify_book_byid(self):
        result = self.lib.modify_book_by_id("b01", "python入门", 20, "python详解")
        assert result == "修改成功"

    # 通过图书编号查询图书信息
    def test_query_book_byid(self):
        result = self.lib.query_book_by_id("b01")
        assert result == "查询成功"

    # 通过名称查询图书信息
    def test_query_book_byname(self):
        result = self.lib.query_book_by_name("python入门")
        assert result == "查询成功"

    # 通过ID删除图书信息
    def test_delete_book_byid(self):
        result = self.lib.delete_book_by_id("b01")
        assert result == "删除成功"

    # 通过图书名称 删除所有符合的图书
    def test_delete_book_byname(self):
        self.lib.add_book("b01", "python入门", 20.01, "python详解")
        result = self.lib.delete_book_by_name("python入门")
        assert result == "删除成功"

添加标签

class TestLibrary:

    def setup_class(self):
        self.lib = BookManagement()

    # 添加图书
    @pytest.mark.P0
    def test_add_book(self):
        result = self.lib.add_book("b01", "python入门", 18.99, "python详解")
        assert result == "添加成功"

参数化

class TestAddLibrary:

    def setup_class(self):
        self.lib = BookManagement()

    @pytest.mark.parametrize(
        "bid, name, price, summary",
        [
            ["b01", "Python入门", 18.99, "Python详解"],
            ["b02", "Java入门", 18.00, "Java详解"],
            ["b03", "Pytest入门", 15.99, "Pytest详解"],
            ["b04", "Selenium入门", 21.09, "Selenium详解"],
        ],
        ids=["add b01", "add b02", "add b03", "add b04"]
    )
    @pytest.mark.P1
    def test_add_book_byparams(self, bid, name, price, summary):
        '''
        参数化添加图书
        '''
        result = self.lib.add_book(bid, name, price, summary)
        assert result == "添加成功"

数据驱动

book_info = Utils.get_yaml_data("./datas/book_info.yaml", "add", "P1")

class TestAddLibrary:

    def setup_class(self):
        self.lib = BookManagement()

    @pytest.mark.parametrize(
        "bid, name, price, summary", book_info[0], ids=book_info[1]
    )
    @pytest.mark.P1
    def test_add_book_byyaml(self, bid, name, price, summary):
        '''
        数据驱动添加图书
        '''
        result = self.lib.add_book(bid, name, price, summary)
        assert result == "添加成功"

生成测试报告

@allure.feature("图书管理系统")
class TestAddLibrary:

    def setup_class(self):
        self.lib = BookManagement()

    @pytest.mark.parametrize(
        "bid, name, price, summary",
        [
            ["b01", "Python入门", 18.99, "Python详解"],
            ["b02", "Java入门", 18.00, "Java详解"],
            ["b03", "Pytest入门", 15.99, "Pytest详解"],
            ["b04", "Selenium入门", 21.09, "Selenium详解"],
        ],
        ids=["add b01", "add b02", "add b03", "add b04"]
    )
    @pytest.mark.P1
    @allure.story("添加图书")
    @allure.title("参数化添加学生 {bid}, {name}")
    def test_add_book_byparams(self, bid, name, price, summary):
        '''
        参数化添加图书
        '''
        with allure.step("添加图书,获取添加结果"):
            result = self.lib.add_book(bid, name, price, summary)
        assert result == "添加成功"

执行用例,生成 allure 报告

# 执行用例,搜集执行结果
pytest -v --alluredir=./result --clean-alluredir

# 生成在线 allure 报告
allure serve ./result

总结

  • Pytest 编写用例的结构与断言
  • Pytest 参数化与基本装饰器用法
  • Pytest 测试用例调度与运行
  • Allure 报告生成