百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

软件测试 | pytest测试框架(pytest框架原理)

ccwgpt 2024-11-02 11:02 22 浏览 0 评论

简介

pytest 是一个全功能的 Python 测试工具,可以帮助您编写更好的程序。它与 Python 自带的 unittest 测 试框架类似,但 pytest 使用起来更简洁和高效,并且兼容 unittest 框架。pytest 支持简单的单元测试和 复杂的功能测试,可以结合 requests 实现接口测试,结合 selenium、appium 实现自动化功能测试,使 用 pytest 结合 Allure2 集成到 Jenkins 中可以实现持续集成。pytest 支持三百多种插件(可以访问网 址:http://plugincompat.herokuapp.com/ 查看插件),可以访问网址:https://docs.pytest.org/ 查看帮助文 档。

安装

pip install -U pytest

查看版本

pytest --version

用例的识别与运行

用例编写规范

  • 测试文件以 test_开头或以 _test 结尾
  • 测试类以 Test 开头,并且不能带有 __init__ 方法
  • 测试函数以 test_开头
  • 断言使用基本的 assert 即可

创建一个 python 文件,命名以 test_ 开头(或者以 _test 结尾),创建测试方法以 test_ 开 头,测试类需要以 Test 开头。

创建文件名为 test_add.py 文件,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def add(x, y):
 return x + y
def test_add():
 assert add(1, 10) == 11
 assert add(1, 1) == 2
 assert add(1, 99) == 100
class TestClass:
 def test_one(self):
 x = "this"
assert "h" in x
 def test_two(self):
 x = "hello"
 assert hasattr(x, "check")

命令行进入到这个文件所在的路径,运行 test_add.py 文件。

可以直接使用 pytest 命令运行,pytest 会找当前目录以及递归查找子目录下所有的 test_*.py 或 *_test.py 的文件,把其当作测试文件。在这些文件里,pytest 会收集符合编写规范的函数、类以及 方法,当作测试用例并且执行。

执行如下:

 $ pytest
....
test_add.py ..F [100%]
....
self = <test_cases.test_add.TestClass object at 0x1091810d0>
 def test_two(self):
 x = "hello"
> assert hasattr(x, "check")
E AssertionError: assert False
E + where False = hasattr('hello', 'check')
test_add.py:18: AssertionError
===================================================== 1 failed, 2 passed in 0.05s
...

结果分析:

执行结果中, F 代表用例未通过(断言错误), . 代表用例通过。如果报错会有详细的错误信息。 pytest 也支持运行 unittest 模式的用例。

运行参数

pytest 提供了很多参数,可以使用 pytest --help 来查看帮助文档,下面介绍几种常用的参数:

  • -v 参数

打印详细运行日志信息,一般在调试的时候加上这个参数,终端会打印出每条用例的详细日志信息,方 便定位问题。使用方法如下:

pytest -v
  • -s 参数

控制台输出结果,当你的代码里面有 print 输出语句,如果想在运行结果中打印 print 输出的代码 (默认控制台是不输出打印结果的),在运行的时候可以添加 -s 参数,一般在调试的时候使用,使 用方法如下:

pytest -s
  • -k 参数

只执行含有某个关键字的测试用例。

控制台输出结果,当你的代码里面有 print 输出语句,如果想在运行结果中打印 print 输出的代码 (默认控制台是不输出打印结果的),在运行的时候可以添加 -s 参数,一般在调试的时候使用,使 用方法如下:

pytest -k "类名"
pytest -k "方法名"
pytest -k "类名 and not 方法名" #运行类里所有的方法,不包含某个方法

注意:如果是 windows 系统, -k 后面的字符串参数必须用双引号。

  • -x 参数

遇到用例失败立即停止运行。

应用场景:

在回归测试过程中,假如一共有 10 条基础用例,当开发人员打完包提交测试的时候,需要先运行这 10 条基础用例,全部通过才能提交给测试人员正式测试。如果有一条用例失败,就将这个版本打回给 开发人员。这时就可以添加 -x 参数,一旦发现有失败的用例即中止运行。

使用方法如下:

pytest -x
  • --maxfail 参数

用例失败个数达到阈值停止运行。 应用场景: 在回归测试过程中,假如一共有 10 条基础用例,当开发人员打完包提交测试的时候,需要先运行这 10 条基础用例,全部通过才能提交给测试人员正式测试。如果运行过程中有 [num] 条用例失败,即 中止运行,后面测试用例都放弃执行,直接退出。这时可以使用 --maxfail 参数。

具体用法:

pytest --maxfail=[num]
  • -m参数

将运行有 @pytest.mark.[标记名] 这个标记的测试用例。

应用场景:

在自动化测试过程中可以将测试用例添加标签进行分类,比如登录功能、搜索功能、购物车功能、订单 结算功能等,在运行的时候可以只运行某个功能的所有的测试用例,比如这个版本只想验证登录功能, 那就在所有登录功能的测试用例方法上面加上装饰符 @pytest.mark.login ,运行的时候使用命令添 加一个 -m 参数,例如执行 pytest -m login 命令就可以只执行登录功能这部分的测试用例。

使用方法如下:

pytest -m[标记名]

运行模式

pytest 提供了多种运行模式,让开发和调试更得心应手。指定某个模块,执行单独一个 pytest 模块。

应用场景:

在编写测试用例的时候,经常会单独调试某个类,或者某个方法,这时可以使用 Pycharm 里面自带的调 试方式,点击用例方法名前面的绿色按钮,也可以使用命令行的方式单独运行某个用例。

pytest 中可以使用 pytest 文件名.py 单独执行某个 python 文件,也可以使用 pytest 文件名.py:: 类名 单独执行某个文件中的类,使用 pytest 文件名.py::类名::方法名 单独执行类中的某个方法。 使用方法如下:

pytest 文件名.py
pytest 文件名.py::类名
pytest 文件名.py::类名::方法名

在Pycharm中运行pytest用例

打开 Pycharm -> 设置 - Tools -> Python Integrated Tools -> Testing: pytest

首先设置成 pytest ,需要安装 pytest,可以直接按照这个页面的提示点击 fix ,也可以在 Project interpreter 里面添加 pytest 安装包。安装完 pytest 之后,符合规则的测试用例都能被识别出来并且会显 示出一个三角形的执行按钮,点击这个按钮也能执行某个方法或者某个类。例如:

pytest 框架结构

执行用例前后会执行 setup,teardown 来完成用例的前置和后置条件。pytest 框架中使用 setup, teardown 更灵活,按照用例运行级别可以分为以下几类:

模块级(setup_module/teardown_module)在模块始末调用

函数级(setup_function/teardown_function)在函数始末调用(在类外部)

类级(setup_class/teardown_class)在类始末调用(在类中)

方法级(setup_method/teardown_methond)在方法始末调用(在类中)

方法级(setup/teardown)在方法始末调用(在类中)

调用顺序

setup_module > setup_class >setup_method > setup > teardown > teardown_method > teardown_class > teardown_module

画图说明

验证上面的执行顺序,看下面的案例。

创建文件名为 test_module.py ,代码如下:

# 模块级别
def setup_module():
 print("setup module")
def teardown_module():
 print("teardown module")
class TestDemo:
 # 执行类 前后分别执行setup_class teardown_class
 def setup_class(self):
 print("TestDemo setup_class")
 def teardown_class(self):
 print("TestDemo teardown_class")
 # 每个类里面的方法前后分别执行 setup, teardown
 def setup(self):
 print("TestDemo setup")
 def teardown(self):
 print("TestDemo teardown")
 def test_demo1(self):
 print("test demo1")
 def test_demo2(self):
 print("test demo2")
class TestDemo1:
 def test_demo3(self):
 print("test demo3")

运行结果:

setup module
TestDemo setup_class
TestDemo setup
test demo1
TestDemo teardown
TestDemo setup
test demo2
TestDemo teardown
TestDemo teardown_class
test demo3
teardown module

setup_module 和 teardown_module 在整个模块只执行一次,setup_class 和 teardown_class 在类里面只 执行一次,setup_method/setup 和 teardown_method/teardown 在每个方法前后都会调用。一般用的最多 的是方法级别(setup/teardown)和类级别(setup_class/teardown_class)。

pytest fixtures

pytest 中可以使用 @pytest.fixture 装饰器来装饰一个方法,被装饰的方法名可以作为一个参数传入 到测试方法中。可以使用这种方式来完成测试之前的初始化,也可以返回数据给测试函数。

将 FIXTURE 作为函数参数

通常使用 setup 和 teardown 来进行资源的初始化。如果有这样一个场景,测试用例 1 和 测试用例 3 需要依赖登录功能,测试用例 2 不需要依赖登录功能。这种场景 setup,teardown 无法实现,可以使用 pytest fixture 功能,在方法前面加个 @pytest.fixture 装饰器,加了这个装饰器的方法可以以参数的 形式传入到方法里面执行。例如在登录的方法,加上 @pytest.fixture 这个装饰器后,将这个用例 方法名以参数的形式传到方法里,这个方法就会先执行这个登录方法,再去执行自身的用例步骤,如果 没有传入这个登录方法,就不执行登录操作,直接执行已有的步骤。

创建一个文件名为 “test_fixture.py”,代码如下;

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
@pytest.fixture()
def login():
 print("这是个登录方法")
 return ('tom','123')
@pytest.fixture()
def operate():
 print("登录后的操作")
def test_case1(login,operate):
 print(login)
 print("test_case1,需要登录")
def test_case2():
 print("test_case2,不需要登录 ")
def test_case3(login):
 print(login)
 print("test_case3,需要登录")

在上面的代码中,测试用例 test_case1 和 test_case3 分别增加了 login 方法名作为参数,pytest 会发现 并调用 @pytest.fixture 标记的 login 功能,运行测试结果如下:

test_fixture.py::test_case1 这是个登录方法
登录后的操作
PASSED [ 33%]('tom', '123')
test_case1,需要登录
test_fixture.py::test_case2 PASSED \
[ 66%]test_case2,不需要登录
test_fixture.py::test_case3 这是个登录方法
PASSED [100%]('tom', '123')
test_case3,需要登录
============================== 3 passed in 0.02s ===============================
Process finished with exit code 0

从上面的结果可以看出,test_case1 和 test_case3 运行之前执行了 login 方法,test_case2 没有执行这个 方法。

指定范围内共享

fixture 里面有一个参数 scope,通过 scope 可以控制 fixture 的作用范围,根据作用范围大小划分: session> module> class> function,具体作用范围如下:

 - function 函数或者方法级别都会被调用
 - class 类级别调用一次
 - module 模块级别调用一次
 - session 多个文件/包调用一次(可以跨.py文件调用,每个.py文件就是module)

例如整个模块有很多条测试用例,需要在全部用例执行之前打开浏览器,全部执行完之后去关闭浏览 器,打开和关闭操作只执行一次,如果每次都重新执行打开操作,会非常占用系统资源。这种场景除了 setup_module/teardown_module 可以实现,还可以通过设置模块级别的 fixture 装饰器 (@pytest.fixture(scope="module"))来实现。

scope='module'

fixture 参数 scope='module' ,module 作用是整个模块都会生效。

创建文件名为 test_fixture_scope.py ,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
# 作用域:module是在模块之前执行, 模块之后执行
@pytest.fixture(scope="module")
def open():
 print("打开浏览器")
 yield
 print("执行teardown !")
 print("最后关闭浏览器")
@pytest.mark.usefixtures("open")
def test_search1():
 print("test_search1")
 raise NameError
 pass
def test_search2(open):
 print("test_search2")
 pass
def test_search3(open):
 print("test_search3")
 pass

代码解析:

@pytest.fixture() 如果不写参数,参数默认 scope='function' 。当 scope='module' 时,在当前 .py 脚本里面所有的用例开始前只执行一次。scope 巧妙与 yield 关键字结合使用,相当于 setup 和 teardown 方法。还可以使用 @pytest.mark.usefixtures 装饰器,传入前置函数名作为参数。

运行结果如下:

test_fixture_yield.py::test_search1 打开浏览器
FAILED [ 33%]test_search1
test_fixture_yield.py:13 (test_search1)
open = None
 def test_search1(open):
 print("test_search1")
> raise NameError
E NameError
test_fixture_yield.py:16: NameError
test_fixture_yield.py::test_search2 PASSED \
[ 66%]test_search2
test_fixture_yield.py::test_search3 PASSED \
[100%]test_search3
执行teardown !
最后关闭浏览器
...
open = None
 def test_search1(open):
 print("test_search1")
> raise NameError
E NameError
test_fixture_yield.py:16: NameError
...

从上面运行结果可以看出, scope="module" 与 yield 结合,相当于 setup_module 和 teardown_module 方法。整个模块运行之前调用了 open() 方法中 yield 前面的打印输出“打开浏览 器”,整个运行之后调用了 yield 后面的打印语句“执行 teardown !”与“关闭浏览器”。

通过 yield 来唤醒 teardown 的执行,如果用例出现异常,不影响 yield 后面的 teardown 执行。

CONFTEST.PY 文件

fixture scope 为 session 级别是可以跨 .py 模块调用的,也就是当我们有多个 .py 文件的用例时, 如果多个用例只需调用一次 fixture,可以将 scope='session' ,并且写到 conftest.py 文件里。 写到 conftest.py 文件可以全局调用这里面的方法。使用的时候不需要导入 conftest.py 这个文 件。使用 conftest.py 的规则:

1. conftest.py 这个文件名是固定的,不可以更改。

2. conftest.py 与运行用例在同一个包下,并且该包中有 __init__.py 文件

3.使用的时候不需要导入 conftest.py ,pytest 会自动识别到这个文件

4.放到项目的根目录下可以全局调用,放到某个 package 下,就在这个 package 内有效。

案例

运行整个项目下的所有的用例,只执行一次打开浏览器。执行完所有的用例之后再执行关闭浏览器,可 以在这个项目下创建一个 conftest.py 文件,将打开浏览器操作的方法放在这个文件下,并添加一个 装饰器 @pytest.fixture(scope="session") ,就能够实现整个项目所有测试用例的浏览器复用,案 例目录结构如下:

创建目录 test_scope,并在目录下创建三个文件 conftest.py , test_scope1.py 和 test_scope2.py 。 conftest.py 文件定义了公共方法,pytest 会自动读取 conftest.py 定义的方法,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
@pytest.fixture(scope="session")
def open():
 print("打开浏览器")
 yield
 print("执行teardown !")
 print("最后关闭浏览器")

创建“test_scopel.py”文件,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
def test_search1(open):
 print("test_search1")
 pass
def test_search2(open):
 print("test_search2")
 pass
def test_search3(open):
 print("test_search3")
 pass
if __name__ == '__main__':
 pytest.main()

创建文件“test_scope2.py”,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
class TestFunc():
 def test_case1(self):
 print("test_case1,需要登录")
def test_case2(self):
 print("test_case2,不需要登录 ")
 def test_case3(self):
 print("test_case3,需要登录")

打开 cmd,进入目录 test_scope/,执行如下命令:

pytest -v -s

或者

pytest -v -s test_scope1.py test_scope2.py

执行结果如下:

省略...
collected 6 items
test_scope1.py::test_search1 打开浏览器
test_search1
PASSED
test_scope1.py::test_search2 test_search2
PASSED
test_scope1.py::test_search3 test_search3
PASSED
test_scope2.py::TestFunc::test_case1 test_case1,需要登录
PASSED
test_scope2.py::TestFunc::test_case2 test_case2,不需要登录
PASSED
test_scope2.py::TestFunc::test_case3 test_case3,需要登录
PASSED执行teardown !
最后关闭浏览器
省略后面打印结果...

自动执行FIXTURE

如果每条测试用例都需要添加 fixture 功能,则需要在每一条要用例方法里面传入这个 fixture 的名字, 这里就可以在装饰器里面添加一个参数 autouse='true' ,它会自动应用到所有的测试方法中,只是这 里没有返回值。 使用方法,在方法前面加上装饰器,如下:

@pytest.fixture(autouse="true")
def myfixture():
 print("this is my fixture")

@pytest.fixture 里设置 autouse 参数值为 true(默认 false),每个测试函数都会自动调用这个前置 函数。 创建文件名为“test_autouse.py”,代码如下:

# coding=utf-8
import pytest
@pytest.fixture(autouse="true")
def myfixture():
 print("this is my fixture")
class TestAutoUse:
 def test_one(self):
 print("执行test_one")
 assert 1 + 2 == 3
 def test_two(self):
 print("执行test_two")
 assert 1 == 1
 def test_three(self):
 print("执行test_three")
 assert 1 + 1 == 2

执行上面这个测试文件,结果如下:

...
test_a.py::TestAutoUse::test_one this is my fixture
执行test_one
PASSED
test_a.py::TestAutoUse::test_two this is my fixture
执行test_two
PASSED
test_a.py::TestAutoUse::test_three this is my fixture
执行test_three
PASSED
...

从上面的运行结果可以看出,在方法 myfixture() 上面添加了装饰器 @pytest.fixture(autouse="true") ,测试用例无须传入这个 fixture 的名字,它会自动在每条用例 前执行这个 fixture。

FIXTURE 传递参数

测试过程中需要大量的测试数据,如果每条测试数据都编写一条测试用例,用例数量将是非常庞大的。 一般我们在测试过程中会将测试用到的数据以参数的形式传入到测试用例中,并为每条测试数据生成一 个测试结果。这时候可以使用 fixture 的参数化功能,在 fixture 方法加上装饰器 @pytest.fixture(params=[1,2,3]) ,就会传入三个数据 1、2、3,分别将这三个数据传入到用例当 中。这里传入的数据类型是个列表。传入的数据需要使用一个固定的参数名 request 来接收。

创建文件名为“test_params.py”,代码如下:

import pytest
@pytest.fixture(params=[1, 2, 3])
def data(request):
 return request.param
def test_not_2(data):
 print(f"测试数据:{data}")
 assert data < 5

运行结果如下:

...
test_params.py::test_not_2[1]PASSED [ 33%]测试数据:1
test_params.py::test_not_2[2] PASSED [ 66%]测试数据:2
test_params.py::test_not_2[3] PASSED [100%]测试数据:3
...

从运行结果可以看出,对于 params 里面的每个值,fixture 都会去调用执行一次,使用 request.param 来 接受参数化的数据,并且为每一个测试数据生成一个测试结果。在测试工作中使用这种参数化的方式, 代码量会大大的减少,并且便于阅读与维护。

第三方插件介绍

控制用例的执行顺序

当一个目录下有很多模块,甚至有很多子目录。每个目录下也有大量的测试用例。pytest 加载所有的测 试用例的顺序是按照 pytest 的自定义的规则(不同的模块间是按照模块名字的 ASCII 码顺序排列,同 一模块间是按照定义的前后顺序加载的)。如果想指定用例的顺序,可以使用 pytest-ordering 插件,指 定用例的执行顺序只需要在测试用例的方法前面加上装饰器 @pytest.mark.run(order=[num]) 设置 order 的对应的 num 值,它就可以按照 num 的大小顺序来执行(由小到大的顺序执行,负数反之)。

应用场景:

有时运行测试用例需要指定它的顺序,比如有些场景需要先要登录,才能执行后续的流程(比如购物流 程,下单流程),这时就需要指定测试用例的顺序。通过 pytest-ordering 这个插件可以完成用例 顺序的指定。

安装

pip install pytest-ordering

案例

创建一个测试文件“test_order.py”,代码如下

import pytest
class TestPytest(object):
 @pytest.mark.run(order=-1)
 def test_two(self):
 print("test_two,测试用例")
 @pytest.mark.run(order=3)
 def test_one(self):
 print("test_one,测试用例")
 @pytest.mark.run(order=1)
 def test_three(self):
 print("\ntest_three,测试用例")

执行结果,如下查看执行顺序:

省略...
test_order.py::TestPytest::test_three
test_order.py::TestPytest::test_one
test_order.py::TestPytest::test_two
省略...

从上面的执行结果可以看出,执行时以 order 的顺序执行:order=1,order=3,order=-1。(1 最先执 行,-1 代表倒数第一个执行)

多线程并行与分布式执行

应用场景:

假如项目中有测试用例 1000 条,一条测试用例需要执行 1 分钟,一个测试人员需要 1000 分钟才能 完成一轮回归测试。通常我们会用人力成本换取时间成本,加几个人一起执行,时间就会缩短。如果 10 人一起执行只需要 100 分钟,这就是一种并行测试,分布式的场景。

pytest-xdist 是 pytest 分布式执行插件,这款插件允许用户将测试并发执行(进程级并发),使用 这款插件执行用例是随机的,为了保证各个测试用例能在各自独立进程里正确的执行,应该保证测试用 例的独立性(这也符合测试用例设计的最佳实践)。

安装

pip install pytest-xdist

多个 CPU 并行执行用例,需要在 pytest 后面添加 -n 参数,如果参数为 auto,会自动检测系统的 CPU 数目。如果参数为数字,则指定运行测试的处理器进程数。

pytest -n auto
pytest -n [num]

案例

某个项目有 200 条测试用例,每条测试用例之间没有关联关系,互不影响。这 200 条测试用例需要在 1 小时之内测试完成,可以加个 -n 参数,使用多 CPU 并行测试。

运行方法

pytest -n 4

进入到项目目录下,执行 pytest 可以将项目目录下所有测试用例识别出来并且运行,加上 -n 参数,可 以指定 4 个 CPU 并发执行。如果设置的 CPU 数大于系统 CPU 个数,则会按照当前 CPU 的实际个数 执行.

结合 PYTEST-HTML 生成测试报告

测试报告通常在项目中尤为重要,报告可以体现测试人员的工作量,开发人员可以从测试报告中了解缺 陷的情况,因此测试报告在测试过程中的地位至关重要,测试报告为纠正软件存在的质量问题提供依 据,为软件验收和交付打下基础。

测试报告根据内容的侧重点,可以分为 “版本测试报告” 和 “总结测试报告”。执行完 pytest 测试 用例,可以使用 pytest-html 插件生成 HTML 格式的测试报告。

安装

pip install pytest-html

执行方法

pytest --html=path/to/html/report.html

结合pytest-xdist使用

pytest -v -s -n 3 --html=report.html --self-contained-html

生成测试报告

如下图:

生成的测试报告最终是 HTML 格式,报告内容包括标题、运行时间、环境、汇总结果以及用例的通过 个数、跳过个数、失败个数、错误个数,重新运行个数、以及错误的详细展示信息。 报告会生成在运行脚本的同一路径下,需要指定路径添加 --html=path/to/html/report.html 这个 参数配置报告的路径。如果不添加 --self-contained-html 这个参数,生成报告的 CSS 文件是独立 的,分享的时候容易数据丢失。

assert 断言使用

编写代码时,我们经常会做出一些假设,断言就是用于在代码中验证这些假设。断言表示为一些布尔表 达式,测试人员通常会加一些断言来判断中间过程的正确性。

断言支持最常见的表达式,包括调用,属性,比较以及二元和一元运算符。 Python 使用 assert(断 言)用于判断一个表达式的正确与否,在表达式条件为 False 的时候触发异常。

使用方法

assert True #断言为真
assert not True #断言不为真

案例如下:

assert "h" in "hello" #判断 h 在 hello 中
assert 5>6 #判断 5>6 为真
assert not True #判断不为真
assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'} #判断两个集合相等

如果没有断言,没有办法判定用例中每一个测试步骤结果的正确性。在项目中适当的使用断言对代码的 结构、属性、功能、安全性等场景检查与验证。

搜索微信公众号:TestingStudio霍格沃兹的干货都很硬核

相关推荐

MFC、Qt、WPF?该用哪个?(mfc和wpf区别)

MFC、Qt和WPF都是流行的框架和工具,用于开发图形用户界面(GUI)应用程序。选择哪个框架取决于你的具体需求和偏好。MFC(MicrosoftFoundationClass)是微软提供的框架,...

一款WPF开发的通讯调试神器(支持Modbus RTU、MQTT调试)

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍Wu.CommTool是一个基于C#、WPF、Prism、MaterialDesign...

关于面试资深C#、WPF开发工程师的面试流程和问题

一、开场(2-3分钟)1.欢迎应聘者,简单介绍公司和面试流程。2.询问应聘者是否对公司或岗位有初步的问题。二、项目经验与技术应用(10-20分钟)1.让应聘者详细介绍几个他参与过的C#、...

C# WPF MVVM模式Prism框架下事件发布与订阅

01—前言处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Prism提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事件进行...

WPF 机械类组件动画制作流程简述(wps上怎么画机械结构简图)

WPF机械类组件动画制作流程简述独立观察员2025年3月4日一、创建组件创建组件用户控件,将组件的各部分“零件”(图片)拼装在一起,形成组件的默认状态:二、给运动部分加上Rend...

C#上位机WinForm和WPF选哪个?工控老油条的&quot;血泪史&quot;

作为一个从互联网卷进工控坑的"跨界难民",在这会摸鱼的时间咱就扯一下上位机开发选框架这档子破事。当年我抱着WPF的酷炫动画一头扎进车间,结果被产线老师傅一句"你这花里胡哨的玩意...

【一文扫盲】WPF、Winform、Electron有什么区别?

近年来,随着软件开发的不断发展,开发人员面临着选择适合他们项目的各种框架和工具的挑战。在桌面应用程序开发领域,WPF、Winform和Electron是三个备受关注的技术。本文将介绍这三者的区别,帮助...

一个开源、免费、强大且美观的WPF控件库

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍HandyControl是一套基于WPF(WindowsPresentationF...

WPF 根据系统主题自动切换浅色与深色模式

WPF根据系统主题自动切换浅色与深色模式控件名:Resources作者:WPFDevelopersOrg-驚鏵原文链接[1]:https://github.com/WPFDevelopers...

WPF与WinForm的本质区别(wpf与maui)

在Windows应用程序开发中,WinForm和WPF是两种主要的技术框架。它们各自有不同的设计理念、渲染机制和开发模式。本文将详细探讨WPF与WinForm的本质区别,并通过示例进行说明。渲染机制W...

Win10/Win11效率神器再进化:微软发布PowerToys 0.90.0版本

IT之家4月1日消息,微软今天(4月1日)更新PowerToys,在最新发布的0.90.0版本中,修复多个BUG之外,引入多项功能更新,为Windows10、Windows...

一款非常漂亮的WPF管理系统(wpf架构及特性)

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!WPFManager项目介绍该项目是一款WPF开发的管理系统,数据库采用的MSSqlserv...

WPF 实现描点导航(wpf按钮的点击事件)

WPF实现描点导航控件名:NavScrollPanel作者:WPFDevelopersOrg-驚鏵原文链接[1]:https://github.com/WPFDevelopersOrg/WPF...

微软更新基于Win11的Validation OS 2504:增强 .NET与WPF

IT之家5月1日消息,科技媒体NeoWin今天(5月1日)发布博文,报道称微软公司更新基于Windows11的ValidationOS,增强支持.NET和WPF,并优...

WPF的技术架构与优势(wpf的前景)

WindowsPresentationFoundation(WPF)是一个现代化的用户界面框架,专为构建Windows应用程序而设计。它通过分层的技术架构和丰富的功能集,提供了全面的应用程...

取消回复欢迎 发表评论: