240530Pytest测试框架作业讲解

图书管理系统代码

# 定义一个图书类
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()

测试用例代码

import pytest
from BMS.scripts.BMS import BookManagement

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 == "删除成功"

在 pytest.ini 配置文件中定义标签

[pytest]
markers =   P0
            P1
            P2

添加标签

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 == "添加成功"

数据驱动

编写工具类

import yaml

class Utils:

    @classmethod
    def get_yaml_data(cls, file_path, name, level):
        '''
        :param file_path:  data 文件路径
        :param name:  第一层 key
        :param level: 第二层 key
        :return:  数据
        '''
        with open(file_path, encoding="utf-8") as file:
            yaml_data = yaml.safe_load(file)
            data = yaml_data.get(name).get(level).get("data")
            return data

yaml数据文件

book:
  add:
    data:
      - [ "b01", "Python入门", 18.99, "Python详解", "添加成功" ]
      - [ "b02", "Java入门", 18.00, "Java详解", "添加成功" ]
      - [ "b03", "Pytest入门", 15.99, "Pytest详解", "添加成功" ]
      - [ "b03", "Selenium入门", 15.99, "Selenium详解", "添加失败" ]
      - [ "b04", "Selenium入门", 21.09, "Selenium详解", "添加成功" ]
  modify:
    data:
      - [ "b01", "Python入门", 999, "Python基础详解", "修改成功" ]
      - [ "b02", "Java入门", 999, "Java基础详解", "修改成功" ]
      - [ "b03", "Pytest入门", 999, "Pytest基础详解", "修改成功" ]
      - [ "b04", "Selenium入门", 999, "Selenium基础详解", "修改成功" ]
      - [ "b06", "Selenium入门", 888, "Selenium基础详解", "修改失败" ]

参数化

from BMS.utils.utils import Utils
import pytest
from BMS.scripts.BMS import BookManagement

add_data = Utils.get_yaml_data("../data/data.yaml", "book", "add")
modify_data = Utils.get_yaml_data("../data/data.yaml", "book", "modify")


class TestLibrary:

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

    # 添加图书
    @pytest.mark.parametrize("bid, name, price,summary, expect", add_data)
    def test_add_book(self, bid, name, price,summary, expect):
        # result = self.lib.addBook("b01", "python入门", 18.99, "python详解")
        result = self.lib.add_book(bid, name, price, summary)
        assert result == expect

    # 通过图书编号修改图书信息
    @pytest.mark.parametrize("bid, name, price,summary, expect", modify_data)
    def test_modify_book_byid(self,bid, name, price,summary, expect):
        # result = self.lib.modifyBookByID("b01", "Python入门", 20, "python详解")
        result = self.lib.modify_book_by_id(bid, name, price, summary)
        assert result == expect

生成报告

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

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