AI 驱动的开发者(MEAP)(二)(4)

简介: AI 驱动的开发者(MEAP)(二)

AI 驱动的开发者(MEAP)(二)(3)https://developer.aliyun.com/article/1516331

6.3 搜索错误

在这一部分,我们将使用一个基本的(尽管相当牵强)示例来演示我们如何使用 Copilot 来查找和修复我们代码中的问题。 这段代码应该循环遍历整数列表并计算总和。 但是,存在一个“眨眼就会错过”的错误。 总和被赋予了 i 的值,而不是将 i 的值添加到累加总和中。

列表 6.11 简单循环遍历整数列表并计算总和
l = [1, 2, 3, 4, 5]
if __name__ == '__main__':
    sum = 0
    for i in l:
        sum = i
    print("sum is", sum)

要调试此问题,我们将引入一个新工具:Copilot 实验室。在 Copilot 聊天之前,Copilot 实验室是我们的 IDE 中某些功能可用的唯一方式,具体来说是 VS Code。例如,我们需要使用 Copilot 实验室来查找和修复错误。Copilot 实验室今天仍然具有的主要优势是,它可以访问编辑器窗格中突出显示的内容。此功能使 Copilot 实验室能够直接在您的 IDE 中的可编辑代码上操作。安装扩展到您的 IDE 后,您应该在 IDE 的左侧看到一个 Copilot 实验室工具包。如果您需要提醒如何将扩展安装到您的 IDE 中,请参考附录 A 到 C,其中包含有关安装扩展的说明。

图 6.1 Copilot 实验室工具包菜单,其中包括查找和修复错误的选项。该工具包还提供增强您的代码以及对其进行文档化的功能。


我们将暂时更改 main.py 文件的内容为列表 6.9 中列出的代码。完成此更改后,请突出显示代码,并在 Copilot 实验室工具包中按下“修复 Bug”按钮。您应该会看到类似于图 6.2 中的输出。Copilot 实验室能够确定此代码中的问题,并提供解决此问题的建议。

图 6.2 Copilot 实验室,使用 GPT 模型,已经识别出了错误以及如何解决此错误


或者,我们可以将这段代码复制到 ChatGPT 中,并要求它找到错误。然而,可以争论的是,这可能不太方便,因为在请求 ChatGPT 修复之前,您必须知道代码中存在错误。

6.4 覆盖代码

代码覆盖率是衡量您的代码被测试覆盖程度的一种指标。通常以百分比表示,代表您的代码被测试执行的比例。

代码覆盖率可以用作评估测试效果的指标。如果您的代码覆盖率较低,可能表示您的代码的某些部分未经过测试,这可能导致未捕获的错误和其他问题。另外,如果代码覆盖率高,则您可以放心您的代码经过了充分测试。这并不保证您的代码是无错的,但应该表明对于应该在测试中捕获的错误,您具有很高的信心。

为了确定我们的 Python 项目中的代码覆盖率,我们将使用 coverage 库中提供的代码覆盖率工具 coverage。coverage 库通过对我们的代码进行工具化来收集运行时的覆盖率数据。它可以收集任何 Python 代码的覆盖率数据,包括测试、脚本和模块。通过使用像 coverage 这样的代码覆盖率工具,我们可以更好地了解我们的代码有多少被我们的测试所覆盖,并识别可能需要更多测试的代码区域。

首先,让我们使用 pip 安装 coverage:pip install coverage. 接下来,让我们使用 coverage 运行我们的测试:coverage run -m pytest. 这将运行您的测试并收集覆盖率数据。

接下来,我们将生成一个覆盖率报告。覆盖率报告将显示项目中每个文件的代码覆盖率。我们使用以下命令创建基于文本的覆盖率报告:coverage report 或使用以下命令生成报告的 HTML 版本:coverage html。报告的 HTML 版本将位于 htmlcov 目录中。图 6.3 显示了覆盖率报告。

图 6.3 代码覆盖率报告显示了我们信息技术资产管理系统项目中每个文件的覆盖情况。


代码覆盖率达到 70% 是一个不错的起点。在现实世界中,我们将继续与我们的团队和生成式人工智能小伙伴合作,将这个指标提高到高 90%。

我们将转向一个新的主题:使用生成式人工智能为我们描述代码列表。

6.5 将代码转换成描述 - 从代码到描述

通常,人们会交给你现有的源代码。确定这段代码的确切入口点、代码的目的以及棕地项目的整体结构可能是具有挑战性的。幸运的是,这正是生成式人工智能真正擅长的领域之一:将代码翻译成文本描述。

首先,我们将把(有 bug 的)代码从上一节复制到 Copilot 聊天对话框中,并加上提示语:“这段代码是做什么的?

图 6.4 上一节的有 bug 代码,并附有提示,要求 Copilot 聊天向我们解释这段代码。


这个解释引人注目的地方在于,Copilot 聊天检测到代码中存在一个 bug,并提出了如何修复这个 bug 的建议。

图 6.5 Copilot 聊天解释了代码的目的,识别了 bug,并提出了修复建议。


接下来,我们将提出一个更具挑战性的问题。我们将要求它解释我们在本章前面设置的行为测试。将代码复制到 Copilot 聊天窗口中,并询问这个类做什么。您可能会收到类似以下清单的回复。

列表 6.12 Copilot Chat 解释了我们之前编写的行为测试的行为。
The code you provided is not a class but a series of step definitions for a Behavior-Driven Development (BDD) test using the Behave framework in Python. These steps correspond to a specific scenario written in Gherkin language (Given, When, Then format).
These step definitions describe how to interact with an AssetManager class and an InMemoryAssetRepository class. They're meant to test the creation of assets and the calculation of the total cost of all assets.
Let's go through each step:
@given('the Asset Manager is running'): This sets up the initial state for the test. It initializes the AssetManager with an InMemoryAssetRepository (which presumably stores assets in memory during the execution of the test) and a mocked AssetLocationMediator.
@given('the InMemoryAssetRepository is initialized') and @given('the AssetLocationMediator is mocked'): These steps appear to be placeholders, as they don't execute any actions.
@when('I create an asset with a cost of ${cost}') and @when('I create another asset with a cost of ${cost}'): These steps create Asset instances with the given cost and add them to the AssetManager.
@then('the total cost of all assets should be ${total_cost}'): This step retrieves all the assets from the AssetManager, calculates the total cost, and checks that it matches the expected total cost.
This sequence of steps allows the user to test the process of creating assets and validating the total cost of all assets in the AssetManager.
    # Question: What does this method do?
    # Answer: It gets an asset by its id
    async def get_asset(self, asset_id: int):
        asset = self._asset_rest_port.read(asset_id)
        if asset is None:
            raise HTTPException(status_code=404, detail="Asset not found")
        return from_asset(asset)

6.6 从一种语言翻译成另一种语言

看起来很遥远,您可能会发现自己正在查看一个语言只是稍有了解的编程语言编写的代码库。或者,您可能想在当前语言中使用来自另一种语言的特定函数。例如,以 JavaScript 重写 AssetFundingDetails 类会是什么样子呢?好吧,让我们问问 Copilot Chat。

列表 6.13 Copilot Chat 将我们的 AssetFundingDetails 类翻译成了 JavaScript。
class Asset {
  constructor(id, name, status, category, cost, useful_life, salvage_value, purchase_date, locations, funding_details) {
    this.id = id;
    this.name = name;
    this.status = status;
    this.category = category;
    this.cost = cost;
    this.useful_life = useful_life;
    this.salvage_value = salvage_value;
    this.purchase_date = purchase_date;
    this.locations = locations;
    this.funding_details = funding_details;
  }
}
class FundingDetails {
  constructor(asset, funding_source, funding_amount) {
    this.asset = asset;
    this.funding_source = funding_source;
    this.funding_amount = funding_amount;
  }
}

我们可能会认为翻译一个或两个类太容易了。好吧,我们将尝试更复杂的事情。如果用 JavaScript 写 AssetManager 行为测试,它会是什么样子?

列表 6.14 Copilot Chat 将我们的 AssetManager 行为测试翻译成了 JavaScript。
const AssetManager = require('./asset_manager');
const Asset = require('./asset');
describe('AssetManager', () => {
  let assetManager;
  beforeEach(() => {
    assetManager = new AssetManager();
  });
  describe('addAsset', () => {
    it('should add an asset to the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      expect(assetManager.assets.length).toBe(1);
      expect(assetManager.assets[0]).toBe(asset);
    });
  });
  describe('removeAsset', () => {
    it('should remove an asset from the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      assetManager.removeAsset(asset);
      expect(assetManager.assets.length).toBe(0);
    });
  });
  describe('getAssetById', () => {
    it('should return the asset with the given ID', () => {
      const asset1 = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      const asset2 = new Asset(2, 'Printer', 'Active', 'Hardware', 500.0, 3, 50.0, new Date(), [], null);
      assetManager.addAsset(asset1);
      assetManager.addAsset(asset2);
      const result = assetManager.getAssetById(2);
      expect(result).toBe(asset2);
    });
    it('should return null if no asset with the given ID is found', () => {
      const result = assetManager.getAssetById(1);
      expect(result).toBeNull();
    });
  });
});

另外,您可能希望让 GPT 以惯用的 JavaScript 重写代码。您只需要说:“用惯用的 JavaScript 编写 AssetManager。”Copilot Chat 将告诉您它使用 ES6 中引入的 class 语法来定义 AssetManager 类。

列表 6.15 AssetManager 类被以惯用的 JavaScript 重写。
class AssetManager {
  constructor() {
    this.assets = [];
  }
  addAsset(asset) {
    this.assets.push(asset);
  }
  removeAsset(asset) {
    const index = this.assets.indexOf(asset);
    if (index !== -1) {
      this.assets.splice(index, 1);
    }
  }
  getAssetById(id) {
    return this.assets.find(asset => asset.id === id) || null;
  }
}

这是 AssetManager 行为测试在 JavaScript 中使用 Jest 测试框架的示例(Copilot Chat 在没有我们的建议的情况下包含了这个):

列表 6.16 Copilot Chat 用惯用的 JavaScript 重写了我们的 AssetManager 测试。
const AssetManager = require('./asset_manager');
const Asset = require('./asset');
describe('AssetManager', () => {
  let assetManager;
  beforeEach(() => {
    assetManager = new AssetManager();
  });
  describe('addAsset', () => {
    it('should add an asset to the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      expect(assetManager.assets.length).toBe(1);
      expect(assetManager.assets[0]).toBe(asset);
    });
  });
  describe('removeAsset', () => {
    it('should remove an asset from the asset list', () => {
      const asset = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      assetManager.addAsset(asset);
      assetManager.removeAsset(asset);
      expect(assetManager.assets.length).toBe(0);
    });
  });
  describe('getAssetById', () => {
    it('should return the asset with the given ID', () => {
      const asset1 = new Asset(1, 'Computer', 'Active', 'Hardware', 1000.0, 5, 100.0, new Date(), [], null);
      const asset2 = new Asset(2, 'Printer', 'Active', 'Hardware', 500.0, 3, 50.0, new Date(), [], null);
      assetManager.addAsset(asset1);
      assetManager.addAsset(asset2);
      const result = assetManager.getAssetById(2);
      expect(result).toBe(asset2);
    });
    it('should return null if no asset with the given ID is found', () => {
      const result = assetManager.getAssetById(1);
      expect(result).toBeNull();
    });
  });
});

在此示例中,我们使用 Jest 测试框架为 AssetManager 类定义了一组行为测试。我们使用 describe 库确定测试套件和单个测试。

在每个测试中,我们创建 AssetManager 类的一个实例并对其执行某些操作,例如添加或删除资产。然后,我们使用 expect 函数对 AssetManager 类的行为进行断言,例如检查资产是否已添加到资产列表或资产是否已从资产列表中删除。

请注意,在 JavaScript 中,定义类和构造函数的语法与 Python 略有不同,我们使用 required 函数从各自的模块中导入 AssetManager 和 Asset 类。

最后,为了大结局:我们将开始一个新的 ChatGPT 4.0 会话,并将第三章中的 Mermaid 图表粘贴到其中。请以提示“这是我应用程序的 Mermaid 图表,请用 Golang 实现。”为主导。它将返回用 Golang 渲染的代码。

列表 6.17 Copilot Chat 用惯用的 Golang 重写了我们的 Asset 类。
type Asset struct {
    id            int
    name          string
    status        string
    category      string
    fundingDetails *FundingDetails
}
func NewAsset(name, status, category string, fundingDetails *FundingDetails) *Asset {
    return &Asset{
        name:          name,
        status:        status,
        category:      category,
        fundingDetails: fundingDetails,
    }
}

接下来,告诉它切换到 Java。

列表 6.18 Copilot Chat 用惯用的 Java 重写了我们的 Asset 类。
class Asset {
    private int id;
    private String name;
    private String status;
    private String category;
    private FundingDetails fundingDetails;
    public Asset(String name, String status, String category, FundingDetails fundingDetails) {
        this.name = name;
        this.status = status;
        this.category = category;
        this.fundingDetails = fundingDetails;
    }

6.7 摘要

  • 单元测试:重点测试代码的单个组件或单元,以识别特定单元内的错误和问题。单元测试将是您代码库中数量最多的部分。
  • 集成测试:测试软件的不同组件或模块之间的交互,以确保无缝集成并检测通信问题。
  • 行为测试:从最终用户的角度测试系统的功能,确保其符合要求和规格。
  • 模拟对象:以受控的方式模拟自然对象的行为,对于测试和模拟错误条件非常有用。Mock 对象特别擅长模仿测试运行所需但不在测试范围内的系统的某些部分。例如,如果您的类有一个构造函数参数为数据库,但您不想直接测试数据库,因为数据可能会更改,导致您的测试无法得出结论、不可重复或不确定。
  • 圈复杂度:衡量软件模块独立路径的数量,表示复杂性和潜在漏洞。
  • Halstead 复杂度度量:根据独特的运算符和操作数评估软件复杂度,提供关于代码大小和认知复杂度的见解。
  • 可维护性指数:组合了圈复杂度、代码行数和 Halstead 度量等因素,评估软件的可维护性。
  • 代码覆盖率:用于评估测试效果的衡量标准,表示代码被测试的程度以及出现未捕获错误的潜力。通常情况下,覆盖率越高越好。
  • 语言熟悉度:需要在一个陌生的编程语言中导航代码或希望在当前语言中使用另一种语言的功能。


相关文章
|
4天前
|
人工智能 Python Shell
CodeFormer——AI驱动的面部图像修复与增强
CodeFormer是由南洋理工大学和商汤科技联合研发的AI人脸复原模型,结合VQGAN和Transformer技术,能从模糊或马赛克图像中生成清晰图像。它具备老照片修复、黑白照片彩色化、马赛克修复和低码率视频增强等功能。安装过程涉及miniconda3、Python环境配置、相关库的安装及模型训练数据下载。在测试视频增强时,虽然初期遇到ffmpeg导入问题,但通过安装ffmpeg-python得以解决,不过CPU占用率高。此外,还展示了对图片进行增强的命令行操作及结果示例。
|
4天前
|
机器学习/深度学习 人工智能 数据挖掘
AI技术对开发者职业天花板的双重影响
随着AI技术的不断创新和飞速发展,人工智能技术在软件开发、数据分析、自动化等领域的应用愈发广泛,并产生了深远的影响。尤其是在程序圈中,对于开发者这一职业群体而言,AI技术的融入不仅改变了传统的开发流程,还对开发者的职业前景带来了全新的挑战和机遇。那么本文就来简单聊聊AI技术究竟对开发者的职业天花板是提升还是降低呢?讨论一下AI技术如何影响开发者的职业天花板。
138 3
AI技术对开发者职业天花板的双重影响
|
10天前
|
机器学习/深度学习 人工智能 算法
关于AI技术,是 提高 or 降低 开发者的职业天花板
【6月更文挑战第5天】关于AI技术,是 提高 or 降低 开发者的职业天花板
|
11天前
|
人工智能 自然语言处理 算法
AI技术对开发者的职业天花板是提升还是降低?
AI技术对开发者的影响复杂多面,既提升也降低了职业天花板。一方面,AI提高开发效率,自动化重复工作,扩展了应用领域,促使开发者持续学习新技能。另一方面,它带来职业转型压力,技能可能过时,竞争加剧。开发者应持续学习,跨领域发展,培养创新思维,以适应和利用AI技术提升自身职业发展空间。
15 0
|
11天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的新时代:AI驱动的自动化
【6月更文挑战第4天】随着人工智能技术的不断进步,软件测试领域正经历着一场革命。本文将探讨AI如何改变传统的软件测试方法,提高测试效率和准确性,以及这一趋势对测试工程师未来技能要求的影响。
21 6
|
14天前
|
机器学习/深度学习 人工智能 算法
后端开发者如何利用AI进行跨学科融合
【6月更文挑战第1天】后端开发者如何利用AI进行跨学科融合
17 6
|
14天前
|
机器学习/深度学习 人工智能 安全
探索软件测试的新时代:AI驱动的测试自动化
本文深入探讨了人工智能(AI)如何革新软件测试领域,特别是测试自动化。随着AI技术的不断进步,它为测试自动化带来了前所未有的效率和准确性,从而极大地提高了软件开发的速度和质量。本文将详细介绍AI在软件测试中的应用,以及它如何帮助测试人员克服传统测试方法的局限性。
|
16天前
|
人工智能 自然语言处理 安全
构建未来:AI驱动的自适应网络安全防御系统提升软件测试效率:自动化与持续集成的实践之路
【5月更文挑战第30天】 在数字化时代,网络安全已成为维护信息完整性、保障用户隐私和企业持续运营的关键。传统的安全防御手段,如防火墙和入侵检测系统,面对日益复杂的网络攻击已显得力不从心。本文提出了一种基于人工智能(AI)技术的自适应网络安全防御系统,该系统能够实时分析网络流量,自动识别潜在威胁,并动态调整防御策略以应对未知攻击。通过深度学习算法和自然语言处理技术的结合,系统不仅能够提高检测速度和准确性,还能自主学习和适应新型攻击模式,从而显著提升网络安全防御的效率和智能化水平。 【5月更文挑战第30天】 在快速迭代的软件开发周期中,传统的手动测试方法已不再适应现代高效交付的要求。本文探讨了如
|
3天前
|
人工智能
当AI“复活”成为产业:确保数字生命技术始终用于正途的探讨
随着科技的飞速发展,AI技术日益成熟,我们迎来了一个令人瞩目的时代——当AI“复活”不再是科幻电影的情节,而是逐渐成为现实世界的产业,这其中就包括所谓的“数字生命”技术。在这一背景下,通过人物已有影像、声音、语言等内容的学习,克隆数字化的人物形象成为了可能,创造出数字化的“复活”形象。但是正如电影《流浪地球2》所展示的那样,图恒宇将女儿的意识上传到超强计算机,创造出拥有自我意识的数字图丫丫,这一技术奇迹引发了关于伦理、法律和社会责任的深刻探讨,所以说当AI“复活”技术逐渐从实验室走向产业化,我们不得不面对一个严峻的问题:如何确保这项技术始终用于正途?那么本文就来聊聊如何确保数字生命技术始终用于
14 1
当AI“复活”成为产业:确保数字生命技术始终用于正途的探讨
|
13小时前
|
数据采集 存储 人工智能
利用AI技术改善数字化转型项目的九种方法
利用AI技术改善数字化转型项目的九种方法