【Python自动化测试】如何才能让用例自动运行完之后,生成一张直观可看易懂的测试报告呢?

小编使用的是unittest的一个扩展HTMLTestRunner

  • 环境准备

使用之前,我们需要下载HTMLTestRunner.py文件

点击HTMLTestRunner后进入的是一个写满代码的网页,小编推荐操作:右键 --> 另存为,文件名称千万不要改

python3使用上述HTMLTestRunner可能会报错,可以替换如下文件

"""A TestRunner for use with the Python unit testing framework. Itgenerates a HTML report to show the result at a glance.The simplest way to use this is to invoke its main method. E.g.import unittestimport HTMLTestRunner... define your tests ...if __name__ == '__main__':HTMLTestRunner.main()For more customization options, instantiates a HTMLTestRunner object.HTMLTestRunner is a counterpart to unittest's TextTestRunner. E.g.# output to a filefp = file('my_report.html', 'wb')runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='My unit test',description='This demonstrates the report output by HTMLTestRunner.')# Use an external stylesheet.# See the Template_mixin class for more customizable optionsrunner.STYLESHEET_TMPL = '<link rel="stylesheet" href="my_stylesheet.css" type="text/css">'# run the testrunner.run(my_test_suite)------------------------------------------------------------------------Copyright (c) 2004-2007, Wai Yip TungAll rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions aremet:* Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer.* Redistributions in binary form must reproduce the above copyrightnotice, this list of conditions and the following disclaimer in thedocumentation and/or other materials provided with the distribution.* Neither the name Wai Yip Tung nor the names of its contributors may beused to endorse or promote products derived from this software withoutspecific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITEDTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR APARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNEROR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."""# URL: http://tungwaiyip.info/software/HTMLTestRunner.html__author__ = "Wai Yip Tung"__version__ = "0.8.2""""Change HistoryVersion 0.8.2* Show output inline instead of popup window (Viorel Lupu).Version in 0.8.1* Validated XHTML (Wolfgang Borgert).* Added description of test classes and test cases.Version in 0.8.0* Define Template_mixin class for customization.* Workaround a IE 6 bug that it does not treat <script> block as CDATA.Version in 0.7.1* Back port to Python 2.3 (Frank Horowitz).* Fix missing scroll bars in detail log (Podi)."""# TODO: color stderr# TODO: simplify javascript using ,ore than 1 class in the class attribute?import datetimeimport ioimport sysimport timeimport unittestfrom xml.sax import saxutils# ------------------------------------------------------------------------# The redirectors below are used to capture output during testing. Output# sent to sys.stdout and sys.stderr are automatically captured. However# in some cases sys.stdout is already cached before HTMLTestRunner is# invoked (e.g. calling logging.basicConfig). In order to capture those# output, use the redirectors for the cached stream.## e.g.# >>> logging.basicConfig(stream=HTMLTestRunner.stdout_redirector)# >>>class OutputRedirector(object):""" Wrapper to redirect stdout or stderr """def __init__(self, fp):self.fp = fpdef write(self, s):self.fp.write(s)def writelines(self, lines):self.fp.writelines(lines)def flush(self):self.fp.flush()stdout_redirector = OutputRedirector(sys.stdout)stderr_redirector = OutputRedirector(sys.stderr)# ----------------------------------------------------------------------# Templateclass Template_mixin(object):"""Define a HTML template for report customerization and generation.Overall structure of an HTML reportHTML+------------------------+|<html> || <head> || || STYLESHEET || +----------------+ || | | || +----------------+ || || </head> || || <body> || || HEADING || +----------------+ || | | || +----------------+ || || REPORT || +----------------+ || | | || +----------------+ || || ENDING || +----------------+ || | | || +----------------+ || || </body> ||</html> |+------------------------+"""STATUS = {0: 'pass',1: 'fail',2: 'error',}DEFAULT_TITLE = 'Unit Test Report'DEFAULT_DESCRIPTION = ''# ------------------------------------------------------------------------# HTML TemplateHTML_TMPL = r"""<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>%(title)s</title><meta name="generator" content="%(generator)s"/><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>%(stylesheet)s</head><body><script language="javascript" type="text/javascript"><!--output_list = Array();/* level - 0:Summary; 1:Failed; 2:All */function showCase(level) {trs = document.getElementsByTagName("tr");for (var i = 0; i < trs.length; i++) {tr = trs[i];id = tr.id;if (id.substr(0,2) == 'ft') {if (level < 1) {tr.className = 'hiddenRow';}else {tr.className = '';}}if (id.substr(0,2) == 'pt') {if (level > 1) {tr.className = '';}else {tr.className = 'hiddenRow';}}}}function showClassDetail(cid, count) {var id_list = Array(count);var toHide = 1;for (var i = 0; i < count; i++) {tid0 = 't' + cid.substr(1) + '.' + (i+1);tid = 'f' + tid0;tr = document.getElementById(tid);if (!tr) {tid = 'p' + tid0;tr = document.getElementById(tid);}id_list[i] = tid;if (tr.className) {toHide = 0;}}for (var i = 0; i < count; i++) {tid = id_list[i];if (toHide) {document.getElementById('div_'+tid).style.display = 'none'document.getElementById(tid).className = 'hiddenRow';}else {document.getElementById(tid).className = '';}}}function showTestDetail(div_id){var details_div = document.getElementById(div_id)var displayState = details_div.style.display// alert(displayState)if (displayState != 'block' ) {displayState = 'block'details_div.style.display = 'block'}else {details_div.style.display = 'none'}}function html_escape(s) {s = s.replace(/&/g,'&amp;');s = s.replace(/</g,'&lt;');s = s.replace(/>/g,'&gt;');return s;}/* obsoleted by detail in <div>function showOutput(id, name) {var w = window.open("", //urlname,"resizable,scrollbars,status,width=800,height=450");d = w.document;d.write("<pre>");d.write(html_escape(output_list[id]));d.write("\n");d.write("<a href='javascript:window.close()'>close</a>\n");d.write("</pre>\n");d.close();}*/--></script>%(heading)s%(report)s%(ending)s</body></html>"""# variables: (title, generator, stylesheet, heading, report, ending)# ------------------------------------------------------------------------# Stylesheet## alternatively use a <link> for external style sheet, e.g.# <link rel="stylesheet" href="$url" type="text/css">STYLESHEET_TMPL = """<style type="text/css" media="screen">body { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }table { font-size: 100%; }pre { }/* -- heading ---------------------------------------------------------------------- */h1 {font-size: 16pt;color: gray;}.heading {margin-top: 0ex;margin-bottom: 1ex;}.heading .attribute {margin-top: 1ex;margin-bottom: 0;}.heading .description {margin-top: 4ex;margin-bottom: 6ex;}/* -- css div popup ------------------------------------------------------------------------ */a.popup_link {}a.popup_link:hover {color: red;}.popup_window {display: none;position: relative;left: 0px;top: 0px;/*border: solid #627173 1px; */padding: 10px;background-color: #E6E6D6;font-family: "Lucida Console", "Courier New", Courier, monospace;text-align: left;font-size: 8pt;width: 500px;}}/* -- report ------------------------------------------------------------------------ */#show_detail_line {margin-top: 3ex;margin-bottom: 1ex;}#result_table {width: 80%;border-collapse: collapse;border: 1px solid #777;}#header_row {font-weight: bold;color: white;background-color: #777;}#result_table td {border: 1px solid #777;padding: 2px;}#total_row { font-weight: bold; }.passClass { background-color: #6c6; }.failClass { background-color: #c60; }.errorClass { background-color: #c00; }.passCase { color: #6c6; }.failCase { color: #c60; font-weight: bold; }.errorCase { color: #c00; font-weight: bold; }.hiddenRow { display: none; }.testcase { margin-left: 2em; }/* -- ending ---------------------------------------------------------------------- */#ending {}</style>"""# ------------------------------------------------------------------------# Heading#HEADING_TMPL = """<div class='heading'><h1>%(title)s</h1>%(parameters)s<p class='description'>%(description)s</p></div>""" # variables: (title, parameters, description)HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s:</strong> %(value)s</p>""" # variables: (name, value)# ------------------------------------------------------------------------# Report#REPORT_TMPL = """<p id='show_detail_line'>Show<a href='javascript:showCase(0)'>Summary</a><a href='javascript:showCase(1)'>Failed</a><a href='javascript:showCase(2)'>All</a></p><table id='result_table'><colgroup><col align='left' /><col align='right' /><col align='right' /><col align='right' /><col align='right' /><col align='right' /></colgroup><tr id='header_row'><td>Test Group/Test case</td><td>Count</td><td>Pass</td><td>Fail</td><td>Error</td><td>View</td></tr>%(test_list)s<tr id='total_row'><td>Total</td><td>%(count)s</td><td>%(Pass)s</td><td>%(fail)s</td><td>%(error)s</td><td>&nbsp;</td></tr></table>""" # variables: (test_list, count, Pass, fail, error)REPORT_CLASS_TMPL = r"""<tr class='%(style)s'><td>%(desc)s</td><td>%(count)s</td><td>%(Pass)s</td><td>%(fail)s</td><td>%(error)s</td><td><a href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td></tr>""" # variables: (style, desc, count, Pass, fail, error, cid)REPORT_TEST_WITH_OUTPUT_TMPL = r"""<tr id='%(tid)s' class='%(Class)s'><td class='%(style)s'><div class='testcase'>%(desc)s</div></td><td colspan='5' align='center'><!--css div popup start--><a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >%(status)s</a><div id='div_%(tid)s' class="popup_window"><div style='text-align: right; color:red;cursor:pointer'><a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >[x]</a></div><pre>%(script)s</pre></div><!--css div popup end--></td></tr>""" # variables: (tid, Class, style, desc, status)REPORT_TEST_NO_OUTPUT_TMPL = r"""<tr id='%(tid)s' class='%(Class)s'><td class='%(style)s'><div class='testcase'>%(desc)s</div></td><td colspan='5' align='center'>%(status)s</td></tr>""" # variables: (tid, Class, style, desc, status)REPORT_TEST_OUTPUT_TMPL = r"""%(id)s: %(output)s""" # variables: (id, output)# ------------------------------------------------------------------------# ENDING#ENDING_TMPL = """<div id='ending'>&nbsp;</div>"""# -------------------- The end of the Template class -------------------TestResult = unittest.TestResultclass _TestResult(TestResult):# note: _TestResult is a pure representation of results.# It lacks the output and reporting ability compares to unittest._TextTestResult.def __init__(self, verbosity=1):TestResult.__init__(self)self.stdout0 = Noneself.stderr0 = Noneself.success_count = 0self.failure_count = 0self.error_count = 0self.verbosity = verbosity# result is a list of result in 4 tuple# (# result code (0: success; 1: fail; 2: error),# TestCase object,# Test output (byte string),# stack trace,# )self.result = []def startTest(self, test):TestResult.startTest(self, test)# just one buffer for both stdout and stderrself.outputBuffer = io.StringIO()stdout_redirector.fp = self.outputBufferstderr_redirector.fp = self.outputBufferself.stdout0 = sys.stdoutself.stderr0 = sys.stderrsys.stdout = stdout_redirectorsys.stderr = stderr_redirectordef complete_output(self):"""Disconnect output redirection and return buffer.Safe to call multiple times."""if self.stdout0:sys.stdout = self.stdout0sys.stderr = self.stderr0self.stdout0 = Noneself.stderr0 = Nonereturn self.outputBuffer.getvalue()def stopTest(self, test):# Usually one of addSuccess, addError or addFailure would have been called.# But there are some path in unittest that would bypass this.# We must disconnect stdout in stopTest(), which is guaranteed to be called.self.complete_output()def addSuccess(self, test):self.success_count += 1TestResult.addSuccess(self, test)output = self.complete_output()self.result.append((0, test, output, ''))if self.verbosity > 1:sys.stderr.write('ok ')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('.')def addError(self, test, err):self.error_count += 1TestResult.addError(self, test, err)_, _exc_str = self.errors[-1]output = self.complete_output()self.result.append((2, test, output, _exc_str))if self.verbosity > 1:sys.stderr.write('E ')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('E')def addFailure(self, test, err):self.failure_count += 1TestResult.addFailure(self, test, err)_, _exc_str = self.failures[-1]output = self.complete_output()self.result.append((1, test, output, _exc_str))if self.verbosity > 1:sys.stderr.write('F ')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('F')class HTMLTestRunner(Template_mixin):""""""def __init__(self, stream=sys.stdout, verbosity=1, title=None, description=None):self.stream = streamself.verbosity = verbosityif title is None:self.title = self.DEFAULT_TITLEelse:self.title = titleif description is None:self.description = self.DEFAULT_DESCRIPTIONelse:self.description = descriptionself.startTime = datetime.datetime.now()def run(self, test):"Run the given test case or test suite."result = _TestResult(self.verbosity)test(result)self.stopTime = datetime.datetime.now()self.generateReport(test, result)# print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))return resultdef sortResult(self, result_list):# unittest does not seems to run in any particular order.# Here at least we want to group them together by class.rmap = {}classes = []for n,t,o,e in result_list:cls = t.__class__if not cls in rmap:rmap[cls] = []classes.append(cls)rmap[cls].append((n,t,o,e))r = [(cls, rmap[cls]) for cls in classes]return rdef getReportAttributes(self, result):"""Return report attributes as a list of (name, value).Override this to add custom attributes."""startTime = str(self.startTime)[:19]duration = str(self.stopTime - self.startTime)status = []if result.success_count: status.append('Pass %s' % result.success_count)if result.failure_count: status.append('Failure %s' % result.failure_count)if result.error_count: status.append('Error %s' % result.error_count )if status:status = ' '.join(status)else:status = 'none'return [('Start Time', startTime),('Duration', duration),('Status', status),]def generateReport(self, test, result):report_attrs = self.getReportAttributes(result)generator = 'HTMLTestRunner %s' % __version__stylesheet = self._generate_stylesheet()heading = self._generate_heading(report_attrs)report = self._generate_report(result)ending = self._generate_ending()output = self.HTML_TMPL % dict(title = saxutils.escape(self.title),generator = generator,stylesheet = stylesheet,heading = heading,report = report,ending = ending,)self.stream.write(output.encode('utf8'))def _generate_stylesheet(self):return self.STYLESHEET_TMPLdef _generate_heading(self, report_attrs):a_lines = []for name, value in report_attrs:line = self.HEADING_ATTRIBUTE_TMPL % dict(name = saxutils.escape(name),value = saxutils.escape(value),)a_lines.append(line)heading = self.HEADING_TMPL % dict(title = saxutils.escape(self.title),parameters = ''.join(a_lines),description = saxutils.escape(self.description),)return headingdef _generate_report(self, result):rows = []sortedResult = self.sortResult(result.result)for cid, (cls, cls_results) in enumerate(sortedResult):# subtotal for a classnp = nf = ne = 0for n,t,o,e in cls_results:if n == 0: np += 1elif n == 1: nf += 1else: ne += 1# format class descriptionif cls.__module__ == "__main__":name = cls.__name__else:name = "%s.%s" % (cls.__module__, cls.__name__)doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""desc = doc and '%s: %s' % (name, doc) or namerow = self.REPORT_CLASS_TMPL % dict(style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',desc = desc,count = np+nf+ne,Pass = np,fail = nf,error = ne,cid = 'c%s' % (cid+1),)rows.append(row)for tid, (n,t,o,e) in enumerate(cls_results):self._generate_report_test(rows, cid, tid, n, t, o, e)report = self.REPORT_TMPL % dict(test_list = ''.join(rows),count = str(result.success_count+result.failure_count+result.error_count),Pass = str(result.success_count),fail = str(result.failure_count),error = str(result.error_count),)return reportdef _generate_report_test(self, rows, cid, tid, n, t, o, e):# e.g. 'pt1.1', 'ft1.1', etchas_output = bool(o or e)tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)name = t.id().split('.')[-1]doc = t.shortDescription() or ""desc = doc and ('%s: %s' % (name, doc)) or nametmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL# o and e should be byte string because they are collected from stdout and stderr?if isinstance(o,str):# TODO: some problem with 'string_escape': it escape \n and mess up formating# uo = unicode(o.encode('string_escape'))# uo = o.decode('latin-1')uo = eelse:uo = oif isinstance(e,str):# TODO: some problem with 'string_escape': it escape \n and mess up formating# ue = unicode(e.encode('string_escape'))# ue = e.decode('latin-1')ue = eelse:ue = escript = self.REPORT_TEST_OUTPUT_TMPL % dict(id = tid,output = saxutils.escape(str(uo)+ue),)row = tmpl % dict(tid = tid,Class = (n == 0 and 'hiddenRow' or 'none'),style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),desc = desc,script = script,status = self.STATUS[n],)rows.append(row)if not has_output:returndef _generate_ending(self):return self.ENDING_TMPL############################################################################### Facilities for running tests from the command line############################################################################### Note: Reuse unittest.TestProgram to launch test. In the future we may# build our own launcher to support more specific command line# parameters like test title, CSS, etc.class TestProgram(unittest.TestProgram):"""A variation of the unittest.TestProgram. Please refer to the baseclass for command line parameters."""def runTests(self):# Pick HTMLTestRunner as the default test runner.# base class's testRunner parameter is not useful because it means# we have to instantiate HTMLTestRunner before we know self.verbosity.if self.testRunner is None:self.testRunner = HTMLTestRunner(verbosity=self.verbosity)unittest.TestProgram.runTests(self)main = TestProgram############################################################################### Executing this module from the command line##############################################################################if __name__ == "__main__":main(module=None)

  • 使用

接下来,小编将以登录网易邮箱为例,生成一份最基础的测试报告。小伙伴们copy走代码验证时一定记得修改账号密码哦。

目录结构如下:

 将HTMLTestRunner.py文件存放到package包下,将test_login.py存放到testcase目录下,用于编写测试用例,建立testreport包,用于存放测试报告,在email目录下建立run_test.py,用于执行测试

HTMLTestRunner的使用方法在代码注释中介绍和解释

【test_login.py】

from selenium import webdriverimport unittest,timeclass Login(unittest.TestCase):def setUp(self):#打开百度,搜索“163网易邮箱”,登录driver=webdriver.Firefox()driver.implicitly_wait(5)self.driver=driverdriver.get("https://www.baidu.com/")driver.find_element_by_id("kw").send_keys("163邮箱登录")driver.find_element_by_id("su").click()name = driver.find_element_by_id("op_email3_username")password = driver.find_element_by_class_name("op_email3_password")login = driver.find_element_by_css_selector(".c-btn")#如下操作可以使setUp中的变量被其他模块调用self.name=nameself.password=passwordself.login=logindef tearDown(self):self.driver.quit()def switch_window(self):#切换窗口for handle in self.driver.window_handles:self.driver.switch_to.window(handle)#j增加等待时间,可以提高测试用例执行的健壮性time.sleep(2)time.sleep(3)#成功登录def test_right_login(self):#账号密码自行填写self.name.send_keys("xxx")self.password.send_keys("xxx")self.login.click()self.switch_window()#t通过新窗口的title验证用例是否通过self.assertEqual(self.driver.title,"网易邮箱6.0版","登录失败")#密码为空登录def test_null_psw_login(self):self.name.send_keys("xxx")time.sleep(3)self.login.click()self.switch_window()# t通过新窗口的title验证用例是否通过self.assertEqual(self.driver.title,"网易帐号中心 > 用户验证","未跳转至用户验证界面")

【run_test.py】


#导入HTMLTestRunner的包from package import HTMLTestRunner#导入test_login的包,执行测试用例时需使用from testcase.test_login import *#定义要执行的测试用例的路径test_dir = './testcase'#定义要执行的测试用例的路径和名称格式#test_*.py的意思是,./testcase路径下文件名称格式为test_*.py的文件,*为任意匹配,路径下有多少的test_*.py格式的文件,就依次执行几个discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')#定义测试报告的名称和存储位置filename = './testreport/loginReport.html'#开始执行if __name__ == '__main__':suit=unittest.TestSuite()suit.addTest(Login("test_right_login"))suit.addTest(Login("test_null_psw_login"))#以wb(可写的二进制文件)形式,打开文件,若文件不存在,则先执行创建,再执行打开fp = open(filename, 'wb')#调用HTMLTestRunner生成报告runner = HTMLTestRunner.HTMLTestRunner(# 指定测试报告的文件stream=fp,# 测试报告的标题title=u"登录网易邮箱测试报告",# 测试报告的副标题description=u'用例执行情况(win7 64位)')#执行用例runner.run(discover)

  • 报告展示

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】(基础篇十八) —— 触发器

触发器 本文学习什么是触发器&#xff0c;为什么要使用触发器以及如何使用触发器&#xff0c;还介绍创建和使用触发器的语法。 MySQL语句在需要时被执行&#xff0c;存储过程也是如此。但是&#xff0c;如果你想要某条语句&#xff08;或某些语句&#xff09;在事件发生自动执…

如何断点调试opencv源码

分几个步骤&#xff1a; 1、下载opencv-4.10.0-windows.exe https://opencv.org/releases/ 2、想要调试opencv的源码&#xff0c;只需要将这两个文件拷贝到我们自己项目的可执行文件的同级目录内即可。 完成拷贝后&#xff0c;直接在vs工程中打断点F11进行单步调试&#xff…

【漏洞复现】FastAdmin——任意文件读取漏洞

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 FastAdmin是一个免费开源的后台管理框架&#xff0c;其lang存在…

前端初学日记 (四) VUE指令

VUE 概述 Vue是一套用于构建用户界面的渐进式框架 Vue.js 是前端的主流框架之一 优点 1、体积小 压缩后 33K 2、更高的运行效率 3、双向数据绑定,简化 Dom 操作 基本指令 v-bind <!DOCTYPE html> <html><head><meta charset"utf-8">…

linux yum和apt指令

目录 yum apt yum和apt的区别 优缺点 总结 yum yum&#xff08;Yellowdog Updater, Modified&#xff09;是一个在Fedora、RedHat以及CentOS等基于RPM的Linux发行版中的Shell前端软件包管理器。它的主要功能包括&#xff1a; 软件包管理&#xff1a;从指定的服务器自动下…

计算机网络 —— 网络字节序

网络字节序 1、网络字节序 (Network Byte Order)和本机转换 1、大端、小端字节序 “大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处&#xff1b;小端存储在起始地址处&#xff0c;即是小端字节序&#xff1b;大端存储在起始地址处&#xff0c;即是大端字节…

以创新赋能引领鸿蒙应用开发,凡泰极客亮相华为HDC2024

6月21日至23日&#xff0c;华为开发者大会2024在松山湖举行。大会现场&#xff0c;华为发布了HarmonyOS、盘古大模型等方面最新进展。国内外众多企业齐聚一堂&#xff0c;共迎新商机、共创新技术、共享新体验。 凡泰极客作为鸿蒙生态的重要战略合作伙伴&#xff0c;同时也是鸿…

AUTOSAR NvM模块(二)

NvMMaxNumOfReadRetries 定义了最大读取重试次数。当前版本的NvM不支持此功能&#xff0c;因此此参数始终需要设置为0。 NvMMaxNumOfWriteRetries 定义了最大写入重试次数。当前版本的NvM不支持此功能&#xff0c;因此这个参数总是需要设置为0。 NvMNvBlockLength 定义了N…

Winform中控件与模型MVC

在Windows Forms (WinForms) 应用程序开发中&#xff0c;用户控件(UserControl)与模型(Model)的结合使用是一种常见的MVC&#xff08;Model-View-Controller&#xff09;模式的体现&#xff0c;能够有效地分离界面表示层与业务逻辑层&#xff0c;从而提高代码的可维护性和复用性…

【vue3|第14期】深入Vue3自定义Hooks:掌握组件逻辑复用的核心

日期&#xff1a;2024年6月26日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

动力环境监控系统内部绝密报价!动环监控系统全套价格一览

作为一个综合性的监控系统&#xff0c;动力环境监控系统包含动力系统、环境系统、安防系统等&#xff0c;是整个机房的控制中枢&#xff0c;无论哪里出现问题都可以实时监测到&#xff0c;并在第一时间通知管理人员。当然&#xff0c;根据机房大小和监测需求不同&#xff0c;动…

Windows系统开启python虚拟环境

.\env4socre\Scripts\activate : 无法加载文件 E:\SocreMan\env4socre\Scripts\Activate.ps1&#xff0c;因为在此系统上禁止运行脚本。 环境&#xff1a;windows 11、vscode 1、用管理员权限打开powershell 输入set-executionpolicy remotesigned&#xff0c;选择Y 2、返回v…

初识ECMAScript 6 (ES6)

ECMAScript 6 (ES6)&#xff0c;也称为 ECMAScript 2015&#xff0c;是 JavaScript 的一个主要更新&#xff0c;增加了许多新的特性和改进&#xff0c;使得编写 JavaScript 更加简洁、高效和易于维护。以下是 ES6 中的一些重要特性及其详细阐述&#xff1a; 1. 块级作用域 (Bl…

稀疏迭代最近点算法(Sparse ICP)

2013年&#xff0c;2013年Sofien Bouaziz等提出了一种新的ICP改进算法&#xff0c;稀疏迭代最近点(Sparse Iterative Closest Point, Sparse ICP)算法。更多扩展资料可参看随书附赠资源中的说明文档。 Sparse ICP算法的设计的灵感、应用范围、优缺点和泛化能力 两个几何数据集…

oninput和onchange事件有什么区别?

onchange事件&#xff1a;触发条件&#xff1a;在域内容更改时触发&#xff0c;也可用于单选框和复选框改变后触发&#xff1b;作用 对象&#xff1a;select、input、textarea。 oninput事件&#xff1a;触发事件&#xff1a;在域内容更改时触发&#xff08;严格说是用户输入时…

NAS—网络附加存储

关键词&#xff1a;私有化存储、Nas、云盘、群晖、Tailscale、 前言 身处于互联网时代的我们&#xff0c;几乎每时每刻都在与计算机打交道&#xff0c;而软件则作为我们和计算机之间沟通的桥梁&#xff0c;因此可以认为软件的作用是&#xff1a;将计算机能力进行包装&#xf…

【React】如何监听LocalStorage的变化

在代码中遇到了需要在react中监听localStorage的数据&#xff0c;下意识想到的是按照useEffect监听useState变化那一套&#xff0c;但是未生效。 代码如下&#xff1a; useEffect(()>{console.log("变化了") },[localStorage.getItem(data)])需要使用监听器 us…

Java基础入门day72

day72 mybatis mybatis的实现方式 三种实现方式&#xff1a; 纯xml方式&#xff0c;namespace随便写&#xff0c;id随便写&#xff0c;只要保证整个项目namespaceid唯一即可 xml接口的方式&#xff0c;namespace必须是接口的全路径&#xff0c;id必须是接口的方法名&#xf…

瓦罗兰特新赛季更新资讯 瓦罗兰特新赛季免费加速器

瓦罗兰特新赛季来喽&#xff0c;这是一款由拳头开发的免费第一人称射击游戏&#xff0c;游戏凭借其独特的玩法和丰富的英雄选择吸引了大量玩家。 我们可以在游戏中选择自己喜欢的角色出场与敌人进行对战&#xff0c;而且每一个角色都有自己独特的道具以及技能&#xff0c;使用好…

SwiftUI 中的内容边距

文章目录 前言创建示例适配 iPad使用 contentMargins可运行 Demo总结前言 SwiftUI 引入了一组视图修饰符,使我们能够有效地管理视图中的安全区域。在许多情况下,安全区域是你希望放置内容的地方。今天,我们将了解 SwiftUI 引入的新内容边距概念以及它与安全区域的区别。 创…