
入门实战:用提示词生成单元测试代码的 5 个案例
在软件开发中,单元测试是保证代码质量的重要环节。但编写单元测试往往耗时费力,尤其是对新手来说,很难快速掌握要领。而利用提示词让 AI 生成单元测试代码,能大大提高效率。下面就通过 5 个实际案例,展示如何用提示词生成单元测试代码。
一、案例一:整数加法函数的单元测试
1.1 被测函数说明
有一个简单的整数加法函数,功能是接收两个整数参数,返回它们的和。函数代码如下:
def add(a, b):
return a + b
1.2 提示词设计
要生成这个函数的单元测试,提示词需要明确函数信息和测试要求。可以这样设计:“请为以下 Python 函数生成单元测试,函数功能是计算两个整数的和,函数定义为 def add (a, b): return a + b。测试要包含正常输入、边界值(如 0、负数)的情况,使用 unittest 框架。”
1.3 生成的测试代码
AI 根据提示词生成的测试代码如下:
import unittest
from your_module import add
class TestAddFunction(unittest.TestCase):
def test_normal_numbers(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(10, 20), 30)
def test_with_zero(self):
self.assertEqual(add(0, 5), 5)
self.assertEqual(add(10, 0), 10)
self.assertEqual(add(0, 0), 0)
def test_with_negative_numbers(self):
self.assertEqual(add(-2, 3), 1)
self.assertEqual(add(5, -5), 0)
self.assertEqual(add(-3, -4), -7)
if __name__ == '__main__':
unittest.main()
1.4 代码分析
这段测试代码覆盖了多种情况。正常输入的测试用例验证了普通整数相加的结果;包含 0 的测试用例检查了 0 与其他数相加的正确性;负数相关的测试用例则确保了函数对负数的处理没有问题。整体符合单元测试的基本要求,能有效验证 add 函数的功能。
二、案例二:字符串反转函数的单元测试
2.1 被测函数说明
一个字符串反转函数,接收一个字符串参数,返回反转后的字符串。函数代码如下:
public class StringUtil {
public static String reverse(String str) {
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
int n = chars.length;
for (int i = 0; i < n / 2; i++) {
char temp = chars[i];
chars[i] = chars[n - 1 - i];
chars[n - 1 - i] = temp;
}
return new String(chars);
}
}
2.2 提示词设计
针对这个 Java 函数,提示词可以这样写:“请为 Java 类 StringUtil 中的 reverse 方法生成单元测试,该方法用于反转字符串,若输入为 null 则返回 null。测试需包含正常字符串、空字符串、特殊字符字符串、null 值的情况,使用 JUnit 4 框架。”
2.3 生成的测试代码
生成的测试代码如下:
import static org.junit.Assert.*;
import org.junit.Test;
import com.yourpackage.StringUtil;
public class StringUtilTest {
@Test
public void testReverseNormalString() {
assertEquals("cba", StringUtil.reverse("abc"));
assertEquals("12345", StringUtil.reverse("54321"));
}
@Test
public void testReverseEmptyString() {
assertEquals("", StringUtil.reverse(""));
}
@Test
public void testReverseSpecialCharacters() {
assertEquals("!@#$%", StringUtil.reverse("%$#@!"));
assertEquals("a!b@c", StringUtil.reverse("c@b!a"));
}
@Test
public void testReverseNull() {
assertNull(StringUtil.reverse(null));
}
}
2.4 代码分析
测试代码考虑了不同类型的字符串输入。正常字符串测试验证了普通字符反转的正确性;空字符串测试确保函数对空输入的处理符合预期;特殊字符测试检查了函数对特殊符号的处理能力;null 值测试则验证了函数在输入为 null 时的返回结果。这些测试用例能较好地覆盖函数的各种使用场景。
三、案例三:数组排序函数的单元测试
3.1 被测函数说明
一个用于对整数数组进行升序排序的函数,使用冒泡排序算法。函数代码如下:
function bubbleSort(arr) {
if (!arr || arr.length <= 1) {
return arr;
}
let len = arr.length;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
3.2 提示词设计
提示词设计为:“请为 JavaScript 的 bubbleSort 函数生成单元测试,该函数对整数数组进行升序排序,若数组为 null 或长度小于等于 1 则直接返回。测试需包含无序数组、已排序数组、倒序数组、包含重复元素的数组、空数组、null 的情况,使用 Jest 测试框架。”
3.3 生成的测试代码
生成的测试代码如下:
const bubbleSort = require('./your-file');
describe('bubbleSort function', () => {
test('sorts an unsorted array', () => {
expect(bubbleSort([3, 1, 2])).toEqual([1, 2, 3]);
expect(bubbleSort([5, 2, 9, 1])).toEqual([1, 2, 5, 9]);
});
test('handles already sorted array', () => {
expect(bubbleSort([1, 2, 3, 4])).toEqual([1, 2, 3, 4]);
});
test('handles reverse sorted array', () => {
expect(bubbleSort([4, 3, 2, 1])).toEqual([1, 2, 3, 4]);
});
test('handles array with duplicate elements', () => {
expect(bubbleSort([2, 1, 2, 3])).toEqual([1, 2, 2, 3]);
expect(bubbleSort([5, 3, 5, 1])).toEqual([1, 3, 5, 5]);
});
test('handles empty array', () => {
expect(bubbleSort([])).toEqual([]);
});
test('handles null', () => {
expect(bubbleSort(null)).toBeNull();
});
});
3.4 代码分析
该测试代码针对排序函数的特点,设计了多种测试场景。无序数组测试验证了函数的基本排序功能;已排序数组测试检查函数是否会对已排好序的数组造成干扰;倒序数组测试是排序函数的常见测试点;重复元素数组测试确保函数能正确处理重复值;空数组和 null 测试则验证了函数对边界输入的处理。这些测试用例能有效检测排序函数的正确性。
四、案例四:用户登录验证函数的单元测试
4.1 被测函数说明
一个简单的用户登录验证函数,接收用户名和密码,与预设的正确信息比对,返回登录是否成功。函数代码如下:
public class LoginService {
private string validUsername = "admin";
private string validPassword = "password123";
public bool ValidateLogin(string username, string password) {
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) {
return false;
}
return username == validUsername && password == validPassword;
}
}
4.2 提示词设计
提示词可以这样写:“请为 C# 的 LoginService 类中的 ValidateLogin 方法生成单元测试,该方法验证用户名和密码是否正确,正确用户名为 'admin',密码为 'password123',若用户名或密码为空则返回 false。测试需包含正确的用户名和密码、错误的用户名、错误的密码、空用户名、空密码的情况,使用 xUnit 测试框架。”
4.3 生成的测试代码
生成的测试代码如下:
using Xunit;
using YourNamespace;
public class LoginServiceTests {
private LoginService loginService = new LoginService();
[Fact]
public void ValidateLogin_ValidCredentials_ReturnsTrue() {
bool result = loginService.ValidateLogin("admin", "password123");
Assert.True(result);
}
[Fact]
public void ValidateLogin_InvalidUsername_ReturnsFalse() {
bool result = loginService.ValidateLogin("user", "password123");
Assert.False(result);
}
[Fact]
public void ValidateLogin_InvalidPassword_ReturnsFalse() {
bool result = loginService.ValidateLogin("admin", "pass123");
Assert.False(result);
}
[Fact]
public void ValidateLogin_EmptyUsername_ReturnsFalse() {
bool result = loginService.ValidateLogin("", "password123");
Assert.False(result);
}
[Fact]
public void ValidateLogin_EmptyPassword_ReturnsFalse() {
bool result = loginService.ValidateLogin("admin", "");
Assert.False(result);
}
}
4.4 代码分析
测试代码围绕登录验证的各种情况展开。正确凭据测试验证了函数在输入正确时能返回 true;错误用户名和错误密码测试分别检查了用户名或密码错误时的返回结果;空用户名和空密码测试则确保了函数对空输入的处理符合预期。这些测试用例能有效验证登录验证函数的逻辑是否正确。
五、案例五:计算矩形面积函数的单元测试
5.1 被测函数说明
一个计算矩形面积的函数,接收长和宽两个参数,返回面积。若长或宽小于等于 0,则返回 - 1 表示错误。函数代码如下:
package rectangle
func CalculateArea(length, width float64) float64 {
if length <= 0 || width <= 0 {
return -1
}
return length * width
}
5.2 提示词设计
提示词设计为:“请为 Go 语言 rectangle 包中的 CalculateArea 函数生成单元测试,该函数计算矩形面积,长或宽小于等于 0 时返回 - 1。测试需包含正常的长和宽、长为 0、宽为 0、长为负数、宽为负数的情况,使用 Go 内置的 testing 包。”
5.3 生成的测试代码
生成的测试代码如下:
package rectangle
import "testing"
func TestCalculateArea_NormalValues(t *testing.T) {
area := CalculateArea(5, 3)
if area != 15 {
t.Errorf("Expected 15, got %v", area)
}
area = CalculateArea(2.5, 4)
if area != 10 {
t.Errorf("Expected 10, got %v", area)
}
}
func TestCalculateArea_ZeroLength(t *testing.T) {
area := CalculateArea(0, 5)
if area != -1 {
t.Errorf("Expected -1, got %v", area)
}
}
func TestCalculateArea_ZeroWidth(t *testing.T) {
area := CalculateArea(5, 0)
if area != -1 {
t.Errorf("Expected -1, got %v", area)
}
}
func TestCalculateArea_NegativeLength(t *testing.T) {
area := CalculateArea(-3, 4)
if area != -1 {
t.Errorf("Expected -1, got %v", area)
}
}
func TestCalculateArea_NegativeWidth(t *testing.T) {
area := CalculateArea(4, -2)
if area != -1 {
t.Errorf("Expected -1, got %v", area)
}
}
5.4 代码分析
测试代码针对矩形面积计算函数的逻辑进行了全面测试。正常数值测试验证了函数在输入合法时能正确计算面积;长为 0、宽为 0、长为负数、宽为负数的测试用例,则确保了函数在输入不合法时能返回 - 1。这些测试用例覆盖了函数的主要逻辑分支,能有效检测函数的正确性。
六、设计提示词的通用技巧
6.1 明确函数信息
在提示词中,要清晰说明被测函数的基本信息,包括函数名、所属语言、参数类型、返回值类型以及函数的功能逻辑。比如 “这是一个 Python 函数,名为 calculate_average,接收一个整数列表作为参数,返回列表的平均值,若列表为空则返回 0”。明确的函数信息能让 AI 更准确地理解要测试的对象。
6.2 列出测试场景
根据函数的功能,列出需要覆盖的测试场景,如正常输入、边界值、异常情况等。例如 “测试场景包括:输入包含多个元素的列表、输入只包含一个元素的列表、输入空列表、输入包含负数的列表”。列出测试场景能引导 AI 生成全面的测试用例。
6.3 指定测试框架
不同的编程语言有不同的测试框架,在提示词中指定具体的测试框架,能让生成的测试代码可以直接使用。比如 “使用 JUnit 5 框架”“使用 pytest 框架” 等。
6.4 说明预期结果
对于一些关键的测试用例,可以说明预期的测试结果,帮助 AI 更准确地生成断言。例如 “当输入为空列表时,函数返回 0,测试用例应断言这一点”。
七、生成代码后的检查与调整
7.1 检查测试覆盖率
生成测试代码后,要检查测试用例是否覆盖了函数的主要逻辑分支和可能的输入情况。如果发现有遗漏的场景,如某个边界值没有被测试到,需要补充相应的测试用例。
7.2 验证代码语法
由于 AI 生成的代码可能存在语法错误,尤其是在涉及具体的包名、类名时。要仔细检查代码的语法,确保没有拼写错误、缺少括号等问题,必要时进行修改。
7.3 调整测试逻辑
如果生成的测试代码中,测试逻辑与被测函数的实际逻辑不符,比如断言的预期结果错误,需要根据函数的实际功能调整测试逻辑,确保测试的正确性。
7.4 考虑代码风格
不同的团队有不同的代码风格要求,生成的测试代码可能不符合团队的规范。可以根据团队的代码风格指南,调整代码的命名、缩进等,使代码更易读、易维护。
八、常见问题及解决方法
8.1 生成的测试用例不全面
如果 AI 生成的测试用例覆盖的场景较少,可能是提示词中没有详细列出测试场景。解决方法是在提示词中更详细地描述需要覆盖的测试情况,明确列出各种可能的输入和场景。
8.2 测试代码与实际环境不兼容
生成的测试代码可能因为包名、类名等与实际项目不符而无法运行。这时候需要根据项目的实际情况,修改代码中的包名、导入路径等,使其与项目环境兼容。
8.3 对复杂函数生成效果差
对于逻辑复杂的函数,AI 可能难以生成全面准确的测试代码。可以将复杂函数拆分成多个简单的部分,分别生成测试代码,或者在提示词中更详细地描述函数的逻辑和各个分支的处理方式。
8.4 生成的断言不正确
如果生成的测试代码中断言的预期结果与实际不符,可能是提示词中对函数功能的描述不够准确。需要重新检查提示词中对函数功能的说明,确保准确无误,必要时在提示词中明确关键场景的预期结果。
九、不同编程语言的提示词差异
9.1 静态类型语言
对于 Java、C#、Go 等静态类型语言,提示词中需要明确函数的参数类型和返回值类型,以及可能的异常情况。同时,要指定对应的测试框架,如 JUnit、xUnit、Go testing 等,因为这些语言的测试框架对代码结构有较严格的要求。
9.2 动态类型语言
对于 Python、JavaScript 等动态类型语言,提示词中可以适当简化类型描述,但要清晰说明函数的功能和参数的含义。这些语言的测试框架相对灵活,如 pytest、Jest 等,在提示词中可以适当说明测试用例的组织方式,如使用函数还是类来组织测试。
十、结合实际项目的使用建议
10.1 融入开发流程
在实际项目开发中,可以将用提示词生成单元测试代码的环节融入到开发流程中。比如,在完成一个函数的编写后,立即根据函数信息设计提示词,生成初步的测试代码,然后结合项目实际情况进行调整和完善。这样能及时对新编写的代码进行测试,尽早发现问题。
10.2 团队共享提示词模板
团队成员可以共同制定一些提示词模板,针对不同类型的函数(如工具类函数、业务逻辑函数等)设计标准化的提示词结构。这样不仅能提高提示词设计的效率,还能保证生成的测试代码风格统一,便于团队协作和维护。例如,针对业务逻辑函数的提示词模板可以包含函数的业务背景、输入输出规则、关键业务场景等内容。
10.3 定期复盘与优化
定期对使用提示词生成单元测试代码的效果进行复盘,分析生成的测试代码在实际运行中发现的问题,总结提示词设计的经验教训。根据复盘结果优化提示词的设计方法和模板,不断提高生成代码的质量和效率。比如,发现某类函数的测试用例经常遗漏某些场景,就针对性地在提示词中强化对这些场景的描述。
十一、提示词生成单元测试的局限性
11.1 依赖函数描述的准确性
AI 生成测试代码的质量很大程度上依赖于对被测函数描述的准确性。如果提示词中对函数功能、参数含义、返回值规则等描述不清楚或存在错误,生成的测试代码就可能不符合预期,甚至出现错误。
11.2 难以处理复杂业务逻辑
对于包含复杂业务逻辑、涉及多个模块交互的函数,提示词生成的测试代码往往难以覆盖所有的业务场景和逻辑分支。因为这类函数的测试不仅需要考虑自身的逻辑,还需要考虑与其他模块的依赖关系,AI 很难仅凭提示词完全理解这些复杂的关联。
11.3 缺乏创造性测试思路
AI 生成测试用例主要是基于提示词中描述的场景和常见的测试模式,缺乏创造性的测试思路。一些边缘的、非常规的测试场景可能无法被覆盖,而这些场景在实际中可能会出现问题。
十二、拓展应用:生成测试数据
除了生成单元测试代码,提示词还可以用于生成测试数据。
12.1 基本数据类型测试数据
对于需要基本数据类型(如整数、字符串、布尔值等)作为输入的函数,可以设计提示词生成相应的测试数据。例如,“生成 10 个用于测试整数除法函数的测试数据,包含正数、负数、零,且除数不为零”,AI 会生成如(6, 2)、(-8, 4)、(5, -1)、(0, 3)等测试数据。
12.2 复杂数据结构测试数据
对于需要数组、对象、列表等复杂数据结构作为输入的函数,也可以通过提示词生成测试数据。比如,“生成 3 个用于测试学生信息排序函数的测试数据,每个数据是包含 3 个学生信息的列表,学生信息包括姓名(字符串)、年龄(整数)、成绩(浮点数)”,AI 可能会生成如下数据:
[
[{"name": "张三", "age": 18, "score": 90.5}, {"name": "李四", "age": 19, "score": 85.0}, {"name": "王五", "age": 17, "score": 95.5}],
[{"name": "赵六", "age": 20, "score": 78.0}, {"name": "孙七", "age": 18, "score": 88.5}, {"name": "周八", "age": 19, "score": 92.0}],
[{"name": "吴九", "age": 17, "score": 60.0}, {"name": "郑十", "age": 20, "score": 80.5}, {"name": "钱十一", "age": 18, "score": 75.0}]
]
12.3 结合业务场景的测试数据
在实际业务中,测试数据需要符合业务规则。可以设计包含业务场景描述的提示词生成测试数据。例如,“生成 5 个用于测试电商订单金额计算函数的测试数据,订单包含商品列表(每个商品有名称、单价、数量)和是否为会员(布尔值),会员可享受 9 折优惠,商品单价大于 100 元的商品另享满减 5 元”,AI 会根据这些业务规则生成符合要求的订单数据。
十三、新手常见错误及避免方法
13.1 提示词过于简略
新手在设计提示词时,常犯的错误是过于简略,只简单说明函数名和要生成测试代码,没有提供足够的函数信息和测试要求。比如,只写 “为 add 函数生成单元测试”。这样生成的测试代码往往很简单,覆盖场景少。避免方法是按照前面提到的通用技巧,详细描述函数信息、测试场景、测试框架等。
13.2 忽略函数的边界情况
很多新手在设计提示词时,只关注函数的正常输入情况,忽略了边界值、异常输入等场景。比如,测试除法函数时,只考虑正数相除,不考虑除数为零的情况。避免方法是在提示词中明确列出需要覆盖的边界情况和异常场景,如 “测试场景包括除数为零的情况”。
13.3 对生成的代码不做检查
有些新手认为 AI 生成的代码一定是正确的,直接使用而不做检查,导致测试代码中存在语法错误或逻辑错误。避免方法是养成生成代码后检查的习惯,按照第七部分的内容进行全面检查和调整。
13.4 过度依赖 AI 生成
过度依赖 AI 生成测试代码,自己不思考测试逻辑和场景,会导致测试能力无法提升。避免方法是将 AI 生成的代码作为参考,结合自己的理解进行修改和完善,在这个过程中学习单元测试的设计思路和方法。
十四、工具推荐:辅助生成提示词
14.1 Prompt Perfect
这是一款浏览器插件,能帮助优化提示词。将初步设计的提示词输入后,它会进行分析,补充遗漏的信息,使提示词更清晰、全面。比如,输入简略的提示词 “为 add 函数生成单元测试”,它会自动补充函数可能的参数类型、功能等信息,生成更完善的提示词。
14.2 AIPRM
AIPRM 提供了大量提示词模板,包括生成单元测试代码的模板。新手可以直接选用合适的模板,根据自己的需求进行修改,快速生成符合要求的提示词。例如,里面有 “生成 Python 函数单元测试的提示词模板”,包含了函数信息、测试场景、测试框架等模块,只需填写具体内容即可。
14.3 在线提示词生成器
一些在线平台提供了提示词生成器,通过选择相关选项(如编程语言、函数类型、测试框架等),自动生成提示词。新手可以通过这些工具快速生成规范的提示词,同时也能学习提示词的结构和内容。
810

被折叠的 条评论
为什么被折叠?



