导航

经典Prompt欣赏 - 给代码生成单元测试

Posted on 2024-03-30 14:14  蝈蝈俊  阅读(446)  评论(0编辑  收藏  举报

在Twitter上看到一段给代码生成单元测试的Prompt:
https://twitter.com/mattshumer_/status/1773385952699789808

虽然它是针对 Claude 3的,但理论上来说可以适用于绝大部分模型。

Prompt 如下:

<prompt_explanation>
You are an expert software tester tasked with thoroughly testing a given piece of code. 
Your goal is to generate a comprehensive set of test cases that will exercise the code and uncover any potential bugs or issues.

First, carefully analyze the provided code. Understand its purpose, inputs, outputs, and any key logic or calculations it performs. Spend significant time considering all the different scenarios and edge cases that need to be tested.

Next, brainstorm a list of test cases you think will be necessary to fully validate the correctness of the code. For each test case, specify the following in a table:
- Objective: The goal of the test case 
- Inputs: The specific inputs that should be provided 
- Expected Output: The expected result the code should produce for the given inputs
- Test Type: The category of the test (e.g. positive test, negative test, edge case, etc.)

After defining all the test cases in tabular format, write out the actual test code for each case. Ensure the test code follows these steps:
1. Arrange: Set up any necessary preconditions and inputs 
2. Act: Execute the code being tested
3. Assert: Verify the actual output matches the expected output

For each test, provide clear comments explaining what is being tested and why it's important. 

Once all the individual test cases have been written, review them to ensure they cover the full range of scenarios. Consider if any additional tests are needed for completeness.

Finally, provide a summary of the test coverage and any insights gained from this test planning exercise. 
</prompt_explanation>

<response_format>
<code_analysis_section>
<header>Code Analysis:</header>
<analysis>$code_analysis</analysis>
</code_analysis_section>

<test_cases_section>
<header>Test Cases:</header>
<table>
<header_row>
<column1>Objective</column1>
<column2>Inputs</column2>
<column3>Expected Output</column3>
<column4>Test Type</column4>
</header_row>
$test_case_table
</table>
</test_cases_section>

<test_code_section>
<header>Test Code:</header>
$test_code
</test_code_section>

<test_review_section>
<header>Test Review:</header>
<review>$test_review</review>
</test_review_section>

<coverage_summary_section>
<header>Test Coverage Summary:</header>
<summary>$coverage_summary</summary>
<insights>$insights</insights>
</coverage_summary_section>
</response_format>

Here is the code that you must generate test cases for:
<code>
PASTE_YOUR_CODE_HERE
</code>

便于理解,下面是翻译后的Prompt。

<prompt_explanation>
你作为一名专家级软件测试员,负责对指定的代码片段进行彻底测试。
你的目标是创建一套全面的测试用例,通过这些用例执行代码,发现任何可能的漏洞或问题。

首先,细致地分析提供的代码。弄清楚它的作用、输入、输出及任何核心逻辑或运算。深入思考所有可能需要测试的不同场景和边缘案例。

然后,头脑风暴,列出一系列你认为必须的测试用例,以彻底验证代码的准确性。对于每一个测试用例,在表格中明确以下信息:

- 目的:测试用例的目标
- 输入:具体需要提供的输入
- 预期输出:对于给定的输入,代码应产出的结果
- 测试类型:测试的分类(比如,正向测试、反向测试、边界案例等)

在以表格形式详细列出所有测试用例之后,针对每个案例编写具体的测试代码。确保测试代码遵循以下流程:

1. 准备:设置必要的前置条件和输入
2. 执行:运行待测代码
3. 验证:确保实际输出与期望输出一致

对于每项测试,都应清晰注释说明测试的内容及其重要性。

完成所有单独测试用例的编写后,进行复查,确保它们全面覆盖了所有场景。思考是否还需要添加额外的测试以确保全面性。

最后,总结测试覆盖范围

及通过这次测试计划活动获得的洞见。
</prompt_explanation>

<response_format>
<code_analysis_section>

<header>代码分析:</header>
<analysis>$code_analysis</analysis>
</code_analysis_section>

<test_cases_section>

<header>测试案例:</header>
<table>
<header_row>
<column1>目的</column1>
<column2>输入</column2>
<column3>预期输出</column3>
<column4>测试类型</column4>
</header_row>
$test_case_table
</table>
</test_cases_section>

<test_code_section>

<header>测试代码:</header>
$test_code
</test_code_section>

<test_review_section>

<header>测试回顾:</header>
<review>$test_review</review>
</test_review_section>

<coverage_summary_section>

<header>测试覆盖概要:</header>
<summary>$coverage_summary</summary>
<insights>$insights</insights>
</coverage_summary_section>
</response_format>

以下是你需要为其生成测试用例的代码:
<code>
将你的代码粘贴于此
</code>

可借鉴的

推荐这个Prompt,是因为它有很多可借鉴的点:

借助XML标签

借助 XML 标签,让文本提示词有了清晰的结构,能让大语言模型更好的理解你的指令,这比传统的分割线标识内容区域更进了一步。

下图为本Prompt的结构:

XML的特殊字符

在XML格式的内容中,下面这些字符具有特殊意义,因此需要对它们进行转义处理:

  • 小于号 (<): 在XML中用来标示标签的开始。如果要在文本中使用,应该使用它的转义字符 &lt;
  • 大于号 (>): 虽然大于号通常在文本中使用时不会引起问题,但在某些情况下(如在包含脚本的CDATA部分)仍建议转义为 &gt;,以提高兼容性和可读性。
  • 和号 (&): 用于引导实体引用(如 &lt; 代表小于号)。如果你需要在文本中显示&,应该使用它的转义字符 &amp;
  • 引号 (") 和 单引号 ('): 分别用于XML属性值的定界。在属性值中使用引号时,应分别转义为 &quot;&apos;
  • 百分号 (%): 在XML实体中用于引用其他实体,如果直接使用可能会被错误地解释为实体引用的开始。虽然不是严格必须,但在某些上下文中可能需要转义,可以转译成十进制表示&#37;或十六进制表示:&#x25;

不想大量转译,还可以用 <![CDATA[]]> 标记用来定义字符数据区块(CDATA区)。在CDATA区内部,所有的文本都会被解析器视为原始文本,而不会进行任何解析操作。CDATA区的限制是 CDATA区的结束标记 ]]> 不能出现在CDATA内容中。

清晰的步骤

借助 CoT(链式思考 Chain of Though)的方式,让模型能按照一定的步骤来思考,每一步的结果又可以作为下一步的输入,得到高质量的输出结果。

这个Prompt的CoT如下:

  1. 分析代码,弄清楚代码的作用、输入、输出及核心逻辑。这样可以保证不遗漏代码中的关键信息。
  2. 列出必要的测试用例,包括目的、输入、预期输出和测试类型。有了前面代码的分析,在写测试用例时就不容易漏掉关键的测试用例。
  3. 为每个测试用例编写具体的测试代码,确保测试代码遵循准备、执行、验证的流程。有了前面的测试用例,就可以挨个写测试代码了,不会遗漏关键的测试代码。
  4. 对生成的结果进行复查,确保全面覆盖了所有场景。
  5. 最后,总结测试覆盖范围及通过这次测试计划活动获得的洞见。这一步其实可以省略,因为对模型来说已经意义不大,但是对于作者来说,可以帮助你更好的理解它为什么要生成这些测试用例。或许从中学到点东西。

一开始就要说明指令的目标是什么

这样可以让模型更好的理解你的指令,生成更符合你预期的结果。

这个Prompt的指令目的如下:

你的目标是创建一套全面的测试用例,通过这些用例执行代码,发现任何可能的漏洞或问题。

角色设定

一开始的角色设定,属于锦上添花,可以让生成结果时,更多的从语料库中挑选角色相关的内容。

这个Prompt的角色设定:

你作为一名专家级软件测试员,负责对指定的代码片段进行彻底测试。

总结

通过这几点提示词的改进,引导模型生成了高质量的输出:

  1. 你的指令要清晰,可以借助 XML 标签来组织你的指令。
  2. 要充分利用 CoT,让模型按照一定的步骤来思考,每一步的结果又可以作为下一步的输入,得到高质量的输出结果。
  3. 明确的输出格式,确保输出的内容按照你列的步骤执行,并且每一步都包含所有必须的信息。