基于大语言模型的自动化单元测试生成系统及测试套件评估方法
A System for Automated Unit Test Generation Using Large Language Models and Assessment of Generated Test Suites
翻译于上述论文
基于大语言模型的自动化单元测试生成系统及测试套件评估方法
摘要
单元测试是软件测试生命周期中最基础的测试层级,对确保软件正确性至关重要。设计和创建单元测试是一个成本高昂且劳动密集型的过程,非常适合进行自动化。近年来,大语言模型(LLMs)已被应用于软件开发的各个方面,包括单元测试生成。尽管已有若干评估LLMs在测试代码生成能力的实证研究,但这些研究主要关注简单场景,例如为单个方法直接生成单元测试。这些评估通常涉及独立且小规模的测试单元,未能全面反映LLMs在真实软件开发场景中的表现。此外,先前的研究未能以适合实际应用的规模处理问题。生成的单元测试通常通过手动集成到原始项目中进行评估,这一过程限制了执行的测试数量并降低了整体效率。
为解决这些不足,我们开发了一种生成和评估更接近真实复杂度的测试套件的方法。我们的方法专注于类级别的测试代码生成,并自动化从测试生成到测试评估的整个过程。本文中,我们介绍了AgonetTest:一个为Java项目生成测试套件的自动化系统,以及一套全面且系统的评估生成测试套件的方法。基于最先进的数据集(即Methods2Test),我们构建了一个新的数据集,用于比较人工编写的测试与LLMs生成的测试。我们的主要贡献包括一个可扩展的自动化软件系统、一个新数据集以及详细的测试质量评估方法。
关键词:软件测试、大语言模型、自动化评估
I. 引言
软件测试是软件开发生命周期中的关键步骤,对确保代码正确性和可靠性至关重要。其中,单元测试是验证单个代码单元功能是否正常的阶段。设计和构建单元测试是一个成本高昂且劳动密集型的过程,需要大量时间和专业技能。自动化这一过程是一个充满前景的研究和开发领域。
自动生成单元测试的工具可以减轻测试工程师和软件开发人员的工作负担。这些工具通常使用静态代码分析方法生成测试套件。例如,EvoSuite [1]是一种结合静态代码分析和进化搜索的流行工具,已被证明能够实现足够的覆盖率。
大语言模型(LLMs)已高效应用于软件开发的多个方面,同样可以处理单元测试的自动生成。多项关于LLMs的实证研究强调了它们在简单场景中生成测试的能力,通常仅限于单个方法[2, 3, 4, 5]。尽管这些探索具有一定的方向性意义,但它们关注的是独立且小规模的测试单元,未能全面反映LLMs在真实软件开发场景中的表现[6]。此外,先前的研究未能以适合实际应用的规模处理问题。生成的单元测试通常通过手动集成到原始项目中进行评估,这一过程限制了执行的测试数量并降低了整体效率。
为解决这些不足,我们开发了一种生成和评估更接近真实复杂度的测试套件的方法。我们的方法专注于类级别的测试代码生成,并自动化从测试生成到测试评估的整个过程。
本文中,我们介绍了AgonetTest,这是一个为Java项目生成测试套件的自动化系统,并附带一套严格且系统的方法来评估这些生成的测试套件。基于Methods2Test数据集[7],我们开发了一个新的数据集,专门用于比较人工编写的测试与LLMs生成的测试。我们集成了JaCoCo、PITest和TsDetect等库来计算测试评估指标。
我们的工作主要贡献如下:
- AgoneTest:我们设计并开发了一个闭环、高度自动化的软件系统,支持大规模生成和评估单元测试的过程。该系统的初始版本针对真实开源Java项目,集成了JaCoCo、PITest和TsDetect等关键库;
- 方法论:基于AgoneTest,我们提出了一套全面评估多种LLMs及其提示技术和提示模式的方法,以及用于评估生成测试套件质量的指标和测试坏味道;
- Classes2Test:一个扩展Methods2Test[7]的带注释的开源Java项目数据集,将目标类与其相关的测试类映射起来。这一扩展数据集使得评估LLMs在整个类上的测试表现成为可能,而不仅限于单个方法。
本文的组织结构如下:第二节介绍背景并强调我们的工作与相关工作的差异;第三节概述AgoneTest及其模块,详细说明其功能范围;第四节通过一个端到端的示例展示AgoneTest的实际应用;第五节通过框架的初步评估回答关键研究问题;第六节总结实验中的见解和经验教训;第七节讨论我们方法的局限性;第八节总结全文并展望未来工作方向。
II. 背景与相关工作
A. 单元测试生成
单元测试生成是为单个软件组件(如函数、方法或模块)自动创建测试用例的过程。这些测试用例用于独立验证每个单元的功能是否正确。
现有技术采用基于随机性[8, 9]、基于约束[10, 11]或基于搜索的方法[12, 13]。这些方法的核心思想是将问题转化为可通过数学方法解决的问题。例如,基于搜索的技术将测试转化为优化问题以生成单元测试用例[14]。因此,这些技术的目标是生成所有可能的解决方案,然后选择那些能够实现更高代码覆盖率的方案。EvoSuite [1]通过接受Java类或方法作为输入,并应用基于搜索的算法生成满足代码或分支覆盖率等标准的测试套件。EvoSuite通过变异、选择和优化的迭代过程评估测试的适应性。它不仅生成JUnit测试用例,还通过检查生成的测试套件的效率(基于代码覆盖率和变异分数等指标)提供全面的报告。EvoSuite的一个局限性是其生成的测试通常缺乏清晰性和可读性[15]。此外,EvoSuite仅适用于使用Java 9或更低版本的项目,这限制了其在更现代Java项目中的适用性(目前最新的Java版本为22)。与EvoSuite不同,AgoneTest通过集成先进的评估指标和测试坏味道识别,提供了对生成测试套件质量的更全面评估,并利用类似人类编写的LLM生成代码确保可读性。此外,AgoneTest支持所有Java LTS版本,使得基于更新版本构建的项目也能被测试,克服了EvoSuite的兼容性限制。
B. 用于测试生成的大语言模型
自LLMs出现以来,它们已被用于测试套件生成。最初利用LLMs的技术被视为神经机器翻译问题的解决方案[16, 17]。这类方法通过从主要方法翻译到适当的测试前缀或测试断言,同时使用测试生成数据集对LLMs进行微调。例如,AthenaTest [17]使用测试生成数据集优化BART [18],其中源是主要方法及其对应的代码上下文,结果是完整的测试用例。AthenaTest主要专注于通过微调单个模型生成方法级测试,而AgoneTest将重点转向类级测试的生成。我们的方法使得可以使用最新的LLMs,并且不受提示设计的限制,从而能够处理更复杂的真实场景。
随着指令调优LLMs的快速发展,利用适当提示引导LLMs生成测试的方法正在兴起,而不是通过模型微调[19, 20]。目前已出现多项评估LLMs在测试套件生成中的能力的提案。例如,ChatTester[5]提出了一种基于ChatGPT评估和改进LLM生成测试的工具。ChatTester专注于改进和评估特定LLM(ChatGPT)生成的测试,但需要人工干预来评估生成的代码,并且未提供对多种LLMs在类级测试上的评估。AgoneTest则支持多种LLMs,并在大量真实Java项目上评估每种LLM的表现。TestPilot[3]也专注于使用LLMs生成和改进JavaScript代码的测试。尽管TestPilot进行了自动化评估,但其适用性仅限于其参考工作中提到的25个仓库。AgoneTest通过使用包含9,410个Github仓库的数据集,并自动集成测试库,提供了更广泛的适用性。Cedar[21]提出了一种基于少样本学习[22]和Codex模型的提示构建策略来生成测试。Cedar使用特定的提示构建策略,但未集成结构化机制以统一框架评估多种LLMs和提示技术。AgoneTest通过允许集成和评估各种提示工程技术和LLMs,提供了更全面的测试生成方法。Guilherme和Vincenzi [2]使用gpt-3.5-turbo分析模型超参数变化的影响。Guilherme和Vincenzi的研究提供了初步评估,但缺乏在变异覆盖率和测试坏味道等全面测试质量指标上的自动化评估。AgoneTest通过自动化这些评估,集成先进指标以提供对生成测试的更深入分析,进一步推进了研究。Siddiq等人[4]提出了一种使用常见数据集评估生成测试的新方法,并尝试使用新指标[23]。尽管Siddiq等人使用了测试正确性(但未使用变异覆盖率)以及AgoneTest使用的所有指标,但其方法未完全自动化测试生成-执行-评估循环,也未专注于类级测试。AgoneTest通过提供端到端自动化并专注于生成和评估复杂的类级测试套件,填补了这一空白。
C. 当前LLMs应用于单元测试生成方法的局限性
尽管前景广阔,当前将LLMs应用于单元测试生成的方法仍存在若干局限性:
a) 范围有限:当前评估LLMs在测试代码生成中有用性的方法大多仅限于生成代码片段,而非整个模块或组件(例如Java中的整个类)。因此,研究社区缺乏用于评估类级测试生成的专用数据集。据我们所知,研究通常仅对生成结果提供零散和轶事性的评估[3, 5, 17]。
b) 缺乏自动化:目前尚未有文献提出能够完全自动化测试生成-执行-评估循环的工作,而这对于全面和可扩展的测试至关重要[3, 19, 20]。
c) 提示选择的主观性:在大多数情况下,选择提示以让LLMs生成测试代码仍然是主观的。没有对最初提出的提示技术与其他替代技术进行彻底评估,这为提示工程的进一步探索和优化留下了空间[4, 20, 21]。
III. AGONETEST概述
“agone”一词源于古希腊和罗马,指的是哲学家们辩论观点并由观众决定胜负的竞赛。我们借用这一术语隐喻性地表示LLMs及其各自提示策略在生成最优单元测试套件的竞技场中的竞争性评估。AGONETEST基于标准测试质量指标(我们将在后续章节中详细说明)确定最优策略。
AGONETEST旨在为软件测试人员提供一个生成和评估单元测试的系统。这一评估侧重于代码覆盖率和已知测试坏味道等关键指标,从而提供对测试套件质量的全面评估。
AGONETEST基于以下原则运行:通过测试工程师和数据科学家(或提示工程师)的协作,可以评估LLMs在生成高质量单元测试任务中的表现。然而,在实践中,一位熟悉生成式AI的经验丰富的测试工程师可以同时扮演这两个角色,从而只需专注于定义新的提示技术和LLMs的比较。在本文的剩余部分中,当我们提到AGONETEST用户(或“测试工程师”)时,指的就是这一角色。
该系统通过以下阶段协助测试工程师:
- 策略配置
- 自动化测试生成
- 策略评估
图1展示了AGONETEST架构的高层示意图,显示了简化测试生成和评估流程的操作模块。这些模块描述如下:
样本项目选择(策略配置 - I):作为初始配置步骤,用户选择要为哪些仓库生成测试套件。这一初始阶段利用我们贡献给社区的一个带注释的开源Java仓库的全面数据集。它涉及准备、加载和管理系统将要测试的仓库。
配置参数提取(策略配置 - II):在这一阶段,从选定的仓库中提取配置参数(例如项目Java版本、使用的测试框架等),并处理这些参数以创建LLMs的提示模板。
提示创建(自动化测试生成 - I):在此阶段,前一阶段的提示模板被完全实例化,然后用于在下一步生成单元测试套件。
测试套件生成(自动化测试生成 - II):在此阶段,AGONETEST协调与选定LLMs的交互,向其提供实例化的提示以生成单元测试代码。每个LLM生成的测试类随后被集成到项目结构中。
A. 配置参数提取
在单元测试生成开始之前,系统从上一阶段选定的项目中提取一些参数。这些参数随后被输入到选择提示和LLMs的模块中。为了查询被检查的模型,可以选择多种提示技术[24]。
配置参数包括:
- focal_class:该变量包含需要为其生成测试套件的Java类;
- testing_framework:该变量提供项目测试框架的名称和版本(例如JUnit 4),在执行期间直接从项目中提取;
- java_version:该变量允许检索项目使用的Java版本;
- example_focal_class & example_test_class:这些变量包含从参考仓库中提取的示例目标类及其对应的测试类,如果用户希望使用少样本提示技术,这些示例对LLM非常有用;
- example_testing_framework & example_java_version:这些变量提供关于示例仓库的信息。
参见第IV-A节中的真实实现示例。
B. 提示创建
在此阶段,前一阶段描述的提示模板被完全实例化,以创建可行的提示来指导LLM生成单元测试。我们通过替换第III-B节中概述的变量来填充用户提供的提示结构。
需要注意的是,为了确保我们的实验和发现可复现,我们通过保存用作源的仓库的提交哈希来准备Classes2Test。这使得AGONETEST能够一致地提取诸如使用的Java版本、测试框架类型(例如jUnit)及其版本等信息。
与之前需要人工输入上下文信息以创建单元测试的LLMs方法不同[2, 5],AgoneTest在更大程度上自动化了这一过程。AgoneTest使用ElementTree [25]和解析器来读取和修改Maven和Gradle构建(参见第III-E3节)。它分析每个构建系统中存在的库和使用的Java版本。这种方法以及使用示例的能力,为用户提供了一个生成提示的灵活系统。
C. 测试套件生成
在流程的这一阶段,我们已经具备了为项目的每个目标类生成测试套件所需的一切。为了确保每个模型具有适当数量的令牌,我们使用tiktoken5(一种BPE分词器[26])来评估提示中的令牌计数。如果超出限制,AgoneTest会向用户返回错误,指明超出的令牌数量。
我们强调,AgoneTest允许用户自动评估多种LLMs。这一能力由开源的LiteLLM库提供,该库基于OpenAI API格式的标准交互,促进了与100多个模型的通信。LiteLLM通过将输入转换为满足每个提供商的独特端点需求,简化了集成。在当前环境中,由于LLM提供商缺乏标准API规范,将多个LLMs集成到项目中具有挑战性,因此这一点至关重要。
在调用LLM之后,AgoneTest从LLM的答案(即生成的测试类)中选择相关信息。这一步骤对整个流程的自动化至关重要,因为LLMs可能会提供详细的描述或解释代码应该如何结构化,而实际上并未生成代码[27]。在此组件中,AgoneTest移除不必要的部分(如大纲描述),并创建一个新文件以将测试类集成到项目中。
D. 测试套件评估
在此阶段,我们根据以下质量指标和测试坏味道评估测试套件的质量。指标和测试坏味道的实际确定通过库集成完成,从而实现测试套件评估的完全自动化。需要注意的是,此组件与后文讨论的实验评估是分开的。相反,它作为AgoneTest提供的额外工具,帮助工程师评估生成测试的质量。
1. 覆盖率指标
- 行覆盖率[28]:该指标衡量测试过程中执行的代码行百分比。100%的行覆盖率意味着软件中的每一行代码在测试期间至少运行了一次。我们选择它是因为它直接显示了被测试的源代码部分。
- 方法覆盖率[28]:类似于行覆盖率,该指标关注代码中的特定方法或函数。100%的方法覆盖率意味着所有方法在测试期间至少运行了一次。该指标有助于识别可能未被充分测试的方法。
- 分支覆盖率[28]:该指标计算测试中执行的决策点(如if或switch语句)的百分比。它确保测试了代码中的所有可能路径,这可以发现仅靠行或方法覆盖率可能遗漏的缺陷。
- 指令覆盖率:该指标计算测试期间执行的Java字节码指令数量。这是一个详细的指标,不受源代码格式的影响,即使类文件中没有调试信息也可以确定。这有助于精确定位未被测试覆盖的最小代码片段。
- 变异覆盖率[28]:该指标评估测试在识别代码中故意引入的变化(变异,如修改算术操作或反转条件)方面的有效性。如果测试检测到所有变异(即识别所有变化),则变异覆盖率得分为100%。选择该指标是因为它衡量了测试套件的鲁棒性。
2. 测试坏味道[23]
这些是低效或问题模式的指标,可能对测试代码的可维护性和有效性产生负面影响。识别测试坏味道有助于随时间提高测试代码的质量,并提高对测试设计中潜在问题的认识。AgoneTest确定代码中是否存在以下测试坏味道:
- Assertion Roulette (AR) [29]:表示包含多个断言语句但无解释/消息(断言方法中的参数)的测试方法数量;
- Conditional Test Logic (CTL) [30]:表示包含一个或多个控制语句(即if、switch、条件表达式、for、foreach和while语句)的测试方法数量;
- Constructor Initialization (CI) [31]:表示测试类是否包含构造函数声明;
- Default Test:表示测试类是否命名为’ExampleUnitTest’或’ExampleInstrumentedTest’;
- Duplicate Assert (DA) [31]:表示包含多个具有相同参数的断言语句的测试方法数量;
- Eager Test (EA) [29]:表示包含对多个生产方法的多次调用的测试方法数量;
- Empty Test (EM) [31]:表示不包含任何可执行语句的测试方法数量;
- Exception Handling (EH) [31]:表示包含throw语句或catch子句的测试方法数量;
- General Fixture:如果测试类的setUp方法中实例化的字段未被同一测试类中的所有测试方法全部使用,则为1;
- Ignored Test (IT) [31]:表示包含@Ignore注解的测试方法数量;
- Lazy Test (LT) [29]:表示调用同一生产方法的测试方法数量;
- Magic Number Test (MNT) [30]:表示包含作为参数的数值字面量的测试方法数量;
- Mystery Guest:表示包含文件或数据库类对象实例的测试方法数量;
- Redundant Print (RP) [31]:表示调用System类的print、println、printf或write方法的测试方法数量;
- Redundant Assertion (RA) [31]:表示包含预期参数和实际参数相同的断言语句的测试方法数量;
- Resource Optimism (RO) [31]:表示使用File类实例但未调用对象的exists()、isFile()或notExists()方法的测试方法数量;
- Sensitive Equality (SE) [29]:表示调用对象toString()方法的测试方法数量;
- Sleepy Test:表示调用Thread.sleep()方法的测试方法数量;
- Unknown Test (UT) [31]:表示不包含任何断言语句和@Test(expected)注解参数的测试方法数量。
3. 库集成
我们使用以下库来计算指标:
- JaCoCo:JaCoCo是一个免费的Java库,用于测量测试套件执行中的代码覆盖率。它帮助开发人员识别代码库中哪些部分已被充分测试,哪些部分尚未被测试,从而更好地理解项目中的测试覆盖率。我们选择JaCoCo是因为其广泛采用、与构建工具轻松集成的能力以及生成报告的功能,这对指标评估至关重要。
- PiTest [32]:PiTest是一个用于Java和基于JVM系统的变异测试系统。它超越了传统的行和语句覆盖率指标,提供了关于测试套件鲁棒性的更具体见解。PiTest在源代码中引入小的变化或变异,然后重新运行测试以确定这些变化是否被检测到。我们选择PiTest是因为与传统的覆盖率工具相比,它提供了对被测系统实际行为和响应的更细粒度和更真实的视图。
- TSDETECT [33]:TSDETECT是一个专注于自动检测软件项目中测试坏味道的库。测试坏味道指的是测试代码中的模式,可能表明设计或实现问题,导致测试可维护性降低并可能阻碍代码理解。选择TSDETECT是因为其能够识别这些坏味道并提供代码改进的可操作指南。
在此阶段,AGONETEST自动将这些库包含到项目中。对于每次运行,AGONETEST检查支持的构建系统(Maven和Gradle,第III-C节)的配置文件,以确定必要的库是否已存在。如果不存在,它会修改配置以添加所需的依赖项。
AGONETEST展示了高度的自动化,如其处理PiTest库的方式所示。具体来说,如果仓库使用JUnit 5测试框架,则需要额外的库“pitest-junit5-plugin”。利用从仓库的提示创建模块(第III-C节)中提取的信息,AGONETEST自动识别使用的测试框架并添加此依赖项,无需任何人工干预。
4. 自动化测试套件评估
添加必要的库后,AGONETEST运行构建和测试以确保没有编译错误。我们流程的测试套件评估阶段具有高度的自动化,如下所述。
AGONETEST生成一份报告,包含为LLM生成的测试计算的测试坏味道和指标结果。为此,该工具自动从库生成的报告中检索详细信息,为每个项目中的每个类编译这些数据。
这一广泛的计算过程使得对生成的测试套件进行详细分析成为可能。通过对比结果,该模块有助于识别与每个LLM和提示配置相关的具体优势和劣势。它提供了关于LLMs表现出色的领域的见解,并突出了可能需要改进的潜在差距。
此外,这种比较有助于清晰理解不同LLMs和提示如何影响测试生成质量的细微差别。它支持识别生成高质量测试的最佳配置。这一详细分析对于改进LLMs和增强其在自动化测试生成中的能力至关重要。
通过提供如此深入的评估,AGONETEST成为研究人员和开发人员的宝贵工具。它有助于LLMs的持续改进,并推动自动化测试领域的进步。最终,它可以确保生成的测试稳健可靠,提高自动化测试解决方案的有效性。
IV. AGONETEST实践
在本节中,我们将通过描述一个实际示例的端到端运行来展示AGONETEST的实际操作。
我们将在描述中跳过仓库选择阶段,直接进入配置阶段,该阶段涉及LLM选择和提示规范。然后,我们将举例说明结果如何呈现给用户以供进一步分析。
A. 配置
如第III-B节所述,AgoneTest使用YAML文件作为输入,可以在其中指定与两个元素相关的信息:llms和prompts。清单1中表示的YAML文件声明了使用OpenAI提供的’gpt-4’和’gpt-3.5 turbo’模型。
清单1. YAML配置文件的设置:为两个不同的LLMs和两个不同的提示设置变量。
llms:- model: gpt-4-1106-previewtemperature: 0- model: gpt-3.5-turbotemperature: 0prompts:- name: zero-shotvalue:- role: systemcontent: You are provided with Java class. Create a test class that fully tests the proposed Java class using the project information for imports. Reply with code only, do not add other text that is not code- role: usercontent: "The project uses {{testing_framework}} and Java {{java_version}} and Java class is : \n<code>\n{{focal_class}}\n</code>"- name: few-shotvalue:- role: systemcontent: You are provided with an example with a Java class and its test class. You are then provided with a new Java class. Take a cue from the example and create a test class that fully tests the new proposed Java class. Reply with code only, do not add other text that is not code- role: usercontent: "#Example:\nThe example Java class is:\n<code>\n{{example_java_class}}\n</code>\nThe example test class is:\n<code>\n{{example_test_class}}\n</code>\nThe Java class you must create the test for is:\n<code>\n{{focal_class}}\n</code>"
提示规范声明包含两个部分:name和value。name是用于标记提示类型的标识符(零样本、少样本等)。而value是一个OpenAI消息类型的数组。每条消息包含一个role和一个content。
role可以是以下类型之一:
- system:用于指示模型应采纳的行为。
- user:用于指示生成测试类的请求。
在YAML配置文件中,指定了两种类型的提示:zero-shot和few-shot。
1. 零样本(Zero-shot)
零样本指的是向模型呈现单个请求或任务实例,而不提供任何先前的示例供模型参考[34]。这种方法强调模型理解和准确执行给定任务的能力。
2. 少样本(Few-shot)
与零样本提示不同,少样本提示涉及向模型提供展示预期输入和输出的示例[22]。这种技术通过将示例包含在提示中,帮助模型进行上下文学习,从而引导模型生成更准确和相关的结果。这些示例作为实际请求的条件,帮助模型生成更准确和相关的结果。
此配置文件将指示AGONETEST执行第III-C节中描述的步骤:它将完全实例化模板变量,包括目标类、仓库使用的测试框架(及其版本)以及仓库中使用的JDK版本。
B. 结果呈现
生成阶段运行完成后,AGONETEST生成一个CSV文件,其中包含为每个选定的LLM和每种提示技术计算的目标类指标以及关于测试坏味道的结果。作为示例,表II显示了该文件的摘录,其中还包含人工编写测试的结果(如它们在CLASSES2TEST数据集中存在的那样)。
通过检查此文件,用户可以深入了解每个LLM和提示组合的优势和劣势。此外,软件测试人员可以准确评估LLM在创建可用和有效的类级测试方面的有效性。这一点在以下部分中变得清晰,我们描述了用于验证AGONETEST的实验设置并讨论了一些结果。
V. 评估
在此实验评估中,我们旨在解决以下研究问题:
- RQ1:在多大程度上可以实现生成测试套件的端到端自动化流程?我们分析框架的自动化程度以及需要人工干预的点(如果有的话)。
- RQ2:是否可以有效评估由不同LLMs和提示策略自动生成的测试套件的质量?我们调查框架是否可以提供关于测试套件在效率和鲁棒性方面的质量信息,并帮助识别优势、劣势和潜在的改进点。
A. 数据集
在我们的实验中,我们从数据集CLASSES2TEST中随机选择了10个仓库。这些仓库总共包含94个目标类,具有不同的长度和复杂性,如表III所示。随机选择的仓库样本大小足以代表真实项目中遇到的变异性(通常由一个或少数几个相互依赖的仓库组成),同时确保我们的系统在规模上是可处理的。
B. LLMs和提示配置
在我们的实验中,我们从LiteLLM支持的模型中选择了两款LLMs。我们选择了’gpt-4’和’gpt-3.5 turbo’模型。选择’gpt-4’是因为其在HumanEval基准测试[35]中的出色表现,而’gpt-3.5 turbo’作为早期一代模型,允许进行有意义的比较。
如表III所示,我们设置了温度参数为0,以增加文本生成的一致性水平(并降低随机性水平),并使生成的不同测试套件具有可比性。关于提示类型,我们决定尝试两种最流行的技术:零样本和少样本。这使我们能够展示AGONETEST的灵活性,并进一步探索第III-B节中看到的上下文变量的使用。在我们的实验中,少样本提示中提供的示例在所有LLMs中始终相同,以确保一致性。该示例包括从一个开放样本仓库中提取的目标类和测试类。
C. 数据收集和分析
并非从我们的样本仓库生成的所有测试套件都是有效的(即测试未通过,在某些情况下,代码甚至无法编译)。类似于[2],我们遇到了一些问题:一些测试由于语法错误或不正确或不存在的导入而无法构建。为了进入评估阶段,系统会自动移除存在错误的测试类以继续编译。一旦所有错误被移除,系统会进行编译和运行测试,以消除所有非绿色套件(即并非所有方法都执行无失败的类)。
这样做有两个原因:首先,在执行根本原因分析后,我们发现失败的测试类之所以失败,是因为它们被错误地指定,而不是因为存在错误。例如,测试失败是因为它们调用了库的私有或过时的方法,或者因为它们调用了不存在的API。第二个原因是拥有绿色套件是PiTest计算变异覆盖率的必要条件。在完成此清理阶段后,系统执行最终编译,运行测试和库以收集评估数据。
表IV显示了实验中编译并通过所有测试的类的数量。平均而言,我们在实验中观察到:
- 75%的生成测试类成功编译;
- 34%的生成测试类是绿色套件并具有可计算的变异覆盖率。
表V显示了不同LLMs和提示技术组合相对于AGONETEST计算的指标的性能的比较分析。我们还报告了人工编写测试的指标,以作为基准。
VI. 讨论与经验教训
在本节中,我们将回答先前定义的研究问题,并讨论经验教训以及未来可能的研究方向。
RQ1:在多大程度上可以实现生成测试套件的端到端自动化流程?
AGONETEST提供了一个端到端的自动化流程来生成和评估测试套件,无需人工干预。然而,我们的实验强调了两个需要注意的点:
- 生成测试类的编译成功率显示还有改进空间(在我们的实验中介于64%和76%之间);
- 测试通过率相对较低(介于30%和38%之间)。
进一步分析显示,许多生成的测试由于不正确的导入或语法错误而失败,而不是因为它们发现了之前未检测到的错误。为了改进这些结果并提高这些百分比,可以探索不同的路径。一种是人工介入:人工干预可能包括手动修复代码错误、调整设置或安装成功执行所需的库。
另一方面,就自动化而言,一个良好的结果是从项目配置文件(如Maven或Gradle)中自动提取上下文信息。这最大限度地减少了人工干预的需求,并提高了生成的提示和测试的准确性。
RQ2:是否可以有效评估由不同LLMs和提示策略自动生成的测试套件的质量?
AgoneTest提供了关于生成的测试套件质量的相关信息,包括代码覆盖率、测试套件对人工注入错误的鲁棒性(即变异覆盖率)以及测试坏味道。实际上,测试坏味道的存在表明测试设计和可维护性可能存在潜在问题。
在表V中,我们可以看到LLMs编写的测试套件在覆盖率方面已经具有良好的质量,但在鲁棒性方面应有所改进。人工编写测试的基准在变异覆盖率方面始终显示出更好的结果。将我们的LLMs驱动系统的输出与实际测试工程师编写的测试进行比较,为我们提供了关于每个模型-设置对的能力和限制的宝贵见解。我们的实验(表V)表明,不同LLMs的性能根据所使用的提示技术而有显著差异。令人惊讶的是,我们发现对于’gpt-4’,零样本提示的结果优于少样本提示。然而,需要注意的是,这并不意味着’gpt-4’是所有场景的最佳模型,这也不是我们实验的目标(即找到最佳模型)。由于模型的性能可能根据上下文的具体情况或提示的结构而有显著差异。因此,我们创建了AgoneTest:为用户提供一个系统,让他们可以尝试各种组合,以找到最适合其特定需求的LLM和提示配置。
A. 经验教训
在AgoneTest的开发和评估过程中,我们收集了几个关键见解,这些见解将指导框架的未来改进。这些经验教训对于完善系统和提高LLM生成测试的有效性至关重要。每个小节下面突出了遇到的具体挑战,并概述了潜在的解决方案。
1. 编译和测试通过率
我们的实验显示,编译和测试通过率在追求完全自动化的过程中还有提升空间。这些问题的原因多种多样(例如,导入的类不存在或缺失)。自动化纠正这些重复出现的问题是可能的[36],并将提高生成测试的成功率。一种有前景的方法是要求LLM本身分析生成的测试代码中的错误并提供修复。通过将识别出的错误作为反馈提供,LLM可以生成更正后的功能代码,从而提高初始输出。此外,通过结合上下文感知的验证和修复机制增强生成测试的鲁棒性,将确保测试套件与项目的特定结构紧密匹配。这种集成方法不仅自动化了错误纠正,还增强了测试生成过程的整体可靠性和有效性,更接近完全自动化、高质量测试套件生产的目标。
2. 变异测试中的性能
人工编写的测试在变异覆盖率方面始终优于LLM生成的测试,表明手动编写的测试在识别通过变异引入的代码变化方面更有效。为了解决这个问题,我们应该专注于通过改进提示算法和结合变异感知的测试生成技术来提高生成测试套件的鲁棒性。
3. 可扩展性和资源管理
自动化整个流程——下载项目、生成测试套件、集成库和执行评估——被证明是资源密集型的。高效管理和并行化这些任务可以减轻计算开销并提高可扩展性,使AgoneTest能够更有效地处理更大的数据集和代码库。
4. 提示技术的影响
提示技术的选择显著影响生成测试的质量。我们的实验表明,使用gpt-4的零样本提示产生了最佳结果,但性能在不同LLMs和提示的组合中有所不同。系统地探索和评估不同的提示策略将有助于识别最适合各种场景的配置。
5. 自动化上下文提取
向LLMs提供准确的上下文信息(如测试框架和Java版本)对于生成正确的测试类至关重要。自动化提取这些上下文信息减少了人工干预的需求,并提高了生成的提示和测试的质量。通过开发更复杂的解析器和上下文推理算法增强上下文提取的自动化,将动态适应各种项目配置。
6. 实际适用性
从GitHub上的实际开源Java仓库构建数据集确保了AgoneTest在真实场景中的运行。然而,确保数据集代表跨不同类型仓库和代码库的真实情况仍然是一个持续的目标。为了保持和提高实际适用性,我们应该不断升级和更新我们的数据集,以包括更广泛的真实仓库和项目结构,确保评估保持相关性和全面性。
这些经验教训指导我们进一步改进AgoneTest。通过实施这些改进,我们旨在开发一个更稳健、高效和可靠的自动化单元测试生成框架。
VII. 局限性
尽管AgoneTest提出了一个创新的框架,用于使用LLMs自动化生成和评估单元测试套件,但其当前实现和初步实验结果存在若干局限性。
A. 数据集与泛化性
在我们的评估中,我们依赖于新创建的Classes2Test数据集,该数据集源自Methods2Test。尽管该数据集旨在评估类级测试生成,但其范围仅限于Java项目。这使得我们的发现很难推广到其他编程语言。此外,Classes2Test中包含的仓库是基于其能够无错误编译的能力选择的,可能引入了对结构良好的代码库的偏见。
B. 模型与提示的变异性
测试的LLMs和提示数量有限:尽管AgoneTest支持多种LLMs和提示技术,我们的初始实验设置仅涉及两个模型(gpt-4和gpt-3.5 turbo)和两种提示类型(零样本和少样本)。随着LLMs和提示工程技术的不断发展,结果可能会因新模型和高级提示而有显著差异。我们初始测试的有限范围可能因此限制了结论的广度。
温度设置限制:在我们的实验中,我们将温度参数设置为0以确保一致性和可复现性。尽管这减少了随机性并增加了一致性,但它可能无意中限制了生成测试用例的创造力和多样性。不同的温度设置可能会产生更多样化的结果,但这在本研究中未进行探索。
C. 编译与执行失败
在我们的实验中观察到一个显著的局限性是某些生成的测试类的非编译和执行失败。大约66%的生成测试类在编译阶段被拒绝,或由于固有错误未能对指标做出积极贡献。这揭示了某些LLMs在一致生成语法和语义正确的测试代码方面的当前不足,影响了整体评估。
D. 评估指标
尽管我们采用了一套全面的指标和测试坏味道指示器,但这些指标本身可能无法完全捕捉测试套件的质量。
VIII. 结论与未来工作
在本文中,我们介绍了AgoneTest,这是一个使用LLMs自动化生成和评估单元测试套件的全面框架。该框架专注于生成复杂的类级测试套件,同时自动化从测试生成到集成和评估的整个测试过程。
我们的实验结果表明,AgoneTest可以在各种实际项目中生成和评估单元测试,提供关于不同LLMs和提示技术性能的详细见解。尽管初步结果令人鼓舞,但它们也突出了挑战,强调了进一步改进的必要性。
使用LLMs自动化单元测试生成是一个充满前景的领域。虽然当前的能力在某些任务(如变异覆盖率)上尚未达到人类工程师的水平,但在指令、行和方法覆盖率方面的良好结果表明,进一步的研究和改进可以弥合这一差距。未来的工作应专注于系统地研究最有效的LLMs和提示,同时持续改进针对常见问题的自动纠正机制。
参考文献
[参考文献部分内容与原文一致,此处不再重复翻译]
相关文章:
基于大语言模型的自动化单元测试生成系统及测试套件评估方法
A System for Automated Unit Test Generation Using Large Language Models and Assessment of Generated Test Suites 翻译于上述论文 基于大语言模型的自动化单元测试生成系统及测试套件评估方法 摘要 单元测试是软件测试生命周期中最基础的测试层级,对确保软…...
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
先给大家看一下网站的整体效果截图: 这个前端静态网站项目主要实现了以下功能: 商城首页、商品分类页、登录注册页、个人中心页、我的收藏页、我的订单页、商品详情页等功能。 最近不是在学习前端开发嘛,肯定要做一些项目来练习以下自己学…...
PyTorch深度学习框架60天进阶学习计划 - 第46天:自动化模型设计(一)
PyTorch深度学习框架60天进阶学习计划 - 第46天:自动化模型设计(一) 第一部分:使用ENAS算法生成图像分类网络 大家好!欢迎来到我们PyTorch深度学习框架60天进阶学习计划的第46天。今天我们要深入探讨一个话题——使用…...
【上海大学计算机系统结构实验报告】多机环境下MPI并行编程
实验目的 学习编制多进程并行程序实现如下功能: 创建多进程,输出进程号和进程数。运行多进程并行例子程序。编程实现大规模矩阵的并行计算。 实验过程及结果分析 实验环境 操作系统:Ubuntu 20.04开发工具:GCC 9.3.0、OpenMPI…...
实用电脑工具,轻松实现定时操作
软件介绍 如果你的电脑有时候需要像个听话的小助手一样,按照你的指令在特定时间做些事情,比如到了点就关机、开机,或者自动打开某个软件,那你可得了解下这个小帮手啦! 小巧功能却不少 程序定时器是一款超实用的电脑…...
jQuery — 动画和事件
介绍 jQuery动画与事件是提升网页交互的核心工具。动画方面,jQuery通过简洁API实现平滑过渡效果,提供预设方法如slideUp(),支持.animate()自定义CSS属性动画,并内置队列系统实现动画链式执行。开发者可精准控制动画速度、回调时机…...
Kubernetes相关的名词解释kube-proxy插件(3)
什么是kube-proxy? kube-proxy 是一个网络代理组件,运行在每个节点(Node)上,是 Kubernetes 服务(Service)功能的核心实现之一。它的主要职责是通过维护网络规则,实现集群内服务&…...
第3章 垃圾收集器与内存分配策略《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》
第3章 垃圾收集器与内存分配策略 3.2 对象已死 Java世界中的所有对象实例,垃圾收集器进行回收前就是确定对象哪些是活着的,哪些已经死去。 3.2.1 引用计数算法 常见的回答是:给对象中添加一个引用计数器,有地方引用࿰…...
MCP是什么?为什么突然那么火?
什么是MCP? MCP全称为Model Context Protocol(模型上下文协议),是由Anthropic公司在2024年11月推出的一个开源协议。Anthropic是一家以其开发的Claude大语言模型而闻名的公司。MCP旨在提供一个通用的开放标准,以简化大型语言模型…...
与终端同居日记:Linux指令の进阶撩拨手册
前情提要: 当你和终端的关系从「早安打卡」进阶到「深夜代码同居」,那些曾经高冷的指令开始展露致命の反差萌—— man 是那个永远在线的钢铁直男说明书,只会说:"想懂我?自己看文档!"(…...
STM32单片机入门学习——第42节: [12-2] BKP备份寄存器RTC实时时钟
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.19 STM32开发板学习——第42节: [12-2] BKP备份寄存器&RTC实时时钟 前言开发板说…...
AI 驱动抗生素发现:从靶点到化合物测试
AI 驱动抗生素发现:从靶点到化合物测试 目录 基于 AI 驱动的研发流程发现抗生素,整合靶点选择和深度学习分子生成,显著提升了候选药物发现效率。结合数据平衡技术,机器学习和 AutoML 能有效提升不平衡数据集分类性能。RibbonFold 是一种新的 AI 模型,可以准确预测淀粉样蛋…...
群晖威联通飞牛等nas如何把宿主机硬盘挂接到可道云docker容器中
可道云系统是用户常用的一款面向个人用户的轻量级私有云存储工具,以高效管理和安全存储为核心,打造便捷的数字化办公体验。但是用户希望把原有其他磁盘中文件挂接到这个新系统中有很大的难度,主要是对linux文件系统理解有很大的误区,认为目录结构是固定的…...
用 R 语言打造交互式叙事地图:讲述黄河源区生态变化的故事
目录 🌟 项目背景:黄河源头的生态变迁 🧰 技术栈介绍 🗺️ 最终效果预览 💻 项目构建步骤 1️⃣ 数据准备 2️⃣ 构建 Leaflet 地图 3️⃣ 使用 scrollama 实现滚动触发事件 4️⃣ 使用 R Markdown / Quarto 打包发布 🎬 效果展示截图 📦 完整代码仓库 …...
opencv(双线性插值原理)
双线性插值是一种图像缩放、旋转或平移时进行像素值估计的插值方法。当需要对图像进行变换时,特别是尺寸变化时,原始图像的某些像素坐标可能不再是新图像中的整数位置,这时就需要使用插值算法来确定这些非整数坐标的像素值。 双线性插值的工…...
Flutter 弹窗队列管理:实现一个线程安全的通用弹窗队列系统
在开发复杂的 Flutter 应用时,弹窗的管理往往是一个令人头疼的问题。尤其是在多个弹窗需要按顺序显示,或者弹窗的显示需要满足特定条件时,手动管理弹窗的显示和隐藏不仅繁琐,还容易出错。为了解决这个问题,我们可以实现…...
Linux压缩与解压命令完全指南:tar.gz、zip等格式详解
Linux压缩与解压命令完全指南:tar.gz、zip等格式详解 在Linux系统中,文件压缩和解压是日常操作中不可或缺的一部分。本文将全面介绍Linux下常用的压缩和解压命令,包括tar.gz、tar、zip等格式的区别和使用方法,帮助你高效管理文件…...
doris/clickhouse常用sql
一、doris常用SQL 1、doris统计数据库的总大小(单位:MB) SELECT table_schema AS database_name,ROUND(SUM(data_length) / 1024 / 1024, 2) AS database_size_MB FROM information_schema.tables WHERE table_schema NOT IN (information…...
实现AWS Lambda函数安全地请求企业内部API返回数据
需要编写一个Lambda函数在AWS云上运行,它需要访问企业内部的API获取JSON格式的数据,企业有网关和防火墙,API有公司的okta身份认证,通过公司的域账号来授权访问,现在需要创建一个专用的域账号,让Lambda函数访…...
【Easylive】Interact与Web服务调用实例及网关安全拦截机制解析
【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版 easylive-cloud-interacteasylive-cloud-web 1. 不同服务(web和interact)之间的调用方式 调用流程 • 角色分工: • easylive-cloud-web:作…...
【HDFS】EC重构过程中的校验功能:DecodingValidator
一、动机 DecodingValidator是在HDFS-15759中引入的一个用于校验EC数据重构正确性的组件。 先说下引入DecodingValidator的动机,据很多已知的ISSUE(如HDFS-14768, HDFS-15186, HDFS-15240,这些目前都已经fix了)反馈, EC在重构的时候可能会有各种各样的问题,导致数据错误…...
Chromium 134 编译指南 macOS篇:编译优化技巧(六)
1. 引言 在Chromium 134的开发过程中,优化编译速度是提升开发效率的关键因素。本文将重点介绍如何使用ccache工具来加速C/C代码的编译过程,特别是在频繁切换分支和修改代码时。通过合理配置和使用这些工具,您将能够显著减少编译时间…...
FPGA——基于DE2_115实现DDS信号发生器
FPGA——基于DE2_115实现DDS信号发生器 文章目录 FPGA——基于DE2_115实现DDS信号发生器一、实验要求二、实现过程(1)新建工程 二、波形存储器ROM(1)方波模块(2)正弦波形存储器(3)锁…...
PHP中的ReflectionClass讲解【详细版】
快餐: ReflectionClass精简版 在PHP中,ReflectionClass是一个功能强大的反射类,它就像是一个类的“X光透视镜”,能让我们在程序运行时深入了解类的内部结构和各种细节。 一、反射类的基本概念和重要性 反射是指在程序运行期间获…...
嵌入式面试题解析:常见基础知识点详解
在嵌入式领域的面试中,基础知识点的考察尤为重要。下面对一些常见面试题进行详细解析,帮助新手一步步理解。 一、原码、反码、补码及补码的好处 题目 什么叫原码、反码、补码?计算机学科引入补码有什么好处? 在计算机科学中&a…...
GPU渲染阶段介绍+Shader基础结构实现
GPU是什么 (CPU)Center Processing Unit:逻辑编程 (GPU)Graphics Processing Unit:图形处理(矩阵运算,数据公式运算,光栅化) 渲染管线 渲染管线也称为渲染流水线&#x…...
08-DevOps-向Harbor上传自定义镜像
harbor创建完成,往harbor镜像仓库中上传自定义的镜像,包括新建项目、docker配置镜像地址、镜像重命名、登录harbor、推送镜像这几个步骤,具体操作如下: harbor中新建项目 访问级别公开,代表任何人都可以拉取仓库中的镜…...
C++学习之路,从0到精通的征途:vector类的模拟实现
目录 一.vector的介绍 二.vector的接口实现 1.成员变量 2.迭代器 (1)begin (2)end 3.容量操作 (1)size,capacity (2)reserve (3)resize…...
嵌入式软件--stm32 DAY 2
大家学习嵌入式的时候,多多学习用KEIL写代码,虽然作为编译器,大家常用vscode等常用工具关联编码,但目前keil仍然是主流工具之一,学习掌握十分必要。 1.再次创建项目 1.1编译器自动生成文件 1.2初始文件 这样下次创建新…...
多模态大语言模型arxiv论文略读(二十九)
Temporal Insight Enhancement: Mitigating Temporal Hallucination in Multimodal Large Language Models ➡️ 论文标题:Temporal Insight Enhancement: Mitigating Temporal Hallucination in Multimodal Large Language Models ➡️ 论文作者:Li Su…...
【人工智能学习-01-01】20250419《数字图像处理》复习材料的word合并PDF,添加页码
前情提要 20250419今天是上师大继续教育人工智能专升本第一学期的第一次线下课。 三位老师把视频课的内容提炼重点再面授。(我先看了一遍视频,但是算法和图像都看不懂,后来就直接挂分刷满时间,不看了) 今天是面对面授…...
B端APP设计:打破传统限制,为企业开启便捷新通道
B端APP设计:打破传统限制,为企业开启便捷新通道 在数字化转型浪潮中,企业级移动应用正突破传统管理系统的功能边界,演变为连接产业链各环节的核心枢纽。本文从技术架构革新、交互模式进化、安全防护升级三个维度,系统…...
【多线程5】面试常考锁知识点
文章目录 悲观/乐观锁挂起等待锁/自旋锁偏向锁轻量级/重量级锁锁升级CASCAS引发的ABA问题解决方案 原子类 公平/不公平锁可重入锁ReentrantLock读写锁 Callable接口 这里的“悲观”“乐观”“挂起等待”“自旋”“轻量级”“重量级”“公平”“非公平”“可重入”仅代表某个锁的…...
Linux第一个系统程序——进度条
1.回车与换行 回车(CR, \r): 作用:将光标移动到当前行的行首(最左侧),但不换到下一行。 历史来源:源自打字机的“回车”操作——打字机的滑架(Carriage)需…...
C 语 言 --- 指 针 3
C 语 言 --- 指 针 3 函 数 指 针函 数 指 针 数 组代 码 解 释回 调 函 数 - - - qsort模 拟 实 现 qsort 函 数 总结 💻作 者 简 介:曾 与 你 一 样 迷 茫,现 以 经 验 助 你 入 门 C 语 言 💡个 人 主 页:笑口常开x…...
蓝桥杯之递归
1.数字三角形 题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和(路径上的每一步只可沿左斜线向下或右斜线向下走)。 输…...
学习笔记十八——Rust 封装
🧱 Rust 封装终极指南:结构体、模块、Trait、目录结构与模块引用 🧭 目录导航 什么是封装?Rust 的封装理念Rust 的封装工具总览模块(mod)和访问控制(pub)详解结构体和枚举ÿ…...
【面试向】点积与注意力机制,逐步编码理解自注意力机制
点积(dot product)两个向量点积的数学公式点积(dot product)与 Attention 注意力机制(Attention)注意力机制的核心思想注意力机制中的缩放点积自注意力机制中,谁注意谁? 逐步编码理解…...
基础数学知识-线性代数
1. 矩阵相乘 c i j = a i k ∗ b k j c_{ij} = a_{ik} * b_{kj} cij=aik∗bkj 1. 范数 1. 向量的范数 任意一组向量设为 x ⃗ = ( x 1 , x 2 , . . . , x N ) \vec{x}=(x_1,x_2,...,x_N) x =(x1,x2,...,xN) 如下: 向量的1范数: 向量的各个元素的绝对值之和∥ …...
【KWDB 创作者计划】_上位机知识篇---Docker容器
文章目录 前言1. Docker 容器是什么?隔离性轻量级可移植性可复用性 2. Docker 核心概念镜像容器仓库Dockerfile 3. Docker 基本使用(1) 安装 Docker(2) 容器生命周期管理(3) 镜像管理(4) 进入容器内部(5) 数据持久化(挂载卷)(6) 网络管理 4. …...
指针函数和函数指针
指针函数本质是一个函数,只是函数的返回值是指针类型 函数指针本质是一个指针,只是这个指针指向的是一个函数 指针函数 函数有很多类型的返回值,例如 short funcA(参数列表) // 表示该函数返回值是一个short类型 void funcA(参数列表) // 表…...
案例驱动的 IT 团队管理:创新与突破之路:第六章 组织进化:从案例沉淀到管理体系-6.1 案例库建设方法论-6.1.2案例分级与标签体系
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 案例分级与标签体系构建方法论:IT团队知识管理的结构化实践1. 案例库建设的战略价值与核心挑战1.1 案例管理的战略定位1.2 分级标签体系的核心价值 2. 案例分级体…...
sqlilabs-Less之HTTP头部参数的注入——基础篇
Less-18 user-agent报错注入 这一关的代码漏洞点出现在了insert语句,因为这里没有对user-agent和ip_address进行过滤,,并且输出了mysql的错误信息 补充知识点 PHP里用来获取客户端IP的变量 $_SERVER[HTTP_CLIENT_IP] #这个很少使用…...
java多线程相关内容
java线程创建的方式 一共有四种方式 继承 Thread 类:本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例 启动线程的唯一方 法就是通过 **Thread 类的 start()**实例方法。start()方法是一个 native 方法,它将启动一个新线 程&…...
Windows Server .NET Core 应用程序部署到 IIS 解决首次访问加载慢的问题
第一篇: Windows .NET Core 应用程序部署到 IIS 解决首次访问加载慢的问题 第二篇:Windows Server .NET Core 应用程序部署到 IIS 解决首次访问加载慢的问题 第三篇:Windows .NET Core 应用程序部署到 IIS 解决首次访问加载慢的问题 设置…...
ubuntu24.04上使用qemu+buildroot+uboot+linux+tftp+nfs模拟搭建vexpress-ca9嵌入式linux开发环境
1 准备工作 1.1 安装依赖工具 sudo apt-get update && sudo apt-get install build-essential git bc flex libncurses5-dev libssl-dev device-tree-compiler1.2 安装arm交叉编译工具链 sudo apt install gcc-arm-linux-gnueabihf安装之后,在终端输入ar…...
Cocos Creater打包安卓App添加隐私弹窗详细步骤+常见问题处理
最终演示效果,包含所有代码内容 + 常见错误问题处理 点击服务协议、隐私政策,跳转到相关网页, 点击同意进入游戏,不同意关闭应用 一,添加Activity,命名为MyLaunchActivity 二,编写MyLaunchActivity.java的内容 package com.cocos.game.launch;import android.os.Bund…...
UI文件上传
1、文件上传:文件上传是自动化中比较麻烦棘手的部分。 有些场景我们需要上传本地文件到项目里。这种比较麻烦,因为需要点开文件上传的窗口后,打开的是windows的文件选择窗口, 而selenium是无法操作这个窗口的。 selenium只能操作…...
2.凸包优化求解
1.减而治之(Decrease and Conquer) 插入排序 典型的减而治之算法就是插入排序方法 插入排序法: 在未排序中选择一个元素,插入到已经排序号的序列中 将凸包也采用减而治之的方法 2.In-Convex-Polygon Test 怎么判断引入的极点存在于多边形里面还是外面࿱…...
从0开发一个unibest+vue3项目,使用vscode编辑器开发,总结vue2升vue3项目开始,小白前期遇到的问题
开头运行可看官网 链接: unibest官网 一:vscode中vue3代码显示报错标红波浪线 去查看扩展商店发现一些插件都弃用了,例如h5的插件以及vue老插件 解决办法:下载Vue - Official插件(注意:横杠两边是要加空格的ÿ…...