首页 > 其他分享 >pytest用例管理

pytest用例管理

时间:2024-10-23 13:58:42浏览次数:1  
标签:py allure 管理 print 用例 pytest test def

pytest用例管理

1.安装

pip install pytest

2.编写

2.1 编写规则

  1. 用例文件:所有文件名以test_开头
  2. 用例类:测试文件中每个Test开头的类就是一个测试用例类
  3. 测试用例:测试类中每一个以test开头的方法就是一个测试用例

2.2 函数形式编写测试用例

def test_demo():
    assert 100 == 100

使用pytest可以执行所有测试用例

2.3 以类的形式编写用例

class Test_demo:
    def test_demo1():
        assert 100 == 100
    
    def test_demo2():
        assert 100 == 200

3.执行测试

3.1 执行方式

  1. 命令行在文件入口执行pytest
  2. 代码中通过 pytest.main()执行

3.2 执行参数

  1. -v 显示测试的详细参数信息

    命令行:pytest -v

    代码:pytest.main("-v")

  2. -s 显示测试执行的详细信息

  3. -vs 展示全部信息

3.3 参数传递

  1. -k 匹配用例名词(当前路径下的 文件名、类名、方法名,备注可以结合or,not 等关键字 ,不区分大小写)

    pytest.main(['-vs', '-k', 'up', './test_2.py'])

  2. -x 遇到错误停止

    `pytest.main(['-vs','-x', './test_stop.py'])

  3. --maxfail=num 失败数量达到num个时停止

    pytest.main(['-vs', '--maxfail=2', './test_stop.py'])

  4. -n=num 开启num个线程去执行用例 (需要安装 pytest-xdist)

    pytest.main(['-vs','./test_thread.py','-n=2'])

  5. --reruns=num 设置失败重跑次数 如果存在用例失败,用例失败后重跑的次数num

    pytest.main(['-vs', './test_fail.py', '--reruns=2'])

3.4 指定执行的测试目录和文件

::用于指定测试类和测试用例

pytest testcase/test_demo::Test_demo::test_demo

4.前后置方法和fixture机制

4.1 函数用例的前后置方法

def setup_function(function):
    print("前置方法")

def teardown_function(function):
    print("后置方法")

def test_0():
    print("执行")

4.2 测试类中的前后置方法

class Test_demo:
    def test_0():
        print("执行0")
    
    def test_1():
        print("执行1")
   
    @classmethod
    def setup_class(cls):
        print("前置方法")
     
    @classmethod
    def teadown_class(cls):
        print("后置方法")

4.3 测试用例前后置方法(先执行测试类方法,再执行函数测试用例)

class Test_demo:
    def test_0():
        print("执行0")
    
    def test_1():
        print("执行1")
   
    @classmethod
    def setup_class(cls):
        print("执行测试类前置")
    
    @clasmethod
    def teadown_class(cls):
        print("执行测试类后置")
    
     def setup_method(function):
        print("测试用例前置")

    def teardown_method(function):
        print("测试用例后置")

4.4 模块级别前后置方法

def setup_module(module):
    print()

def teardewn_module(module):
    print()

4.5 fixture机制

4.5.1 测试夹具级别

夹具定义可以通过参数scope指定夹具的级别,如果不指定夹具级别,scope 默认值为function(用例级别)

function 每个函数或方法都会调用
class 每个类调用一次,一个类中存在多个方法
module 每个.py文件调用一次,一个文件中存在多个class和多个function
session 多个文件调用一次,可以跨.py文件使用,每个文件就是一个module

4.5.2 调用fixture

  1. 函数或类里面方法直接传fixture的函数名称

    import pytest
    
    @pytest.fixture(scope='function')
    def test1():
        print("前置夹具")
    
    def test_01(test1):
        print("测试函数")
    
    class Test_02:
        def test_02(self, test1):
            print("类方法")
    
  2. 使用装饰器@pytest.mark.usefixtures()

    import pytest
    
    @pytest.fixture(scope='function')
    def test1():
        print("前置夹具")
    
    @pytest.mark.usefixtures('test1')
    def test_01():
        print("测试函数")
    
    @pytest.mark.usefixtures('test1')
    class Test_01:
        def test_02(self):
            print("类方法")
        
    
  3. 叠加usefixtures

    import pytest
    
    @pytest.fixture(scope='function')
    def test1():
        print("前置夹具1")
    
    @pytest.fixture(scope='function')
    def test2():
        print("前置夹具2")
    @pytest.mark.usefixtures("test1")
    @pytest.mark.usefixtures("test2")
    # 按照顺序执行夹具
    class Test_01:
        def test_01(self):
            print("类方法")
    
  4. fixture自动执行 autouse=True

    适用于多用例情况,直接执行

    import pytest
    
    @pytest.fixture(scope='function', autore=True)
    def test1():
        print("前置夹具1")
    
    @pytest.fixture(scope='function', autore=True)
    def test2():
        print("前置夹具2")
    
    class TestCase:
        def test_01(self):
            print("类方法")
    

4.5.3 yield和终结函数

  1. yield

    @pytest.fixture(scope="function")
    def test1():
        print("开始执行")
        yield 1  # 不需要返回值时直接 yield
        print("执行结束")
        
    # 起到分割作用,yield之前的代码为setup,后面为teardown
    # 可以实现参数传递
    
    def test2(test1):
        print(test1) # 1
    

    存在多个fixture存在yield时,先按照线性顺序执行前置,执行过后,反向执行yield后的逻辑

5. conftest.py

用于管理fixture,工程根目录下设置的conftest.py文件起到全局作用,不同子目录下只在该层级以及一下目录生效

5.1 注意事项

  1. pytest会默认读取conftest.py里面的所有fixture
  2. conftest.py文件名是固定的,不能移动
  3. conftest.py只对同一个package下的所有测试用例生效
  4. 不同目录可以有自己的conftest.py,一个项目可以有多个conftest.py
  5. 测试用例文件不用手动import,pytest会自动查找

5.2 举例

conftest.py

import pytest

@pytest.fixture(score="session")
def login():
    print("登录")
    name = "test"
    token = ""
    yield name, token # 起到分割作用,yield之前的代码为setup,后面为teardown
    print("退出登录")

@pytest.fixture(autose=True)
def get_info(logins):
    name, token = logins
    print(f"打印token: {token}")

get_info(next(login()))

test1.py

def test_get_info(login):
    name, token = login
    print(f"用户名:{}, token{}")

run.py

import pytest

if __name__ == '__main__':
    pytest.main(["-s", "目录"])

6. 参数化和数据驱动

6.1 fixture传参

@pytest.fixture(scope="function", params=[1, 2, 4])
def need_data(request):
    yield request.param

def test_001(need_data):
    print(need_data)# 依次输出1, 2, 4,经历三次测试

6.2 mark.parametrize数据驱动

class Test_add:
    @pytest.mark.parametrize("arg", [1, 2, 3])
    def test_01(self, arg):
        print(arg)   # 三次测试

read_yaml.py

class Read_Yaml:
    def __init__(self, filename):
        self.filename = filename

    def read_yam(self):
        with open(self.filename, "r", encoding="utf-8") as f:
            context = yaml.load(f, Loader=yaml.Loader)
        return context

requests_paclage.py

class PacKag:
    def __init__(self, api_data):
        self.api_data = api_data

    def packaging(self):
        if self.api_data["method"] == "get":
            res = requests.request(method=self.api_data["method"],                                                    url=self.api_data["url"],
                                   params=self.api_data["params"],                                                    headers=self.api_data["headers"])
        else:
            data = json.dumps(self.api_data["body"])
            res = requests.request(method=self.api_data["method"],                             url=self.api_data["url"],
            data=data, headers=self.api_data["headers"])
        return res.json()

testcase.py

class Test_001:
    test_data = Read_Yaml(setting.yaml_data).read_yam()
    # 读取列表嵌套字典,依次取出字典,存在几个字典进行几次用例
    @allure.title("用户登录")
    @pytest.mark.parametrize("arg", test_data)
    def test_case001(self, arg):
        try:
            res = PacKag(arg).packaging()
            assert res["errorMessage"] == arg["msg"]
            logger.info("测试通过,结果为{}".format(res["errorMessage"]))
        except Exception as e:
            logger.error(e)

6.3 fixture+mark.parametrize

在fixture中实现前后置方法,使用mark进行数据驱动

@pytest.fixture(scope='function')
def add_data(request):
    print(request.param) # 根据传进来的参数依次执行前后置方法
    yield request.param["name"]
class Test_001:
    test_data = Read_Yaml(setting.authentication_yaml).read_yam()

    @allure.title("用户登录")
    @pytest.mark.parametrize("add_data", test_data, indirect=True)
    # indirect=True,可以指定数据传入指定的前后置函数
    def test_case001(self, add_data):
        try:
            res = PacKag(add_data).packaging()
            assert res["errorMessage"] == arg["msg"]
            logger.info("测试通过,结果为{}".format(res["errorMessage"]))
        except Exception as e:
            logger.error(e)

6.4 多个传入变量,列表嵌套元组

class Test_001:

    @allure.title("用户登录")
    @pytest.mark.parametrize("tt, ll", [(1, 2), (3, 4)])
    # indirect=True,可以指定数据传入指定的前后置函数
    def test_case001(self, tt, ll):
        try:
            print(tt, ll)
        except Exception as e:
            logger.error(e)
    # 第一次输出1,2   第二次输出3,4

6.5 参数组合测试

username = ["lilei", "hanmeimei"]
password = ["123456", "888888"]
@pytest.mark.parametrize("password", password)
@pytest.mark.parametrize("username", username)
def test_login(username, password):
    headers = {"Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    assert res['code'] == 1000
# 同时存在多个mark时,会采用枚举两两组合,上文存在四次测试用例

6.5 参数说明(ids)

@pytest.mark.parametrize("args, tt", [(1, 2), (3, 4)], ids=["a:{}-b:{}".format(a, b) for a, b in [(1, 2), (3, 4)]])

# 输出testcase.py::Test_002::test_case002[a:1-b:2].......

7.插件

7.1测试执行顺序:pytest-ordering

默认执行顺序从上而下,使用pytest-ordering实现自定义执行顺序

pip install pytest-ordering

import pytest

class TestOrder:

    def test_e(self):
        print("test_e")

    def test_4(self):
        print("test_4")


def test_b():
    print("test_a")

@pytest.mark.run(order=2)
def test_a():
    print("test_a")

@pytest.mark.run(order=1)
def test_2():
    print("test_2")

def test_1():
    print("test_1")


if __name__ == '__main__':
    pytest.main()

7.2 失败后重新执行:pytest-rerunfailures

测试失败后要重新运行n次,间隔n秒后执行

执行命令 pytest -v --reruns 5 --reruns-delay 1,每次等待1秒,重新执行5次

7.3 一个用例多个断言,前面失败后依然可以运行

pytest-assume

pytest.assume(1 == 1)
pytest.assume(1 == 2)
# 使用这种断言不会执行try except,详情需要实时日志

7.4 多进程并行和分布式执行

pytest-xdist

pytest -v test.py -n 5,五个进程执行

8.标记用例执行

只执行标记的部分用例,指定执行某一类或某个场景的测试用例

8.1 pytest.ini

[pytest]

markers =
    smoke: marks test as smoke
    login
    order: 下单场景
@pytest.mark.smoke
def test_01():
    print("执行test_01")

def test_02():
    print("执行test_02")

8.2 conftest.py

定义钩子函数

def pytest_configure(config):
    marker_list = [
        "smoke: ok",
        "login",
        "order: 场景"
    ]
    for marker in marker_list:
        config.addinivalue_line("markers", marker)
import pytest

# 标记测试函数
@pytest.mark.smoke
def test_01():
    print("执行test_01")

def test_02():
    print("执行test_02")

    
# 标记测试类
@pytest.mark.order
class TestOrder:
    
    def test_order(self):
        print("下单")

    def test_pay(self):
        print("支付")

        
# 多个标签 
@pytest.mark.smoke
@pytest.mark.login
def test_login():
    print("登录")

8.3 执行

pytest -m smoke 执行单个用例

pytest -m smoke and login执行多个用例

pytest -m smoke or login 执行或

pytest.main(['-m', 'smoke and login']) 不能在当前模块运行,需要新建run.py,分离执行才会生效

8.4 标记跳过

import pytest

@pytest.mark.skip(reason="不需要执行test_01")
def test_01():
    print("执行test_01")

@pytest.mark.skip(2>1, reason="如果2大于1则跳过不执行")
def test_02():
    print("执行test_02")
    
    
if __name__ == '__main__':
    pytest.main(['-s'])

8.5 标记执行失败

部分场景:对未实现的功能或者尚未修复的错误进行测试,使用@pytest.mark.xfail可以将测试用例标记为失败

pytest.mark.xfail(condition=None, reason=None, raises=None, run=True, strict=False)
condition: 预期失败的条件
reason: 失败原因,会在控制台展示
run: 默认值为True,当run为false时,pytest不会执行该用例,直接将结果标记为xfail
strict: 当 strict=False 时,如果用例执行失败,则结果标记为xfail,表示符合预期的失败;如果用例执行成功,结果标记为XPASS,表示不符合预期的成功;

当strict=True时,如果用例执行成功,结果将标记为failed。

import pytest

# run、strict都为默认,因为用例执行是失败的,所以该用例执行结果会被标记为xfail
@pytest.mark.xfail(reason="bug待修复")
def test_01():
    print("执行test_01")
    a = "hello"
    b = "hi"
    assert a == b

# run、strict都为默认,因为用例执行是通过的,所以该用例执行结果会被标记为xpass
@pytest.mark.xfail(condition=lambda: True, reason="bug待修复")
def test_02():
    print("执行test_02")
    a = "hello"
    b = "hi"
    assert a != b

# run=False,该用例不执行,直接将结果标记为xfail
@pytest.mark.xfail(reason="功能尚未开发完成", run=False)
def test_03():
    print("执行test_03")
    a = "hello"
    b = "hi"
    assert a == b

# strict=True,因为用例执行是通过的,所以结果会被标记为failed
@pytest.mark.xfail(reason="功能尚未开发完成", strict=True)
def test_04():
    print("执行test_04")
    a = "hello"
    b = "he"
    assert b in a
    
if __name__ == '__main__':
    pytest.main(['-s'])

9.实时日志(方便监控一个用例多个断言)

9.1 pytest.ini

[pytest]
log_cli = 1
log_cli_leavl = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)

9.2 直接使用pytest- o

pytest test.py -o log_cli=true -o log_cli_level=INFO

格式: -vv -o log_cli=true -o log_cli_level=INFO --log-date-format="%Y-%m-%d %H:%M:%S" --log-format="%(filename)s:%(lineno)s %(asctime)s %(levelname)s %(message)s"

10.测试报告

10.1 pytest-html

pip install pytest-html

  1. pytest.main执行

    pytest.mian(["--html=测试报告.html"])在用例文件中执行该命令不能生成测试报告,需要单独开一个run.py文件执行

  2. 命令行执行:

    pytest test.py --html=测试报告.html

    pytest test.py --html=E:测试报告.html

10.2 allue

10.2.1 安装

  1. 安装pytest-allure: pip install pytest-allure
  2. 安装allure
  3. 配置环境变量:path: D:\allure\allure-2.15.0\bin

10.2.2 特性

@allure.epic() 描述被测软件系统
@allure.feature() 描述被测软件的某个功能模块
@allure.story() 描述功能模块下的功能点和测试场景
@allure.title() 定义测试的标题
@allure.description() 测试用例的说明描述
@allure.severity() 标记测试用例级别,由高到低:blocker、critical、normal、mirnor、trivial
@allure.step() 标记通用函数使之成为测试步骤,测试方法中调用此函数的地方会像报告中输出步骤描述
allure.attach() 插入附件 allure.attach(body, name=None, attachment_type=None, extension=None),内容,名称,类型
allure.attach.file() 插入附件 allure.attach.file(source, name=None, attachment_type=None, extension=None) 内容,名称,类型
with allure.step() 标记测试步骤
allure.issue("url", name='') 跳转链接
allure.testcase() 跳转链接
 @allure.story("用户退出登录")
 @allure.title("退出登录")
 def test_logout(self):
      '''这条测试用例仅仅只是为了举例说明allure.attach.file的使用'''
        print("退出登录,并截图")
        # 截图路径
        testcase_path = (os.path.join(os.path.dirname(os.path.abspath(__file__))), "/screenshot/logout.jpg")
        allure.attach.file(
            source=testcase_path,
            name="退出登录后截图",
            attachment_type=allure.attachment_type.JPG # 图片类型
        )
        assert True

with allure.step()

 with allure.step("请求登录接口"):
        allure.attach(
                body="用户名-{},密码-{}".format(username, password),
                name="登录参数",
                attachment_type=allure.attachment_type.TEXT
            )
         res = requests.post(url=url, headers=headers, json=_data).text
         res = json.loads(res) 
           
  # 第二步,获取返回参数进行断言
 with allure.step("断言"):
       assert res['code'] == 1000
# with 方式一般用于截图或者文件
    
    
# with allure.step("步骤详情"):
      # 具体用例
# 或者装饰器,这种可以展示步骤传参
@allure.step("step:添加购物车")
def add_shopping_cart(goods_id="10086"):
    '''添加购物车'''
    print("添加购物车")

10.2.4 生成测试报告

  1. pytest.main()

    pytest.main(['test.py', '-s', '-q', '--alluredir', './result'])
    # 运行test.py测试用例,将测试结果以json的格式保存在当前目录的result文件夹中
    os.system('allure generate ./result -o ./report --clean')
    执行json数据,并生成测试报告,保存在当前目录的report文件夹中, --clean删除之前生成的测试报告
    

    run.py

    if __name__ == '__main__':
        pytest.main(['testcase/test_case.py', '-s', '-q', '--alluredir', './result'])
        os.system('allure generate ./result -o ./report --clean')
    
  2. 命令行

    pytest testcase/test_case.py --alluredir ./result

    allure generate ./result -o ./report --clean 然后 allure open ./report 或者 allure serve ./report

10.2.5 定制部分模板

  1. envionment,展示此次测试执行的环境信息

    创建envionment.properties,放在--alluredor指定的文件夹

    system=win
    python=3.7.7
    version=1.0.1
    host=127.0.0.1
    test=孔振国
    
  2. categories,用于定制缺陷分类,创建categories.json配置,跟上一个相同目录

    [
      {
        "name": "Passed tests", 
        "matchedStatuses": ["passed"]
      },
      {
        "name": "Ignored tests",
        "matchedStatuses": ["skipped"]
      },
      {
        "name": "Infrastructure problems",
        "matchedStatuses": ["broken", "failed"],
        "messageRegex": ".*bye-bye.*"
      },
      {
        "name": "Outdated tests",
        "matchedStatuses": ["broken"],
        "traceRegex": ".*FileNotFoundException.*"
      }
    ]
    

11.CI/CD jenkins

11.1 docker 安装jenkins并更新版本

docker pull jenkens/jenkins

docker run -it --name jenkins -p 8080:8080 -p 5000:5000 jenkins/jenkins

docker cp jenkins.war jenkins/jenkins: var/share/jenkins

docker restart jenkins/jenkins

11.2 安装Allure插件并进行全局工具配置

本地安装直接取消自动安装并写入allure安装目录

11.3 新建windows节点,并启动

​ 新建本地运行环境

curl.exe -sO http://47.92.76.123:8080/jnlpJars/agent.jar

java -jar agent.jar -jnlpUrl http://47.92.76.123:8080/computer/windows/jenkins-agent.jnlp -secret 724f3a87c3cf0c7278c35d365a28c9b32345c1fccc5859dc2a3ac7a3546714a4 -workDir "E:\Jenkins"

11.4 新建任务

  1. 限制项目的运行节点
  2. 使用自定义工作空间
  3. 构建前命令 pytest testcase.py -vs --alluredir ./allure
  4. 构建后添加Allure Report 指定json数据目录,并指定生成报告目录

12.钩子函数

12.1 切换测试环境

  1. Hook方法

    conftest.py

    注册一个自定义的命令行参数

    def pytest_addoption(parser):
        parser.addoption("--env", action="store", default="url", help="将--env添加到pytest配置中")
        # action="store",允许用户存储任何类型的值
        # default 在--env不填值时,默认值
        # help 说明
    
    @pytest.fixture(scope="session")
    def get_env(request):
        """从配置对象中读取自定义参数的值"""
        return request.config.getoption("--env")
    
    # 可以不用写
    @pytest.fixture(autouse=True)
    def set_env(get_env):
        """将自定义参数的值写入全局配置文件"""
        with open(ENV_TXT_FILE, 'w', encoding='utf-8') as f:
            f.write(get_env)
    

    test_demo.py

    def test_001(get_env):
        print(get_env)
    # 传入主机名,测试用例中可以通过使用不同的主机切换测试环境
    
  2. 使用pytest-base-url插件

    1. 安装pytest-base-url pip install pytest-base-url -i https://pypi.douban.com/simple

    2. 将base-url参数传入fixture函数中

      @pytest.fixture
      def driver_setup(base_url):
          try:
              URL = base_url
              start_chrome(URL, options=browser_options(), headless=False)
              driver = get_driver()
          except Exception as e:
              log.error(e)
          else:
              yield driver
      # 如果发生异常,对异常操作,如果正常,执行eles里面的逻辑
      #或者直接使用
      def test_001(base_url):
          print base_url
      
    3. pytest命令行传参

      pytest --base-url https://www.cnblogs.com/

标签:py,allure,管理,print,用例,pytest,test,def
From: https://www.cnblogs.com/leaveName/p/18496253

相关文章

  • 基于Django+Python的宾馆管理系统设计与实现
    项目运行需要先安装Python的相关依赖:pymysql,Django==3.2.8,pillow使用pipinstall安装第一步:创建数据库第二步:执行SQL语句,.sql文件,运行该文件中的SQL语句第三步:修改源代码中的settings.py文件,改成自己的mysql数据库用户名和密码第四步:运行命令:pythonmanage.pyrunser......
  • Springbootspringboot微服务车站寄存柜管理系统oan92
    Springbootspringboot微服务车站寄存柜管理系统oan92本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,寄存柜,计价规则,用户等级,寄存订单,寄存结束,用户反馈,反馈回复,寄存柜位置开题报告内容......
  • jsp ssm 共享充电宝管理系统 充电宝平台 电源管理 源码 web java
    一、项目简介本项目是一套基于SSM的共享充电宝管理系统,主要针对计算机相关专业的和需要项目实战练习的Java学习者。包含:项目源码、数据库脚本、软件工具等。项目都经过严格调试,确保可以运行!二、技术实现​后端技术:Spring、SpringMVC、MyBatis前端技术:JSP、HTML、CSS、......
  • 适合数据库管理者的七个空间数据库(在2021版本中)
    适合数据库管理者的七个空间数据库(在2021版本中)最新推荐文章于 2024-09-0610:57:43 发布fmechina于2022-01-1116:43:00发布阅读量8.6k收藏23点赞数3分类专栏:默认分类文章标签:数据库postgresqldatabase  默认分类专栏收......
  • 会话管理-帮你搞懂cookie(Html版本)
    前端JavaScript中的cookie是一种用于在浏览器和服务器之间传递数据的机制。它们通常用于跟踪用户的会话信息,如登录状态、购物车内容等。Cookie的使用非常广泛,几乎所有的web应用程序都会使用到cookie来保存用户信息或者偏好设置‌。【注:dom和jdom的概念和转换看这篇-->】后端入......
  • 【VMware VCF】使用 PowerShell 脚本管理 SDDC Manager 中的软件包。
    SDDCManager中有两种类型的软件包,分别是“升级/修补包(PATCH)”和“安装包(INSTALL)”。“升级/修补包”用于执行VCF环境中组件的升级/修补,这个已经在前面的文章中使用过了;而另外一种“安装包”,这种包用于在VCF环境中部署其他集成解决方案,比如VMwareAriaSuiteLifecycleMana......
  • 【JAVA毕业设计】基于Vue和SpringBoot的课程作业管理系统
    本文项目编号T023,文末自助获取源码\color{red}{T023,文末自助获取源码}......
  • 为什么需要证件管理软件系统?建筑企业证照管理系统有什么特点?
    大多数企业在投标过程中面临一些普遍的问题:每次准备投标时,都需要耗费大量时间和精力来重新整合所有相关资质文件,包括企业资质、项目案例、投标人员证书、奖项和各类认证。而且,常常在临近投标时,才发现某些资质已经过期或存在缺失,导致关键时刻措手不及。此外,由于缺乏有效的管理,......
  • Spring Boot论坛网站:开发、部署与管理
    3系统分析3.1可行性分析通过对本论坛网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本论坛网站采用SSM框架,JAVA作为开发语言,是基于WEB平台的B/S架构系统。(1)Java......
  • springboot优质鸭梨的培育管理系统-计算机毕业设计源码92834
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程2.2.2业务流程2.3 系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4 系统用例分析2.5本章小结3 系统......