Web UI自动化测试之PO篇
点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快本文大纲截图1、PO模式基本介绍概念PO是Page Object的缩写PO模式是自动化测试项目开发实践的最佳设计模式之一。作用通过对界面元素的封装减少冗余代码同时在后期维护中若元素定位发生变化 只需要调整页面元素封装的代码提高测试用例的可维护性、可读性。2、PO模式核心思想PO模式核心思想方法封装。概念 方法封装是将一些有共性的或多次被使用的代码提取到一个方法中供其他地方调用目的 用最少的代码实现最多的功能好处避免代码冗余容易维护隐藏代码实现的细节套路1确定方法的存放位置找位置2给方法起个合适名字起名字3放入要封装的代码内容放代码4确认是否需要参数和返回值确必要5调用封装好的方法使用做调用PO模式学习思路采用版本迭代的方式来学习便于对不同版本的优缺点进行对比和理解。案例 对TPshop项目的登录模块进行自动化测试。登录模块包含了很多测试用例如账号不存在、密码错误、验证码错误、登录成功等从中选取代表性的用例来演示。选择的测试用例账号不存在1点击首页登录链接进入登录页面2输入一个不存在的用户名3输入密码4输入验证码5点击登录按钮6获取错误提示信息密码错误1点击首页登录链接进入登录页面2输入用户名3输入一个错误的密码4输入验证码5点击登录按钮6获取错误提示信息版本迭代V1不使用任何设计模式和单元测试框架V2使用PyTest管理用例并删除多余的注释掉的代码1按模块新建测试类2提取出setup和teardown函数中的方法内容如setup实例化浏览器对象driver打开网页最大化浏览器设置隐式等待teardown暂停3秒、关闭/退出浏览器3提取出setup_class和teardown_class函数中的方法内容将共同的步骤打开首页、点击登录进入登录页面 提取到setup函数中注释掉两个函数中的“ # 1、点击首页登录链接进入登录页面”代码V3使用方法封装的思想对代码进行优化。定义获取驱动对象的工具类封装“获取弹出框的提示消息”。V4PO页面元素封装步骤1对应页面创建页面 PO 代码文件命名规则页面功能_page.py例如login_page.py2定义三个类格式对象层XxxPage、操作层XxxHandle、业务层XxxTask3对象层init 方法中获取浏览器对象;自定义方法封装元素定位方法;封装元素定位方法需要添加返回值4操作层init 方法获取对象层对象根据类名写对应变量名;自定义方法封装元素操作方法。5业务层init 方法获取操作层对象根据类名写对应变量名自定义方法封装测试业务逻辑。6在测试用例文件中实例化业务层对象调用测试业务方法执行测试V5将元素的定位方法及特征值封装成属性能够实现集中管理目标元素的定位方法及特征如利用元素定位方法find_element和By将page页面元素信息集中放在page的__init__文件中。V6PO模式深入封装把共同操作提取封装到父类中子类直接调用父类的方法page页面的公共方法初始化方法、查找元素方法、点击元素方法、输入方法、获取文本方法、截图方法 ......封装工具类get_driver、get_logger、read_txt、read_json......3、PO模式设计说明模式说明说明PO模式又可以叫POM是 UI 自动化测试中一个非常流行的设计模式代码套路核心将元素定位、操作、业务逻辑 拆分为三个层面每个曾铭对应一个单独的类然后通过调用完成最终的测试执行行为的过程。好处就是有元素变化只需要维护每一个Page就行了测试步骤变化只需要维护TestCase即可设计步骤1首先抽象封装一个Base类这个基类拥有一些指向Webdriver实例的属性然后每一个Page继承基类Base可以通过driver管理每一个Page中的元素而且在Page中将这些操作封装为一个一个的方法。2Page类封装页面元素对象继承Base类调用Base类中封装的操作元素的方法并组合业务流程方法供TestCase类调用。3TestCase继承unittest里面的TestCase类并且依赖page类进行组织测试步骤的工作。4、PO模式三层结构操作层基类base操作层对元素操作方法封装命名举例模块名base.py函数名class Base:方法名def base_find():、def base_click():page页面一些公共的方法初始化方法查找元素方法点击元素方法输入方法获取文本方法截图方法......对象层page对象层对元素定位方法封装命名规则模块名page下划线实际操作模块名称。函数名类名使用大驼峰讲模块名称抄进来有下划线去掉下划线。继承Base类。方法名根据业务需求每个操作步骤单独封装一个方法涉及元素将每个元素操作单独封装一个操作方法。命名举例模块名page_login.py函数名类名class PageLogin(Base):方法名def page_input_username():输入用户名注意一个页面封装成一个对象并继承 base组合业务方法组装根据需求组装以上操作步骤。如page_login业务层scripts业务层测试业务逻辑封装将一个或多个操作组合起来完成一个业务功能。命名规则模块名test数字下划线实际操作模块名称如果测试用例存在先后顺序则可加上数字。测试业务名称以大驼峰方法将模块名抄进来有下划线去掉下划线。方法名def test_login():命名举例模块名test01_login.py测试业务名class TestLogin():方法名def test_login():说明业务层实际就是测试脚本并且要导包调用page页面封装的方法如登录业务需要输入账号、密码、点击登录三个操作方法:1初始化方法setup()注在unittest框架中不能使用__init__初始化方法。如实例化页面对象、前置操作如打开浏览器等2结束方法teardown()。如关闭驱动3测试方法。如根据要操作的业务来实现步骤# 导包 # 新建测试类 # setup # teardown # 业务测试方法 # 调用功能方法如 登录方法 # 获取登录提示信息 # 断言 # try 捕获异常 # 截图5、PO模式下的项目结构PO模式下的主要项目文件夹base、page、scriptscases、run、tools、data、image、log、reportbasebase.pyimport time from time import sleep from selenium.webdriver.support.wait import WebDriverWait from day11_tpshop import page from day11_tpshop.base.get_logger import GetLogger # 获取log日志器 log GetLogger().get_logger() class Base: def __init__(self, driver): log.info([base:]正在获取初始化driver对象{}.format(driver)) self.driver driver # 查找元素方法 封装 def base_find(self, loc, timeout30, poll0.5): log.info([base]:正在定位{}元素默认定位超时时间为{}.format(loc, timeout)) # 使用显式等待 查找元素 return WebDriverWait(self.driver, timeouttimeout, poll_frequencypoll).until(lambda x: x.find_element(*loc)) # 点击元素方法 封装 def base_click(self, loc): log.info([base]:正在对{}元素执行点击事件.format(loc)) self.base_find(loc).click() # 输入元素方法 封装 def base_input(self, loc, value): log.info([base]:正在获取{}元素.format(loc)) # 获取元素 el self.base_find(loc) log.info([base]:正在对{}元素执行清空操作.format(loc)) # 输入前 清空 el.clear() log.info([base]:正在给{}元素输入内容{}.format(loc, value)) # 输入 el.send_keys(value) # 获取文本信息方法 封装 def base_get_text(self, loc): log.info([base]:正在获取{}元素文本值.format(loc)) return self.base_find(loc).text # 截图方法 封装 def base_get_img(self): log.info([base]:断言出错调用截图) self.driver.get_screenshot_as_file(../image/{}.png.format(time.strftime(%Y_%m_%d %H_%M_%S))) # 判断元素是否存在方法 封装 def base_elememt_is_exist(self, loc): try: self.base_find(loc, timeout2) log.info([base]:{}元素查找成功存在页面.format(loc)) return True # 代表元素存在 except: log.info([base]:{}元素查找失败不存在当前页面.format(loc)) return False # 代表元素不存在 # 回到首页购物车、下订单、支付都需要用到此方法 def base_index(self): # 暂停2秒 sleep(2) log.info([base]:正在打开首页) self.driver.get(page.URL) # 切到frame表单方法 以元素属性切换 def base_switch_frame(self, element): log.info([base]:正在切换到frame表单) self.driver.switch_to.frame(element) # 回到默认目录方法 def base_default_content(self): log.info([base]:正在返回默认目录) self.driver.switch_to.default_content() # 切换窗口方法 def base_switch_to_window(self, title): log.info(正在执行切换title值为{}窗口.format(title)) self.base_get_title_handle(title) # self.driver.switch_to.window(self.base_get_title_handle(title)) # 获取指定title页面的handle方法 def base_get_title_handle(self, title): # 获取当前页面所有的handles handles self.driver.window_handles # 遍历handle for handle in handles: log.info(正在遍历handles{}--{}.format(handle, handles)) # 切换 handle self.driver.switch_to.window(handle) log.info(切换{}窗口.format(handle)) # 获取当前页面title 并判断 是否等于 指定参数title log.info(条件成立返回当前handle{}.format(handle)) if self.driver.title title: # 返回 handle return handleget_driver.pyfrom selenium import webdriver from day11_tpshop import page class GetDriver: driver None # 获取 driver classmethod def get_driver(cls): if cls.driver is None: cls.driver webdriver.Chrome() # 最大化浏览器 cls.driver.maximize_window() # 打开 url cls.driver.get(page.URL) # 返回 driver return cls.driver # 关闭 driver classmethod def quit_driver(cls): if cls.driver: cls.driver.quit() # 必须置空操作 cls.driver None if __name__ __main__: GetDriver().quit_driver()get_logger.pyimport logging.handlers import time class GetLogger: logger None # 获取logger classmethod def get_logger(cls): if cls.logger is None: # 获取 logger 日志器 并设置名称为“admin” cls.logger logging.getLogger(admin) # 设置日志级别 cls.logger.setLevel(logging.INFO) # 获取 控制台处理器 sh logging.StreamHandler() # 获取 文件处理器 根据时间分割 th logging.handlers.TimedRotatingFileHandler(../log/{}.log.format(time.strftime(%Y_%m_%d %H_%M_%S)), whenS, interval1, backupCount3, encodingutf-8) # 设置 文件处理器 日志级别 th.setLevel(logging.ERROR) # 获取 格式器 fmt %(asctime)s %(levelname)s [%(name)s] [%(filename)s %(funcName)s %(lineno)d] - %(message)s fm logging.Formatter(fmt) # 将 格式器 添加到 处理器 sh.setFormatter(fm) th.setFormatter(fm) # 将 处理器 添加到 日志器 cls.logger.addHandler(sh) cls.logger.addHandler(th) # 返回日志器 return cls.logger if __name__ __main__: logger GetLogger.get_logger() # 日志器应用 logger.info(这是info日志信息) logger.debug(这是debug日志信息) logger.warning(这是warning日志信息) logger.error(这是error日志信息)page__init__.pyfrom selenium.webdriver.common.by import By 以下为项目服务器地址 URL http://localhost 以下为登录模块涉及元素 配置信息 # 登录链接 login_link By.PARTIAL_LINK_TEXT, 登录 # 用户名 login_username By.CSS_SELECTOR, #username # 密码 login_pwd By.CSS_SELECTOR, #password # 验证码 login_verify_code By.CSS_SELECTOR, #verify_code # 登录按钮 login_btn By.CSS_SELECTOR, .J-login-submit # 错误提示信息 login_err_info By.CSS_SELECTOR, .layui-layer-content # 错误提示框 确定按钮 login_err_ok_btn By.CSS_SELECTOR, .layui-layer-btn0 # 安全退出 按钮 login_logout_link By.PARTIAL_LINK_TEXT, 安全退出 以下数据为购物车配置数据 # 搜索框 cart_search By.CSS_SELECTOR, #q # 搜索按钮 cart_search_btn By.CSS_SELECTOR, .ecsc-search-button # 添加购物车 -- 跳转到详情页面 cart_add_info By.CSS_SELECTOR, .p-btna # 添加购物车 cart_add By.CSS_SELECTOR, #join_cart # iframe 表单名称 cart_frame_name By.CSS_SELECTOR, layui-layer-iframe1 # id 属性 定义元素 cart_frame_id By.CSS_SELECTOR, #layui-layer-iframe1 # 获取添加购物车结果 cart_add_result By.CSS_SELECTOR, .conect-titlespan # 关闭提示窗口 cart_close_window By.CSS_SELECTOR, .layui-layer-close 以下数据为订单页面配置数据 # 我的购物车 order_my_cart By.CSS_SELECTOR, .c-n # 全选 order_all By.CSS_SELECTOR, .checkCartAll # 去结算 order_account By.CSS_SELECTOR, .gwc-qjs # 收货人 备用 order_person By.CSS_SELECTOR, .consigneeb # 提交订单 order_submit By.CSS_SELECTOR, .Sub-orders # 获取提交订单结果 order_submit_result By.CSS_SELECTOR, .erhuhh3 以下数据为支付模块配置数据 # 我的订单 pay_my_order By.PARTIAL_LINK_TEXT, 我的订单 # 我的订单页面title 注意此处为变量不要By pay_my_order_title 我的订单 # 立即支付 pay_now_payment By.CSS_SELECTOR, .ps_lj # 支付页面title pay_payment_title 订单支付-开源商城 | B2C商城 |... # 货到付款 pay_on_delivery By.CSS_SELECTOR, [src/plugins/payment/cod/logo.jpg] # 确认支付 pay_confirm_payment By.CSS_SELECTOR, .button-confirm-payment # 获取支付结果 pay_payment_result By.CSS_SELECTOR, .erhuhh3page_cart.py# 导包 from time import sleep from day11_tpshop import page from day11_tpshop.base.base import Base from day11_tpshop.base.get_logger import GetLogger # 获取log日志 log GetLogger().get_logger() class PageCart(Base): # 打开首页 def page_open_index(self): # 注意由于业务问题必须暂停2秒否则在登录时改变url会报错 sleep(2) log.info([page_cart]:正在打开首页) self.base_index() # 输入搜索内容 小米手机 def page_input_search(self, value小米手机): log.info([page_cart]:正在输入搜索内容:{}.format(value)) self.base_input(page.cart_search, value) # 点击搜索按钮 def page_click_search_btn(self): log.info([page_cart]:正在点击搜索按钮) self.base_click(page.cart_search_btn) # 点击添加购物车 跳转到商品详情页 def page_click_add_cart_info(self): log.info([page_cart]:正在点击加入购物车按钮跳转到商品详情页) self.base_click(page.cart_add_info) # 点击加入购物车 def page_click_add_cart(self): log.info([page_cart]:正在点击加入购物车按钮弹出frame表单) self.base_click(page.cart_add) # 点击获取添加结果 def page_get_text(self): # # 切换frame表单 以name属性切换 由于电脑配置问题导致加载比较慢不建议使用 # self.switch_to_frame(page.cart_frame_name) # 以元素属性切换 推荐 self.base_switch_frame(self.base_find(page.cart_frame_id)) # 获取结果并返回 log.info([page_cart]:正在返回购物结果信息) return self.base_get_text(page.cart_add_result) # 关闭窗口 def page_close_window(self): # 回到默认目录 self.base_default_content() # 关闭操作 log.info([page_cart]:正在关闭表单弹窗) self.base_click(page.cart_close_window) # 组合业务调用方法 def page_cart(self): log.info([page_cart]:正在执行添加购物车操作) self.page_input_search() self.page_click_search_btn() self.page_click_add_cart_info() self.page_click_add_cart()page_login.pyfrom day11_tpshop import page from day11_tpshop.base.base import Base from day11_tpshop.base.get_logger import GetLogger # 获取log日志器 log GetLogger().get_logger() class PageLogin(Base): # 点击 登录链接 def page_click_login_link(self): log.info([page_login]:执行{}元素点击链接操作.format(page.login_link)) self.base_click(page.login_link) # 输入用户名 def page_input_username(self, username): log.info([page_login]:对{}元素 输入用户名{}操作.format(page.login_username, username)) self.base_input(page.login_username, username) # 输入密码 def page_input_pwd(self, pwd): log.info([page_login]:对{}元素 输入密码{}操作.format(page.login_pwd, pwd)) self.base_input(page.login_pwd, pwd) # 输入验证码 def page_input_verify_code(self, verify_code): log.info([page_login]:对{}元素 输入验证码{}操作.format(page.login_verify_code, verify_code)) self.base_input(page.login_verify_code, verify_code) # 点击 登录 def page_click_login_btn(self): log.info([page_login]:执行{}元素点击操作.format(page.login_btn)) self.base_click(page.login_btn) # 获取 错误提示信息 def page_get_err_info(self): return self.base_get_text(page.login_err_info) # 点击 错误提示框 确定按钮 def page_click_error_alert(self): log.info([page_login]:执行{}元素点击操作.format(page.login_err_ok_btn)) self.base_click(page.login_err_ok_btn) # 判断是否登录成功 def page_if_login_success(self): # 注意 一定要将找元素的结果返回True存在 return self.base_elememt_is_exist(page.login_logout_link) # 点击 安全退出 def page_click_logout_link(self): self.base_click(page.login_logout_link) # 判断是否退出成功 def page_if_logout_success(self): return self.base_elememt_is_exist(page.login_link) # 组合业务方法 登录业务直接调用 def page_login(self, username, pwd, verify_code): log.info([page_login]:正在执行登录操作用户名{}密码{}验证码{}.format(username, pwd, verify_code)) self.page_input_username(username) self.page_input_pwd(pwd) self.page_input_verify_code(verify_code) self.page_click_login_btn() # 组合登录业务方法 给购物车模块、订单模块、支付模块依赖登录使用 def page_login_success(self, username13800001111, pwd123456, verify_code8888): # 点击登录链接 self.page_click_login_link() log.info([page_login]:正在执行登录操作用户名{}密码{}验证码{}.format(username, pwd, verify_code)) self.page_input_username(username) self.page_input_pwd(pwd) self.page_input_verify_code(verify_code) self.page_click_login_btn()page_order.pyfrom time import sleep from day11_tpshop import page from day11_tpshop.base.base import Base class PageOrder(Base): # 打开首页 def page_click_index(self): self.base_index() # 点击 我的购物车 def page_click_my_cart(self): self.base_click(page.order_my_cart) # 点击 全选复选框 def page_click_all_select(self): # 判断 如果没选中 就进行点击操作 if not self.base_find(page.order_all).is_selected(): self.base_click(page.order_all) # 点击 去结算 def page_click_account(self): self.base_click(page.order_account) # 备用 查找收货人 -- 动态 解决 收货人加载慢的问题数据异步加载 def page_find_person(self): self.base_find(page.order_person) # 点击 提交订单 def page_click_submit_order(self): self.base_click(page.order_submit) # 获取 订单提交结果 def page_get_submit_result(self): return self.base_get_text(page.order_submit_result) # 组装订单业务方法 def page_order(self): self.page_click_my_cart() self.page_click_all_select() self.page_click_account() # 注意此处有一个坑默认收货人在页面加载完成后3秒后才出现。 # 解决方法一使用sleep(5) # sleep(5) # 解决方法二使用显示等待时长机制查找收货人元素【推荐】 # 找到收货人说明异步加载完成收货人信息出现直接可以执行下一步提交订单操作 self.page_find_person() self.page_click_submit_order()page_pay.pyfrom day11_tpshop import page from day11_tpshop.base.base import Base class PagePay(Base): # 点击 我的订单链接 def page_click_my_order_link(self): self.base_click(page.pay_my_order) # 点击 立即支付 def page_click_now_payment(self): # 必须先切换窗口 self.base_switch_to_window(page.pay_my_order_title) # 点击立即支付 self.base_click(page.pay_now_payment) # 点击 货到付款 def page_click_pay_on_delivery(self): # 先切换窗口 self.base_switch_to_window(page.pay_payment_title) # 点击货到付款 self.base_click(page.pay_on_delivery) # 确认支付 def page_click_payment_mode(self): self.base_click(page.pay_confirm_payment) # 获取支付结果 def page_get_payment_result(self): self.base_get_text(page.pay_payment_result) # 组合支付业务方法 def page_pay(self): self.page_click_my_order_link() self.page_click_now_payment() self.page_click_pay_on_delivery() self.page_click_payment_mode()scriptstest01_login.pyimport unittest from day11_TPshop项目.base.get_driver import GetDriver from day11_TPshop项目.base.get_logger import GetLogger from day11_TPshop项目.page.page_login import PageLogin from day11_TPshop项目.tools.read_txt import read_txt from parameterized import parameterized # 获取log日志器 log GetLogger().get_logger() def get_data(): arrs [] for data in read_txt(login.txt): arrs.append(tuple(data.strip().split(,))) return arrs[1:] # 新建 登录测试类 并 继承 unittest.TestCase class TestLogin(unittest.TestCase): # 新建 setUpClass classmethod def setUpClass(cls) - None: try: # 实例化 并获取 driver cls.driver GetDriver.get_driver() # 实例化 PageLogin() cls.login PageLogin(cls.driver) # 点击登录链接 cls.login.page_click_login_link() except Exception as e: # 截图 cls.login.base_get_img() # 日志 log.error(错误{}.format(e)) # 新建 tearDownClass classmethod def tearDownClass(cls) - None: # 关闭driver驱动对象 GetDriver.quit_driver() # 新建 登录测试方法 parameterized.expand(get_data()) def test_login(self, username, pwd, verify_code, expect_result, status): try: # 调用 登录业务方法 self.login.page_login(username, pwd, verify_code) # 判断是否为正向 if status true: # 断言是否登录成功 try: self.assertTrue(self.login.page_if_login_success()) except Exception as e: # 截图 self.login.base_get_img() # 日志 log.error(出错了{}.format(e)) # 点击 安全退出 self.login.page_click_logout_link() # 点击 登录链接 self.login.page_click_login_link() # 逆向用例 else: # 获取错误提示信息 msg self.login.page_get_err_info() print(msg:, msg) try: self.assertEqual(msg, expect_result) except Exception as e: # 截图 self.login.base_get_img() # 日志 log.error(出错了{}.format(e)) # 点击错误提示框 确定按钮 self.login.page_click_error_alert() except Exception as e: # 截图 self.login.base_get_img() # 日志 log.error(出错了{}.format(e))test02_cart.py代码略test03_order.py代码略test04_pay.py代码略runrun_main.py# 导包 import unittest import time from day11_tpshop.tools.HTMLTestRunner import HTMLTestRunner # 定义测试套件 suite unittest.defaultTestLoader.discover(../scripts/) # 报告生成目录及文件名称 dir_path ../report/{}.html.format(time.strftime(%Y_%m_%d %H_%M_%S)) # 获取文件流并调用run运行生成测试报告 with open(dir_path, wb) as f: HTMLTestRunner(streamf, titleTpShop商城自动化测试报告, description操作系统Win10)toolsHTMLTestRunner.pyHTMLTestRunnerCN.pyread_text.pydef read_txt(filename): filepath ../data/filename with open(filepath, r, encodingutf-8) as f: return f.readlines() 问题读出来的不是预期需要的格式 if __name__ __main__: print(read_txt(calc.txt)) print(-- * 60) arrs1 [] for data in read_txt(calc.txt): arrs1.append(tuple(data.strip().split(,))) print(arrs1为, arrs1) # [(), ()] arrs2 [] for data in read_txt(calc.txt): arrs2.append(data.strip().split(,)) print(arrs2为, arrs2[1::]) # [[], []]read_json.py# 导包 import json def read_json(filename): filepath ../data/filename # 获取文件流 并调用load with open(filepath, r, encodingutf-8) as f: return json.load(f) 问题 需求格式[(), ()] 或 [[], []] 解决 1、新建空列表 arrs [] 2、读取现有的 json 值存放到列表中 if __name__ __main__: print(read_json(login.json)) print(-- * 60) # 新建空列表 arrs1 [] for data1 in read_json(login.json).values(): # print(data) arrs1.append((data1.get(username), data1.get(password), data1.get(verify_code), data1.get(expect))) print(arrs1) # [(), ()] arrs2 [] for data2 in read_json(login.json).values(): arrs2.append([data2.get(username), data2.get(password), data2.get(verify_code), data2.get(expect)]) print(arrs2) # [[], []]datalogin.txt内容略login.json内容略image 截图保存的文件夹内容略log 日志收集保存的文件夹内容略report 测试报告生成的文件夹内容略最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。

相关新闻

国产替代不止于价格:耐达讯自动化Profibus六路集线器以技术实力对标进口profiHub B5

国产替代不止于价格:耐达讯自动化Profibus六路集线器以技术实力对标进口profiHub B5

在化工生产过程中,变送器作为数据采集的关键设备,其数据实时性、稳定性直接影响生产安全与效率。然而,传统系统中,进口PLC与国产变送器常因协议不匹配面临兼容性差、成本高昂等问题。耐达讯自动化Profibus六路集线器以“协议转换多…

2026/7/3 23:30:30 阅读更多 →
超越profiHub B5:耐达讯自动化Profibus六路集线器——更高兼容、更强防护的伺服驱动控制中枢

超越profiHub B5:耐达讯自动化Profibus六路集线器——更高兼容、更强防护的伺服驱动控制中枢

在数控机床与加工中心领域,多轴伺服驱动系统的高精度协同依赖于稳定、高速的通信网络。通常,多个伺服驱动器通过Profibus-DP总线与数控系统(CNC)连接。然而,当轴数增多、布线复杂时,传统线性拓扑易导致信号…

2026/7/3 1:33:43 阅读更多 →
基于flask+python的网上二手交易系统的设计与实现-vue pycharm django

基于flask+python的网上二手交易系统的设计与实现-vue pycharm django

目录 技术栈选择与分工系统模块设计开发流程关键技术实现部署方案测试策略 开发技术路线源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 技术栈选择与分工 后端框架选择FlaskDjango Flask负责轻量级API开发,Django处理复杂业…

2026/7/3 22:42:35 阅读更多 →

最新新闻

基于CNN的中药识别系统开发与Flask部署实践

基于CNN的中药识别系统开发与Flask部署实践

1. 项目概述与核心思路 中药识别一直是传统医学数字化进程中的重要课题。作为一名长期从事计算机视觉应用的开发者,我发现将深度学习技术应用于中药识别领域具有广阔前景。本项目通过构建一个基于卷积神经网络(CNN)的中药识别系统,实现了从数据准备到模型…

2026/7/4 10:19:48 阅读更多 →
Python+OpenCV实现实时口罩检测系统开发指南

Python+OpenCV实现实时口罩检测系统开发指南

1. 项目概述 这个口罩识别系统是我去年疫情期间开发的一个实用工具,主要用来实时检测摄像头画面中的人员是否佩戴口罩。系统采用Python作为开发语言,结合OpenCV进行图像处理和模型推理,使用PyQt构建用户界面。整套方案在普通办公电脑上能达到…

2026/7/4 10:19:48 阅读更多 →
ICM-42688-P与STM32F417ZG在运动控制与振动监测中的应用

ICM-42688-P与STM32F417ZG在运动控制与振动监测中的应用

1. ICM-42688-P与STM32F417ZG的黄金组合解析 在工业自动化和机器人控制领域,传感器与处理器的协同工作能力直接决定了系统性能上限。ICM-42688-P作为TDK InvenSense推出的6轴MEMS运动跟踪传感器,与STMicroelectronics的STM32F417ZG微控制器形成的技术组合…

2026/7/4 10:17:48 阅读更多 →
Appium与Open-AutoGLM深度对比:AI如何重塑移动端自动化测试

Appium与Open-AutoGLM深度对比:AI如何重塑移动端自动化测试

1. 项目概述:当传统自动化框架遇上AI新范式 最近在搞移动端自动化测试和流程自动化,发现圈子里的讨论风向变了。以前大家一提到手机自动化,张口闭口就是Appium、Selenium,现在越来越多人在聊Open-AutoGLM、Agent这些新词。作为一个…

2026/7/4 10:17:48 阅读更多 →
Startup AI自动化落地实战:客服、库存与决策的闭环打法

Startup AI自动化落地实战:客服、库存与决策的闭环打法

1. 项目概述:当AI自动化真正落地到 startup 的日常毛细血管里 我带过三支不同阶段的创业团队,从十几人的 SaaS 工具公司,到二十人出头的跨境 DTC 品牌,再到刚完成种子轮的工业 IoT 解决方案团队。过去三年里,我亲手拆过…

2026/7/4 10:13:45 阅读更多 →
ID3到XGBoost:决策树模型演进的工程实战路径

ID3到XGBoost:决策树模型演进的工程实战路径

1. 这不是“树”的科普,而是决策模型演进的实战路线图 你打开任何一本机器学习入门书,十有八九会在第三章遇到“决策树”——画着几根分叉的流程图,讲着信息增益、基尼不纯度这些词,然后戛然而止。但真实项目里,没人只…

2026/7/4 10:13:45 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻