大家好,我是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. ubuntu系统下安装最新版的MySQL

    目录 下载mysql源 视频地址 原文章地址 下载mysql源 打开mysql官网 mysql官网文档 进入下载地址页面 下载mysql源 apt-get install -y wget #如果没有w ...

  2. WEB服务与NGINX(14)-NGINX的压缩功能

    1. nginx压缩功能 nginx支持对指定类型的文件进行压缩后再回传给客户端,而且压缩可以设置压缩比,压缩后的文件会明显变小,有助于降低出口带宽的利用率,但是会占用一定的CPU资源. nginx实 ...

  3. cesium教程9-加载倾斜摄影并解决高度问题

    无人机航拍的倾斜摄影,用照片和视频处理生成三维模型,一般照片都带有坐标信息,所以一般都能定位的比较准确,但是经常会出现高度偏差,这个时候就需要特殊处理了. 今天航拍建模的效果如下: 这个建模没有裁剪, ...

  4. 『手撕Vue-CLI』添加帮助和版本号

    前言 经过上一篇『手撕Vue-CLI』编码规范检查之后,手撕 Vue-CLI 已经进阶到了代码规范检查这一步,已经将基本的工程搭建好了,然后代码规范约束也已经加入了,并且将 nue-cli 指令绑定到 ...

  5. 【漏洞复现】用友NC-Cloud PMCloudDriveProjectStateServlet接口存在JNDI注入漏洞

    阅读须知 花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站.服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作.利用此 ...

  6. navicat安装和破解

    navicat16.0 下载地址: https://download.navicat.com.cn/download/navicat160_premium_cs_x64.exe 破解教程&破解 ...

  7. THUWC 2024 游记

    其实这个游记也没啥好写的-- day 0 上午做动车两个小时到重庆,路上玩了 1.5h 的星露谷. 下午去巴蜀中学报道试机,系统是 Ubuntu Jammy,大大的好评,只是桌面是 Xubuntu/X ...

  8. kettle从入门到精通 第六十四课 ETL之kettle kettle中执行SQL脚本步骤,使用需当心

    1.群里有不定时会有同学反馈执行SQL脚本步骤使用有问题,那么咱们今天一起来学习下该步骤.trans中的执行SQL脚本有两方面功能,使用时需小心,不然很容易踩坑. 官方定义: 翻译: 您可以使用此步骤 ...

  9. C#.NET Winform承载WCF RESTful API (硬编码配置)

    1.新建一个名为"WindowsForms承载WCF"的WINFORM程序. 2.在解决方案里添加一个"WCF 服务库"的项目,名为"WcfYeah& ...

  10. Vue学习:20.综合案例-商品列表

    学而时用之,方能融会贯通! 实例:商品列表 实现功能 要求表格组件支持动态数据渲染.自定义表头和主体.标签组件需要双击显示输入框并获得焦点,可以编辑标签信息. 思路 首先是表格组件,动态渲染需要使用组 ...