大家好,我是Edison。

本篇我们基于上一篇的基础,来写一个单元测试助手的prompt,让它帮我们写一些我们.NET开发者不太愿意编写的单元测试代码,进而提高我们的代码质量,同时还降低我们的开发工作量。

单元测试助手

这里我们基于上一篇中提到的万能语言辅助专家的提示词,稍作修改,形成我们的单元测试助手的提示词,如下所示,经过一些测试在GPT4-o模型下效果真的不错,建议收藏!

初始回复:“
**Hi I'm Unit Test Master,Created by Edison Zhou,V1.0,20230701**
### ⚙️ Preferences:
- lang: <> else C#
- ⏲️ test: <> else xUnit
- mock: <> else Moq
### Menu:
请使用表格输出支持的`instructions`和对应名称,不需要解释具体含义,也不需要显示这句话:
---
请指出你的开发语言,E.g.:/lang C#。
回复1保持默认。
” `preferences`
/lang:<开发语言偏好,默认为C#>
/test:<测试框架偏好,默认为xUnit>
/mock:<模拟框架偏好,默认为Moq> `instructions`
/models:被测试代码涉及到的模型定义
用户输入一些被测试代码涉及到的Models如Entity,DTO, VO等,请按以下模版输出Models相关信息:
## Models:
用表格输出:**Model Name**
/constants:被测试代码涉及到的常量或枚举定义
用户输入一些被测试代码涉及到的Constants如Enum,Constant等,请按以下模版输出Constants相关信息:
## Constants:
用表格输出:**Constant Name**
/refer: 被测试代码依赖的的对象接口定义
用户输入一些被测试代码涉及到的对象接口如Repository,Gateway等,请按以下模版输出References相关信息:
## Refers:
用表格输出:**Reference Name**
/method:被测试方法的实际代码
结合之前的models,constants,refers定义,直接生成被测试方法的单元测试,无需再用表格输出相关信息。如果还有其他要求,用户会补充告诉你。
/help:输出支持的指令指引 `rules`
- 请使用用户设置的偏好的开发语言、测试框架和模拟框架实现
- 每个单元测试方法的命名请遵循格式:"被测试方法名_测试场景_预期结果"
- 假如被测试方法中有try-catch,请考虑针对catch部分也编写单元测试用例
- 请一步一步思考,不需要解释代码,如果有错误,用户会纠正你

对话示例

假设我们有一个基于.NET开发的API项目,想要对其中某个Service的某个方法写写单元测试,我们只需要按照以下步骤即可生成可能会“一把过”的单元测试代码。

在我们的实践中,最好通过VS Code将上述的人设prompt编辑好,同时把下面需要喂给GPT的代码片段也准备好。

第一轮:偏好选择

直接回复1,即保持C#+xUnit+Moq的框架组合,默认偏好设置

第二轮:给GPT喂Models相关class的定义

例如下所示,如果model有继承一些接口或基类,最好也一起告诉GPT。

/models
public class AppTokenVo: VoBase, IVo
{
public string TokenName { get; set; }
public AppNamesapce Namespace { get; set; }
public AppTokenType Type { get; set; }
public string Remark { get; set; }
public DateTime ExpireTime { get; set; }
}
public class VoBase : IIdentity<Guid>
{
public virtual Guid Id { get; set; }
}
public class AppTokenEntity : EntityBase, IEntity
{
......
}
......

第三轮:给GPT喂Constants相关class/enum的定义

例如下所示,如果constant有继承一些接口或基类,最好也一起告诉GPT。

/constants
public enum AppStatusCode
{
......
//// +++++++++++++++++++++++++++++++++++++
//// Common error codes [-1..-99]
//// +++++++++++++++++++++++++++++++++++++
UnexpectedException = -1,
OperationFinishedWithErrors = -2,
ValidationFailed = -3,
CouldNotSaveEntityInDb = -4,
EntityNotFoundInDb = -5,
EntityAlreadyExistInDb = -6
}
......

第四轮:给GPT喂被测试方法依赖的一些对象的定义,如Repository或Gateway等

例如下所示,如果被依赖的对象有继承一些接口或基类,最好也一起告诉GPT。

/refers
public interface IOperationResult<out T> where T : class
{
int StatusCode { get; } string ErrorMessage { get; } T Content { get; } bool HasContent { get; } bool IsSuccess { get; }
}
public interface IAppTokenRepository : IEfCoreRepositoryBase<AppTokenEntity>
{
}
public interface IEfCoreRepositoryBase<TEntity> where TEntity : EntityBase, IEntity
{
Task<IEnumerable<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> predicate, bool asNoTracking = true); Task<TEntity> GetAsync(Guid id, bool asNoTracking = false); Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool asNoTracking = false); Task<PagedEntityResult<TEntity>> GetPagedDataAsync(Expression<Func<TEntity, bool>> predicate, int limit, int skip); Task<PagedEntityResult<TEntity>> GetPagedDataAsync(Expression<Func<TEntity, bool>> predicate, string orderField, bool orderByAsc, int limit, int skip); TEntity Add(TEntity entity); TEntity Update(TEntity entity); TEntity Delete(TEntity entity);
}

第四轮:告诉GPT被测试的方法代码

例如下所示,最好将该service的定义和构造函数也一起告诉GPT,可以将该service的其他方法移除掉再告诉GPT,让其保持专注。

当然,这也是我们为什么需要通过编辑器将其编辑好,再统一发给GPT的原因。

/method
public class AppTokenService : AppServiceBase<AppTokenService>, IAppTokenService
{
public AppTokenService(
IAppUnitOfWork unitOfWork,
IMapper mapper,
ILogger<AppTokenService> logger)
: base(unitOfWork, mapper, logger)
{
} public async Task<IOperationResult<IEnumerable<AppTokenVo>>> GetAllAppTokensAsync()
{
Logger.LogInformation(LoggingConstants.FunctionCalled,
nameof(AppTokenService), nameof(GetAllAppTokensAsync));
try
{
......
return OperationResult<IEnumerable<AppTokenVo>>.Success(appTokens);
}
catch (Exception ex)
{
Logger.LogError(ex, LoggingConstants.Exception,
nameof(AppTokenService), nameof(GetAllAppTokensAsync));
return OperationResult<IEnumerable<AppTokenVo>>.Error((int)AppStatusCode.UnexpectedException);
}
finally
{
Logger.LogInformation(LoggingConstants.FunctionFinished,
nameof(AppTokenService), nameof(GetAllAppTokensAsync));
}
}
}

随后,GPT就会输出一些高质量的单元测试代码,你可以将其复制出来做一些验证:

(1)首先看看有没有编译错误,如果有,那一定是GPT虚构了某些依赖对象的接口定义,换言之,你忘记告诉GPT准确的定义了,因此你需要补充告诉GPT。

(2)其次如果没有编译错误了,那么恭喜你,你基本可以得到一个全部Pass的结果。但是,请再次review一下它的Assert有没有满足你的需求,如果没有,请一定反馈给GPT,按照你的需求做一些完善。

(3)最后建议跑一下代码覆盖率,看看还有没有没有覆盖的分支语句和代码行,然后反馈给GPT,直到满足你的需求再结束,比如Line Coverage和Branch Coverage都达到了80%及以上。

最后,你可能会发现你这么准备下来,可能自己手写单元测试也差不多写完了,但是这毕竟是你第一次调教GPT帮你写单元测试,当你熟悉这个套路之后,有了自己的固定模板,以后的单元测试就会越来越快,而且你几乎不需要写一行代码了,是不是很酷?

小结

本篇,我们了解了如何基于ChatGPT中的参数化表达沟通,实现一个可以帮我们开发者编写单元测试代码的单元测试助手。当然,这个Prompt我们的参数化设置,我们还可以将其用于C#之外的其他编程语言和测试框架,只要你愿意,你可以根据本文中的模板去修改和完善。

本文工具

本文示例大模型版本:gpt4-o

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

ChatGPT学习之旅 (8) 单元测试助手的更多相关文章

  1. Spring学习之旅(十)--MockMvc

    在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就 ...

  2. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  3. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  4. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  5. WCF学习之旅—第三个示例之三(二十九)

    上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...

  6. WCF学习之旅—WCF服务部署到IIS7.5(九)

    上接   WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...

  7. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  8. WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...

  9. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  10. WCF学习之旅—WCF服务的批量寄宿(十三)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...

随机推荐

  1. linux基础命令及bash shell特性

    linux基础命令及bash shell特性 目录 linux基础命令及bash shell特性 1.linux基础命令 1.1 查看内核版本和linux发行版本 1.2 查看服务器硬件信息 1.3 ...

  2. 4G EPS 中的各种唯一标识

    目录 文章目录 目录 电信运营商的唯一标识:PLMN.MCC 与 MNC 移动用户的唯一标识:IMSI.MSIN 与 MSISDN/MDN 移动用户的唯一临时标识:TMSI.GUTI 与 GUMMEI ...

  3. .NET ASPIRE 预览版 7 发布

    .NET Aspire 预览版 7 并不是原计划的一部分,此预览版有很多重大 API 更改,部分原因是一旦产品发布,我们将致力于稳定的 API 表面.可以说,Aspire团队希望确保在最终发布之前完成 ...

  4. AIRIOT答疑第2期|如何使用物联网平台的数据采集与控制引擎?

    任性用!   作为AIRIOT物联网低代码平台的五大核心能力引擎之一,数据采集与控制引擎具备极强的系统集成能力,提供丰富的接口,具备海量工业设备驱动库,分布式采集,稳定性高,实现快速的设备接入.报警. ...

  5. winform 绘图控件 chart 实时曲线图

    官方教程:http:////files.cnblogs.com/files/HelloQLQ/Winform图表.rar 更多参考:https://blog.csdn.net/boxuming/art ...

  6. 【知识点】深入浅出STL标准模板库

    前几天谈论了许多关于数论和数据结构的东西,这些内容可能对初学者而言比较晦涩难懂(毕竟是属于初高等算法/数据结构的范畴了).今天打算来讲一些简单的内容 - STL 标准模板库. STL 标准模板库 C+ ...

  7. Swoole 源码分析之 WebSocket 模块

    首发原文链接:Swoole 源码分析之 WebSocket 模块 大家好,我是码农先森. Swoole 源码分析之 WebSocket 模块 引言 WebSocket 是一种在单个 TCP 连接上进行 ...

  8. GIT文件上传演示

    Be Written By Handat.憨大头 注:以下内容默认你已经做好了git工具的用户账户配置. (1)创建Gitee线上代码仓库,HTTPS协议地址就是仓库地址,如例https://gite ...

  9. C#笔记 关于采集卡

    周更!节日快乐! 1. 参数 1.1 CAM file CAM file是文件扩展名为.cam的可读ASCII文件,包含了参数列表,比如:AcquisitionMode,TrigMode等.通过McS ...

  10. rhcsa练习题容易错的地方

    rhcsa练习题容易错的地方 yum仓库的配置 注意 配置yum仓库的时候,baseurl的路径不要写错 dnf clean all && dnf makecache //检查错误 s ...