当前位置:   article > 正文

国产AI编程辅助插件对比_codegeex 通义灵码

codegeex 通义灵码

目录

1. 插件范围

2. 初步对比

3. 评测标准和场景

3.1. 标准

3.2. 场景

4. 评测结果

5. 评测过程

5.1. 文本排序

5.2. 生成代码

5.3. 生成代码注释

5.4. 代码补全

5.5. 生成单元测试

5.6. 代码纠错


1. 插件范围

  1. 百度“文心一言” Comate

    官网详见:https://comate.baidu.com/

  2. 讯飞“iFlyCode"

    官网详见:http://iflycode.xfyun.cn/

  3. CodeGeeX

    官网详见:https://codegeex.cn/zh-CN

  4. 阿里“通义灵码”

    官网详见:https://tongyi.aliyun.com/lingma

2. 初步对比

根据官网文档整理的初步对比。

3. 评测标准和场景

3.1. 标准

  1. 准确率:低、中、高

  2. 生成速度:慢、中、快

  3. 易用性:差、中、友好

3.2. 场景

4. 评测结果

先说结论,基于下方评测过程,通义灵码辅助 Java 编码最佳;SQL 及代码纠错方面,可以考虑 iFlyCode

5. 评测过程

PS:长文警告~

  1. 以下用例执行结果均为使用个人版或公测版,均采用云端模型。

  2. 由于本人最常用的是 Java,因此代码相关用例以 Java 为例,使用 IDE 为 IDEA  2023.1。

  3. IDEA 插件版本:
    1. CodeGeeX 2.3.0

    2. Comate 1.13.0

    3. iFlyCode 2.0.0

    4. 通义灵码 1.0.6

5.1. 文本排序

用例

  1. 帮我排序下面的XML,要求FieldModuleUpgrader要在UpdateUpgrader后面,并保持每一行内容不变进行结果输出:
  2. <value>com.demo.rdb.upgrade.v1.r2.UpdateUpgrader</value>
  3. <value>com.demo.rdb.upgrade.v1.r3.FieldModuleUpgrader</value>
  4. <value>com.demo.rdb.upgrade.v1.r3.UpdateUpgrader</value>
  5. <value>com.demo.rdb.upgrade.v1.r2.FieldModuleUpgrader</value>
  6. <value>com.demo.rdb.upgrade.v1.r4.FieldModuleUpgrader</value>
  7. <value>com.demo.rdb.upgrade.v1.r4.UpdateUpgrader</value>
  8. <value>com.demo.rdb.upgrade.v1.r5.UpdateUpgrader</value>
  9. <value>com.demo.rdb.upgrade.v1.r5.FieldModuleUpgrader</value>
  10. <value>com.demo.rdb.upgrade.v1.r8.UpdateUpgrader</value>
  11. <value>com.demo.rdb.upgrade.v1.r7.UpdateUpgrader</value>
  12. <value>com.demo.rdb.upgrade.v1.r7.FieldModuleUpgrader</value>
  13. <value>com.demo.rdb.upgrade.v1.r8.FieldModuleUpgrader</value>
  14. <value>com.demo.rdb.upgrade.v1.r6.FieldModuleUpgrader</value>
  15. <value>com.demo.rdb.upgrade.v1.r9.UpdateUpgrader</value>
  16. <value>com.demo.rdb.upgrade.v1.r9.FieldModuleUpgrader</value>
  17. <value>com.demo.rdb.upgrade.v1.r10.UpdateUpgrader</value>
  18. <value>com.demo.rdb.upgrade.v1.r10.FieldModuleUpgrader</value>
  19. <value>com.demo.rdb.upgrade.v1.r11.UpdateUpgrader</value>
  20. <value>com.demo.rdb.upgrade.v1.r11.FieldModuleUpgrader</value>
  21. <value>com.demo.rdb.upgrade.v1.r12.UpdateUpgrader</value>
  22. <value>com.demo.rdb.upgrade.v1.r13.UpdateUpgrader</value>
  23. <value>com.demo.rdb.upgrade.v1.r13.FieldModuleUpgrader</value>
  24. <value>com.demo.rdb.upgrade.v1.r12.FieldModuleUpgrader</value>
5.1.1. iFlyCode
  • 提问

  • 回答

  • 评价
    • 准确率:低,输出格式不对、排序结果也不对;输出结果文本有缺失(可能免费版针对问答大小有限制)。

    • 生成速度:中,15 秒左右。

    • 易用性:中,针对结果无快捷操作。

5.1.2. 通义灵码
  • 提问

  • 回答

  • 评价
    • 准确率:高,输出格式正确、排序结果正确,输出结果无缺失。

    • 生成速度:中,15 秒左右。

    • 易用性:中,针对结果无快捷操作。

5.1.3. CodeGeeX
  • 提问

  • 回答

  • 评价
    • 准确率:低,输出格式正确、排序结果无变化,输出结果无缺失。

    • 生成速度:一般,15 秒左右。

    • 易用性:友好,生成结果有复制快捷操作。

5.1.4. Comate
  • 提问

由于 Comate 没有只有代码生成和代码推荐的功能,没有智能问答,因此本用例使用文心一言 3.5 进行提问。否则会被理解为代码生成,Comate 给出的是生成文本处理的 Java 代码。

  • 回答

  • 评价
    • 准确率:中,输出格式正确、排序结果基本正确,最后几行内容变了,且有一定缺失。

    • 生成速度:中,15 秒左右。

    • 易用性:友好,生成结果有复制快捷操作。

5.2. 生成代码

用例一

  1. // 以下是一个Java对象,帮我生成oracle的建表脚本,要求使用uuid作为主键,并且需要包含表结构的数据字典脚本:
  2. @Data
  3. @ApiModel(description = "费用规则")
  4. public class FeeRule implements Serializable {
  5.     private static final long serialVersionUID = -7253280007530220138L;
  6.     public static final String TABLE_NAME = "fee_rule";
  7.     @ApiModelProperty(value = "数据标识")
  8.     @Size(max = 38)
  9.     @NotBlank
  10.     private String uuid;
  11.     @ApiModelProperty(value = "规则类型,取值范围:permit-允许,deny-拒绝")
  12.     @NotNull
  13.     private AccessRuleType type;
  14.     @ApiModelProperty(value = "匹配规则")
  15.     @Size(max = 255)
  16.     @NotBlank
  17.     private String matcher;
  18.  @ApiModelProperty(value = "金额")
  19.  @NotNull
  20.  private BigDecimal total;
  21. }

用例二

  1. 以下是一段oracle建表脚本,根据它生成一个Java类且类属性字段上添加对应的注释说明:
  2. CREATE TABLE fee_rule (
  3.     uuid VARCHAR2(38NOT NULL,
  4.     type VARCHAR2(10NOT NULL,
  5.     matcher VARCHAR2(255NOT NULL,
  6.     total NUMBER(192NOT NULL,
  7.     PRIMARY KEY (uuid)
  8. );
  9. COMMENT ON TABLE fee_rule IS '费用规则';
  10. COMMENT ON COLUMN fee_rule.uuid IS '数据标识';
  11. COMMENT ON COLUMN fee_rule.type IS '规则类型,取值范围:permit-允许,deny-拒绝';
  12. COMMENT ON COLUMN fee_rule.matcher IS '匹配规则';
  13. COMMENT ON COLUMN fee_rule.total IS '金额';
5.2.1. iFlyCode
  • 回答

  1. # 用例一,生成结果
  2. CREATE TABLE fee_rule (
  3.     uuid VARCHAR2(38NOT NULL,
  4.     type AccessRuleType NOT NULL,
  5.     matcher VARCHAR2(255NOT NULL,
  6.     total NUMBER(102NOT NULL,
  7.     PRIMARY KEY (uuid)
  8. );
  9. COMMENT ON TABLE fee_rule IS '费用规则';
  10. COMMENT ON COLUMN fee_rule.uuid IS '数据标识';
  11. COMMENT ON COLUMN fee_rule.type IS '规则类型,取值范围:permit-允许,deny-拒绝';
  12. COMMENT ON COLUMN fee_rule.matcher IS '匹配规则';
  13. COMMENT ON COLUMN fee_rule.total IS '金额';
  14. # 用例二,生成结果
  15. import java.math.BigDecimal;
  16. import java.util.UUID;
  17. /**
  18.  * 费用规则
  19.  */
  20. public class FeeRule {
  21.     /**
  22.      * 数据标识
  23.      */
  24.     private String uuid;
  25.     /**
  26.      * 规则类型,取值范围:permit-允许,deny-拒绝
  27.      */
  28.     private String type;
  29.     /**
  30.      * 匹配规则
  31.      */
  32.     private String matcher;
  33.     /**
  34.      * 金额
  35.      */
  36.     private BigDecimal total;
  37.     public String getUuid() {
  38.         return uuid;
  39.     }
  40.     public void setUuid(String uuid) {
  41.         this.uuid = uuid;
  42.     }
  43.     public String getType() {
  44.         return type;
  45.     }
  46.     public void setType(String type) {
  47.         this.type = type;
  48.     }
  49.     public String getMatcher() {
  50.         return matcher;
  51.     }
  52.     public void setMatcher(String matcher) {
  53.         this.matcher = matcher;
  54.     }
  55.     public BigDecimal getTotal() {
  56.         return total;
  57.     }
  58.     public void setTotal(BigDecimal total) {
  59.         this.total = total;
  60.     }
  61. }
  • 评价
    • 准确率:高。
      • 用例一,生成脚本和注释基本可直接采用。

      • 用例二,生成的类对象也可直接采用。

    • 生成速度:中,10 秒左右。

    • 易用性:友好。
      • 生成结果有复制、插入、比较、新建文件 4 个快捷操作。

5.2.2. 通义灵码
  • 回答

  1. #用例一,生成结果
  2. CREATE TABLE fee_rule (
  3.   uuid VARCHAR2(38NOT NULL,
  4.   type VARCHAR2(10NOT NULL,
  5.   matcher VARCHAR2(255NOT NULL,
  6.   total DECIMAL(19,2NOT NULL,
  7.   CONSTRAINT fee_rule_pk PRIMARY KEY (uuid)
  8. );
  9. INSERT INTO fee_rule (uuid, type, matcher, total) VALUES ('your-uuid''permit''your-matcher'100.00);
  10. #用例二,生成结果
  11. @Data
  12. @ApiModel(description = "费用规则")
  13. public class FeeRule {
  14.     @ApiModelProperty(value = "数据标识", required = true)
  15.     private String uuid;
  16.     @ApiModelProperty(value = "规则类型,取值范围:permit-允许,deny-拒绝", required = true)
  17.     private String type;
  18.     @ApiModelProperty(value = "匹配规则", required = true)
  19.     private String matcher;
  20.     @ApiModelProperty(value = "金额", required = true)
  21.     private BigDecimal total;
  22. }
  • 评价
    • 准确率:
      • 用例一,中。
        • 未生成数据字典脚本。

        • 其中金额更常用 Number 类型来定义。

      • 用例二,高
        • 能结合用例一生成一个简洁合理的对象。

    • 生成速度:快,5 秒左右。

    • 易用性:友好。
      • 方法上有操作按钮选择生成注释,生成结果有复制、插入、新建文件 3 个快捷操作。

5.2.3. CodeGeeX
  • 回答

  1. #用例一,生成结果
  2. CREATE TABLE fee_rule (
  3.   uuid NCHAR(38DEFAULT '00000000-0000-0000-0000-000000000000' NOT NULL,
  4.   type VARCHAR2(7NOT NULL,
  5.   matcher VARCHAR2(255NOT NULL,
  6.   total NUMBER(19,4NOT NULL,
  7.   PRIMARY KEY (uuid)
  8. );
  9. CREATE SEQUENCE fee_rule_seq
  10.   START WITH 1
  11.   INCREMENT BY 1
  12.   MINVALUE 1
  13.   MAXVALUE CREATE SEQUENCE fee_rule_seq
  14.   START WITH 1
  15.   INCREMENT BY 1
  16.   MINVALUE 1
  17.   MAXVALUE 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
  18. #用例二,生成结果
  19. import java.math.BigDecimal;
  20. /**
  21.  * 费用规则
  22.  */
  23. public class FeeRule {
  24.     /**
  25.      * 数据标识
  26.      */
  27.     private String uuid;
  28.     /**
  29.      * 规则类型,取值范围:permit-允许,deny-拒绝
  30.      */
  31.     private String type;
  32.     /**
  33.      * 匹配规则
  34.      */
  35.     private String matcher;
  36.     /**
  37.      * 金额
  38.      */
  39.     private BigDecimal total;
  40.     // getters and setters
  41. }
  • 评价
    • 准确率:中。
      • 用例一
        • 字段类型基本是所想要的,除了 uuid。

        • 表结构字典没生成 oracle 自己的添加注释的脚步,而是自己建了个表,且 MAXVALUE 卡死持续输出 9。

      • 用例二
        • 类和属性及属性的注释都生成正确,getters 和 setters 省略了。

    • 生成速度:快,5 秒左右。

    • 易用性:中
      • 生成结果上有复制按钮。

5.2.4. Comate
  • 回答
    • 用例一

  • 用例二

  • 评价
    • 准确率:中。
      • 用例一
        • 字段类型基本是所想要的,除了 uuid。

        • 表结构字典没生成。

      • 用例二
        • 类和属性及属性的注释都生成正确,getters 和 setters 也生成

        • 不足的是,金额的类型给的不对;类属性的注释不太规范。

    • 生成速度:中,15 秒左右。

    • 易用性:中
      • 生成结果上有复制按钮。

5.3. 生成代码注释

用例

  1. 生成代码注释
  2.  public static BigDecimal avg(List<Object> list, String propName, int scale, String roundScale) {
  3.       if (CollectionUtils.isEmpty(list)) {
  4.         return BigDecimal.ZERO;
  5.       }
  6.       BigDecimal sum = sum(list, propName);
  7.       return sum.divide(new BigDecimal(list.size()), scale, RoundingMode.valueOf(roundScale));
  8.     }
5.3.1. iFlyCode
  • 提问

  • 回答

  • 评价
    • 准确率:高,生成的注释基本可直接采用。

    • 生成速度:快,5 秒左右。

    • 易用性:友好。
      • 生成结果有复制、插入、比较、新建文件 4 个快捷操作。

      • 也可设置快捷键触发。

      • 也可通过鼠标右键触发。

5.3.2. 通义灵码
  • 提问

  • 回答

  • 评价
    • 准确率:高,生成的注释基本可直接采用。

    • 生成速度:快,5 秒左右。

    • 易用性:友好。
      • 方法上有操作按钮选择生成注释,生成结果有复制、插入、比较、新建文件 4 个快捷操作。

      • 也可设置快捷键触发。

      • 也可通过鼠标右键触发。

5.3.3. CodeGeeX
  • 提问

  • 回答

  • 评价
    • 准确率:中,输出格式不是想要的,有点像代码解释。

    • 生成速度:快,5 秒左右。

    • 易用性:中
      • 选中代码块,通过快捷键或右键触发。

      • 生成结果直接在代码上添加注释,会生成多余的注释。

5.3.4. Comate
  • 回答

  • 评价
    • 准确率:高,注释基本可用。

    • 生成速度:快,5 秒左右。

    • 易用性:中
      • 选中代码块,需要再问答框中点生成注释。

      • 生成结果上有采纳按钮,可以直接插入代码上方。

5.4. 代码补全

用例如下

  1. 1. 编写一个Student类,包含uuid、code、name字段。
  2. 2. 从一个List<Student>列表中提取uuid列表。
5.4.1. iFlyCode
  • 续写过程

  • 评价
    • 准确率:中。
      • 上述示例中的 get/set 方法级别的续写未能触发。

      • 对代码上下文的识别有待改进。

    • 生成速度:慢,需要停顿等待较长时间。

    • 易用性:友好。
      • 启用插件后自动触发代码续写、或者通过快捷键触发。

      • Esc 取消建议代码,Tab 接受并插入建议代码。

5.4.2. 通义灵码
  • 续写过程

  • 评价
    • 准确率:高,能识别上下文。

    • 生成速度:快,不影响正常的编码。

    • 易用性:友好。
      • 启用插件后自动触发代码续写。

      • Esc 取消建议代码,Tab 接受并插入建议代码。

5.4.3. CodeGeeX
  • 续写过程

  • 评价
    • 准确率:低。

    • 生成速度:慢,示例没录完,卡得不要不要加上准确度低没有往下的必要。

    • 易用性:差
      • 通过快捷键触发、建议结果还得再点下 insert。

5.4.4. Comate
  • 续写过程

  • 评价
    • 准确率:中。
      • 对代码上下文的识别有待改进,不能明确识别 main 函数中 uuids 的赋值意图,需要输入较多上下文才能识别,且生成的建议代码不太理想。

    • 生成速度:快。

    • 易用性:中。
      • 启用插件后自动触发代码续写、或者通过快捷键触发。

      • Esc 取消建议代码,Tab 接受并插入建议代码。

      • 没有多行续写,普通的 getter、setter 都得一行一行进行确认,可能和插件设置的模式有关系。

5.5. 生成单元测试

用例如下

  1. //生成以下控制器的单元测试代码:
  2. @Api(tags = "测试类")
  3. @RestController
  4. @RequestMapping("/api/student")
  5. public class StudentController {
  6.     @ApiOperation(value = "获取学生")
  7.     @GetMapping(value = "/get")
  8.     public Response<Student> get(@RequestParam(value = "code", required = true) String code) {
  9.         //...
  10.         return Response.success();
  11.     }
  12.     @ApiOperation(value = "创建学生")
  13.     @PostMapping(value = "/create")
  14.     public Response<Void> create(@RequestBody Student student) {
  15.         //...
  16.         return Response.success();
  17.     }
  18.     @ApiOperation(value = "编辑学生")
  19.     @PostMapping(value = "/modify")
  20.     public Response<Void> modify(@RequestBody Student student) {
  21.         //...
  22.         return Response.success();
  23.     }
  24.     @ApiOperation(value = "删除学生")
  25.     @PostMapping(value = "/delete")
  26.     public Response<Void> delete(@RequestBody Student student) {
  27.         //...
  28.         return Response.success();
  29.     }
  30. }
5.5.1. iFlyCode
  • 回答

  1. import org.junit.jupiter.api.Test;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.http.MediaType;
  6. import org.springframework.test.web.servlet.MockMvc;
  7. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
  8. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  9. @SpringBootTest
  10. @AutoConfigureMockMvc
  11. public class StudentControllerTest {
  12.     @Autowired
  13.     private MockMvc mockMvc;
  14.     @Test
  15.     public void testGet() throws Exception {
  16.         String code = "123456";
  17.         mockMvc.perform(get("/api/student/get")
  18.                 .param("code"code))
  19.                 .andExpect(status().isOk());
  20.     }
  21.     @Test
  22.     public void testCreate() throws Exception {
  23.         Student student = new Student();
  24.         // Set student properties here
  25.         mockMvc.perform(post("/api/student/create")
  26.                 .contentType(MediaType.APPLICATION_JSON)
  27.                 .content(json(student)))
  28.                 .andExpect(status().isOk());
  29.     }
  30.     @Test
  31.     public void testModify() throws Exception {
  32.         Student student = new Student();
  33.         // Set student properties here
  34.         mockMvc.perform(post("/api/student/modify")
  35.                 .contentType(MediaType.APPLICATION_JSON)
  36.                 .content(json(student)))
  37.                 .andExpect(status().isOk());
  38.     }
  39.     @Test
  40.     public void testDelete() throws Exception {
  41.         Student student = new Student();
  42.         // Set student properties here
  43.         mockMvc.perform(post("/api/student/delete")
  44.                 .contentType(MediaType.APPLICATION_JSON)
  45.                 .content(json(student)))
  46.                 .andExpect(status().isOk());
  47.     }
  48.     @Test
  49.     public void testGetMissingParam() throws Exception {
  50.         mockMvc.perform(get("/api/student/get"))
  51.                 .andExpect(status().is4xxClientError());
  52.     }
  53.     @Test
  54.     public void testCreateMissingParam() throws Exception {
  55.         Student student = new Student();
  56.         // Remove required property here
  57.         mockMvc.perform(post("/api/student/create")
  58.                 .contentType(MediaType.APPLICATION_JSON)
  59.                 .content(json(student)))
  60.                 .andExpect(status().is4xxClientError());
  61.     }
  62.     @Test
  63.     public void testModifyMissingParam() throws Exception {
  64.         Student student = new Student();
  65.         // Remove required property here
  66.         mockMvc.perform(post("/api/student/modify")
  67.                 .contentType(MediaType.APPLICATION_JSON)
  68.                 .content(json(student)))
  69.                 .andExpect(status().is4xxClientError());
  70.     }
  71.     @Test
  72.     public void testDeleteMissingParam() throws Exception {
  73.         mockMvc.perform(post("/api/student/delete")
  74.                 .contentType(MediaType.APPLICATION_JSON)
  75.                 .content(json(new Student())))
  76.                 .andExpect(status().is4xxClientError());
  77.     }
  78. }
  • 评价
    • 准确率:高
      • 生成的建议代码基本可用,只需补充 json 方法、执行入口类声明。

    • 生成速度:慢,20 秒左右。

    • 易用性:友好。
      • 生成结果有复制、插入、比较、新建文件 4 个快捷操作。

      • 也可设置快捷键触发。

      • 也可通过鼠标右键触发。

5.5.2. 通义灵码
  • 回答

  1. 默认使用 mockito+junit 生成单测。

  2. 也可以选择 Sprint Test 库生成。

  1. //Mockito框架生成的
  2. import org.junit.jupiter.api.Assertions;
  3. import org.junit.jupiter.api.BeforeEach;
  4. import org.junit.jupiter.api.Test;
  5. import org.mockito.InjectMocks;
  6. import org.mockito.Mock;
  7. import org.mockito.MockitoAnnotations;
  8. import org.springframework.http.ResponseEntity;
  9. import static org.mockito.Mockito.*;
  10. public class StudentControllerTest {
  11.     @Mock
  12.     private StudentService studentService;
  13.     @InjectMocks
  14.     private StudentController studentController;
  15.     @BeforeEach
  16.     public void setup() {
  17.         MockitoAnnotations.initMocks(this);
  18.     }
  19.     @Test
  20.     public void testGet() {
  21.         String code = "123456";
  22.         Student student = new Student();
  23.         when(studentService.getByCode(code)).thenReturn(student);
  24.         ResponseEntity<Response<Student>> response = studentController.get(code);
  25.         Assertions.assertEquals(ResponseStatus.SUCCESS.getStatusCode(), response.getStatusCode());
  26.         Assertions.assertEquals(student, response.getBody().getData());
  27.     }
  28.     @Test
  29.     public void testCreate() {
  30.         Student student = new Student();
  31.         when(studentService.create(student)).thenReturn(ResponseStatus.SUCCESS);
  32.         ResponseEntity<Response<Void>> response = studentController.create(student);
  33.         Assertions.assertEquals(ResponseStatus.SUCCESS.getStatusCode(), response.getStatusCode());
  34.         Assertions.assertNull(response.getBody().getData());
  35.     }
  36.     @Test
  37.     public void testModify() {
  38.         Student student = new Student();
  39.         when(studentService.modify(student)).thenReturn(ResponseStatus.SUCCESS);
  40.         ResponseEntity<Response<Void>> response = studentController.modify(student);
  41.         Assertions.assertEquals(ResponseStatus.SUCCESS.getStatusCode(), response.getStatusCode());
  42.         Assertions.assertNull(response.getBody().getData());
  43.     }
  44.     @Test
  45.     public void testDelete() {
  46.         Student student = new Student();
  47.         when(studentService.delete(student)).thenReturn(ResponseStatus.SUCCESS);
  48.         ResponseEntity<Response<Void>> response = studentController.delete(student);
  49.         Assertions.assertEquals(ResponseStatus.SUCCESS.getStatusCode(), response.getStatusCode());
  50.         Assertions.assertNull(response.getBody().getData());
  51.     }
  52. }
  53. //SpringTest生成的
  54. @RunWith(SpringRunner.class)
  55. @SpringBootTest
  56. public class StudentControllerTest {
  57.     @Autowired
  58.     private WebApplicationContext context;
  59.     @Test
  60.     public void getTest() {
  61.         // Mock request parameters
  62.         MockHttpServletRequestBuilder getBuilder = MockMvcRequestBuilders.get("/api/student/get")
  63.                 .param("code""123456");
  64.         // Perform the GET request
  65.         MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
  66.         mockMvc.perform(getBuilder)
  67.                 .andExpect(status().isOk())
  68.                 .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
  69.                 .andDo(MockMvcResultMatchers.write(outputMessage));
  70.         // Verify the response
  71.         String responseBody = outputMessage.getContentAsString();
  72.         Response<Student> response = objectMapper.readValue(responseBody, ResponseStudent.class);
  73.         Assertions.assertEquals(HttpStatus.OK, response.getStatus());
  74.         Assertions.assertNotNull(response.getData());
  75.         // Assert other properties of the response here
  76.     }
  77.     @Test
  78.     public void createTest() {
  79.         // Mock request body
  80.         Student student = new Student();
  81.         // Set properties of the student object
  82.         // Perform the POST request
  83.         MockHttpServletRequestBuilder postBuilder = MockMvcRequestBuilders.post("/api/student/create")
  84.                 .contentType(MediaType.APPLICATION_JSON)
  85.                 .content(objectMapper.writeValueAsString(student));
  86.         // Perform the POST request
  87.         MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
  88.         mockMvc.perform(postBuilder)
  89.                 .andExpect(status().isCreated())
  90.                 .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
  91.                 .andDo(MockMvcResultMatchers.write(outputMessage));
  92.         // Verify the response
  93.         String responseBody = outputMessage.getContentAsString();
  94.         Response<Void> response = objectMapper.readValue(responseBody, ResponseVoid.class);
  95.         Assertions.assertEquals(HttpStatus.CREATED, response.getStatus());
  96.         Assertions.assertNull(response.getData());
  97.         // Assert other properties of the response here
  98.     }
  99.     @Test
  100.     public void modifyTest() {
  101.         // Mock request body
  102.         Student student = new Student();
  103.         // Set properties of the student object
  104.         // Perform the POST request
  105.         MockHttpServletRequestBuilder postBuilder = MockMvcRequestBuilders.post("/api/student/modify")
  106.                 .contentType(MediaType.APPLICATION_JSON)
  107.                 .content(objectMapper.writeValueAsString(student));
  108.         // Perform the POST request
  109.         MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
  110.         mockMvc.perform(postBuilder)
  111.                 .andExpect(status().isOk())
  112.                 .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
  113.                 .andDo(MockMvcResultMatchers.write(outputMessage));
  114.         // Verify the response
  115.         String responseBody = outputMessage.getContentAsString();
  116.         Response<Void> response = objectMapper.readValue(responseBody, ResponseVoid.class);
  117.         Assertions.assertEquals(HttpStatus.OK, response.getStatus());
  118.         Assertions.assertNull(response.getData());
  119.         // Assert other properties of the response here
  120.     }
  121.     @Test
  122.     public void deleteTest() {
  123.         // Mock request body
  124.         Student student = new Student();
  125.         // Set properties of the student object
  126.         // Perform the POST request
  127.         MockHttpServletRequestBuilder postBuilder = MockMvcRequestBuilders.post("/api/student/delete")
  128.                 .contentType(MediaType.APPLICATION_JSON)
  129.                 .content(objectMapper.writeValueAsString(student));
  130.         // Perform the POST request
  131.         MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
  132.         mockMvc.perform(postBuilder)
  133.                 .andExpect(status().isOk())
  134.                 .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
  135.                 .andDo(MockMvcResultMatchers.write(outputMessage));
  136.         // Verify the response
  137.         String responseBody = outputMessage.getContentAsString();
  138.         Response<Void> response = objectMapper.readValue(responseBody, ResponseVoid.class);
  139.         Assertions.assertEquals(HttpStatus.OK, response.getStatus());
  140.         Assertions.assertNull(response.getData());
  141.         // Assert other properties of the response here
  142.     }
  143. }
  • 评价
    • 准确率:中~高。
      • mockito 生成的结果不理想,基本不可用。

      • SpringTest 的生成的结构比 iFlyCode 多了 response 校验,但缺少 import 包,同时部分异常、注解、变量没有声明;要跑起来比较费劲。

    • 生成速度:快,10~15 秒左右。

    • 易用性:友好。
      • 可设置快捷键或右键选择触发生成单元测试。

      • 生成结果有插入、复制、新建快捷操作按钮。

      • 生成结果可选择单测的框架生成。

5.5.3. CodeGeeX
  • 回答

  1. import com.example.demo.controller.StudentController;
  2. import com.example.demo.entity.Student;
  3. import com.example.demo.response.Response;
  4. import com.example.demo.response.StudentResponse;
  5. import org.junit.jupiter.api.Test;
  6. import org.springframework.mock.web.MockHttpServletRequest;
  7. import org.springframework.mock.web.MockHttpServletResponse;
  8. import org.springframework.test.web.servlet.MockMvc;
  9. import org.springframework.test.web.servlet.request.MockRequestBuilders;
  10. import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
  11. import org.springframework.test.web.servlet.setup.MockMvcSetup;
  12. import static org.springframework.test.web.servlet.request.RequestMethod.GET;
  13. import static org.springframework.test.web.servlet.request.RequestMethod.POST;
  14. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
  15. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  16. public class StudentControllerTest {
  17.     private MockMvc mockMvc;
  18.     @Test
  19.     public void testGet() throws Exception {
  20.         // Prepare test data
  21.         String code = "123";
  22.         // Create mock request and response
  23.         MockHttpServletRequest request = new MockHttpServletRequest();
  24.         request.setMethod(GET.toUpperCase());
  25.         request.addParameter("code"code);
  26.         MockHttpServletResponse response = new MockHttpServletResponse();
  27.         // Prepare mock controller instance
  28.         StudentController studentController = new StudentController();
  29.         // Configure mock MVC
  30.         MockMvcSetup mockMvcSetup = mockMvcSetup()
  31.                 .andController(studentController)
  32.                 .andRequest(request)
  33.                 .andResponse(response);
  34.         // Execute test
  35.         mockMvc.perform(mockMvcSetup)
  36.                 .andExpect(status().isOk())
  37.                 .andExpect(jsonPath("$.code").value(code));
  38.     }
  39.     @Test
  40.     public void testCreate() throws Exception {
  41.         // Prepare test data
  42.         Student student = new Student();
  43.         student.setCode("123");
  44.         student.setName("John Doe");
  45.         // Create mock request and response
  46.         MockHttpServletRequest request = new MockHttpServletRequest();
  47.         request.setMethod(POST.toUpperCase());
  48.         request.addHeader("Content-Type""application/json");
  49.         request.setContentType("application/json");
  50.         request.setCharacterEncoding("UTF-8");
  51.         request.getWriter().write(student.toString());
  52.         request.getWriter().flush();
  53.         request.getWriter().close();
  54.         MockHttpServletResponse response = new MockHttpServletResponse();
  55.         // Prepare mock controller instance
  56.         StudentController studentController = new StudentController();
  57.         // Configure mock MVC
  58.         MockMvcSetup mockMvcSetup = mockMvcSetup()
  59.                 .andController(studentController)
  60.                 .andRequest(request)
  • 评价
    • 准确率:差。
      • 内容输出不全,可能免费版有限制。

      • 生成代码不够友好,部分常量写死。

      • 生成代码难以使用。

    • 生成速度:快,10 秒左右。

    • 易用性:中
      • 选中代码块,通过智能问答框输入“生成单元测试”。

      • 生成结果有复制按钮。

5.5.4. Comate
  • 回答

  1. package com.test.ai;
  2. import org.junit.jupiter.api.Assertions;
  3. import org.junit.jupiter.api.Test;
  4. import org.junit.runner.RunWith;
  5. import org.mockito.Mockito;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.boot.test.mock.mockito.MockBean;
  10. import org.springframework.http.MediaType;
  11. import org.springframework.test.context.junit4.SpringRunner;
  12. import org.springframework.test.web.servlet.MockMvc;
  13. import org.springframework.boot.test.mock.mockito.MockBean;
  14. import org.springframework.test.web.servlet.MockMvc;
  15. @RunWith(SpringRunner.class)
  16. @SpringBootTest
  17. public class StudentControllerTest {
  18.     @Autowired
  19.     private MockMvc mvc;
  20.     @MockBean
  21.     private StudentService studentService;
  22.     @Test
  23.     public void get() throws Exception {
  24.         Mockito.when(studentService.get(Mockito.anyString())).thenReturn(new Student());
  25.         RequestBuilder builder = (RequestBuilder) new RequestBuilder()
  26.                 .setRequest(TestClient.httpRequest("/get?code=123""GET"))
  27.                 .setMediaType(MediaType.APPLICATION_JSON);
  28.         ResponseEntity<Response<Student>> response = TestClient.sendRequest(mvc, builder, new TypeReference<Response<Student>>() {});
  29.         Assertions.assertNotNull(response);
  30.         Assertions.assertEquals(200, response.getStatusCode().value());
  31.     }
  32. }
  • 评价
    • 准确率:低。
      • 只生成了 get 方法,没有 service 也给生成了 service 相关代码。

      • 生成的结果需要费大力气改动才能跑起来。

    • 生成速度:快,8 秒左右。

    • 易用性:中。
      • 有采纳的快捷按钮操作,可以直接在 test 目录下自动生成单测类。

5.6. 代码纠错

用例如下

  1.  //下面代码存在bug吗?
  2.  public static BigDecimal avg(List<Object> list, String propName, int scale, String roundScale) {
  3.       if (CollectionUtils.isEmpty(list)) {
  4.         return BigDecimal.ZERO;
  5.       }
  6.       BigDecimal sum = sum(list, propName);
  7.       return sum.divide(new BigDecimal(list.size()), scale, RoundingMode.valueOf(roundScale));
  8.     }
5.6.1. iFlyCode
  • 提问

  • 回答

  1. //由于结果展示不友好,以下为复制出来后的修复结果
  2. import java.math.BigDecimal;
  3. import java.math.RoundingMode;
  4. import org.apache.commons.collections4.CollectionUtils;
  5. import java.util.List;
  6. public class Main {
  7.     public static BigDecimal sum(List<Object> list, String propName) {
  8.         BigDecimal sum = BigDecimal.ZERO;
  9.         for (Object obj : list) {
  10.             try {
  11.                 // Assuming propName is a field in the object and it's type is BigDecimal
  12.                 Field field = obj.getClass().getDeclaredField(propName);
  13.                 field.setAccessible(true);
  14.                 sum = sum.add(new BigDecimal(field.get(obj).toString()));
  15.             } catch (NoSuchFieldException | IllegalAccessException e) {
  16.                 e.printStackTrace();
  17.             }
  18.         }
  19.         return sum;
  20.     }
  21.     public static BigDecimal avg(List<Object> list, String propName, int scale, String roundScale) {
  22.         if (CollectionUtils.isEmpty(list)) {
  23.             return BigDecimal.ZERO;
  24.         }
  25.         BigDecimal sum = sum(list, propName);
  26.         RoundingMode roundingMode;
  27.         try {
  28.             roundingMode = RoundingMode.valueOf(roundScale);
  29.         } catch (IllegalArgumentException e) {
  30.             throw new IllegalArgumentException("Invalid rounding mode: " + roundScale, e);
  31.         }
  32.         return sum.divide(new BigDecimal(list.size()), scale, roundingMode);
  33.     }
  34. }
  • 评价
    • 准确率:高,生成的建议代码基本可用。

    • 生成速度:中,15 秒左右。

    • 易用性:友好。
      • 生成结果有复制、插入、比较、新建文件 4 个快捷操作。

      • 也可设置快捷键触发。

      • 也可通过鼠标右键触发。

5.6.2. 通义灵码
  • 回答

  • 评价
    • 准确率:低。

    • 生成速度:快,5 秒左右。

    • 易用性:差,无快捷操作,只能自己拷贝放到问答框中。

5.6.3. CodeGeeX
  • 提问

  • 回答

  • 评价
    • 准确率:中,如果 sum 没处理好返回值,确实可能存在其描述的 bug。

    • 生成速度:快,5 秒左右。

    • 易用性:中
      • 选中代码块,通过右键或快捷键触发智能问答;或这自行拷贝到问答框中。

      • 纠错结果提供拷贝按钮。

5.6.4. Comate
  • 回答

  • 评价
    • 准确率:低,结果和通义灵码类似,处理方式还略有不如。

    • 生成速度:快,5 秒左右。

    • 易用性:差,无快捷操作,只能自己拷贝放到问答框中。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/361816
推荐阅读
相关标签
  

闽ICP备14008679号