AI大模型的使用-让AI帮你写单元测试

这篇具有很好参考价值的文章主要介绍了AI大模型的使用-让AI帮你写单元测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.体验多步提示语

我们本节就让AI帮我们写一个单元测试,全程用AI给我们答案,首先单元测试前需要有代码,那么我们让AI给我们生成一个代码,要求如下:

用Python写一个函数,进行时间格式化输出,比如:
输入  输出
1  1s
61  1min1s
要求仅需要格式化到小时(?h?min?s),即可

假如AI给了我们这样一段代码,比如,输入 1 就返回 1s,输入 61 就返回 1min1s,代码如下:

def format_time(seconds):
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    if hours > 0:
        return f"{hours}h{minutes}min{seconds}s"
    elif minutes > 0:
        return f"{minutes}min{seconds}s"
    else:
        return f"{seconds}s"
print(format_time(1))

我们可以用单元测试一下下面代码,单元测试包采取pytest

!pip install pytest
import pytest

def test_format_time():
    assert format_time(1) == "1s"
    assert format_time(59) == "59s"
    assert format_time(60) == "1min0s"
    assert format_time(61) == "1min1s"
    assert format_time(3600) == "1h0min0s"
    assert format_time(3661) == "1h1min1s"

ok,没有问题,但是关注点放入这个单元测试,我们发现这个单元测试过于简单,很多边界情况或者容易出现异常的情况都没有测试到,如,没有包含异常情况以及类型不一致或者空情况的测试。

我们想让AI生成完美的单元测试就需要一步一步引导,让它理解代码是干什么的,才能进行单元测试的编写。

下面我们就给出代码让它解释出我们的代码是干嘛的,看解释的是否准确,代码比较简单,

1.定义代码变量code母的是将代码给到openAI让它解释这段代码,

2.定义prompt跟Ai说明需求,这里需求是“让它写单元测试,并用Python 3.10和pytest高级特性写代码出合适的单元测试代码验证有效性,写代码之前,先去了解作者的意图”将需求promot和代码传给 AI即可,

3.最后我们防止直接给出代测试代码(不完美的单元测试),我们需要用stop及时停止,让它只返回代码解释说明,看看它有没有理解。

#! pip install openai
import openai
openai.api_key='sk'
# 使用text-davinci-002模型,是一个通过监督学习微调的生成文本的模型。因为这里我们希望生成目标明确的文本的代码解释,所以选用了这个模型。
# openAI调用
def gpt35(prompt, model="text-davinci-002", temperature=0.4, max_tokens=1000, 
          top_p=1, stop=["\n\n", "\n\t\n", "\n    \n"]):
    response = openai.Completion.create(
        model=model,
        prompt = prompt,
        temperature = temperature,
        max_tokens = max_tokens,
        top_p = top_p,
        stop = stop
        )
    message = response["choices"][0]["text"]
    return message

# 代码
code = """
def format_time(seconds):
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)

    if hours > 0:
        return f"{hours}h{minutes}min{seconds}s"
    elif minutes > 0:
        return f"{minutes}min{seconds}s"
    else:
        return f"{seconds}s"
"""

# promot跟AI说明要做什么
def explain_code(function_to_test, unit_test_package="pytest"):
    prompt = f""""# How to write great unit tests with {unit_test_package}

In this advanced tutorial for experts, we'll use Python 3.10 and `{unit_test_package}` to write a suite of unit tests to verify the behavior of the following function.
```python
{function_to_test}


Before writing any unit tests, let's review what each element of the function is doing exactly and what the author's intentions may have been.
- First,"""
    response = gpt35(prompt)
    return response, prompt
# 在最后一行用 “- First” 开头,引导 GPT 模型,逐步分行描述要测试的代码干了什么。

# 封装调用
code_explaination, prompt_to_explain_code = explain_code(code)-
print(code_explaination)

结果:

the function `format_time` takes in a single parameter `seconds` which should be a `float` or an `int`.
- The function then uses `divmod` to calculate the number of `minutes` and `seconds` from the total number of `seconds`.
- Next, `divmod` is used again to calculate the number of `hours` and `minutes` from the total number of `minutes`.
- Finally, the function returns a `string` formatted according to the number of `hours`, `minutes`, and `seconds`.

接下来根据上面的反馈以及进一步的需求,让它帮忙写出一个简单的但是包含多种情况的单元测试例子,我们提出测试单元的需求,看看它能否给出可靠的全面的测试要求,代码如下,

# 要求如下
# 1.我们要求测试用例,尽量考虑输入的范围广一些。
# 2.我们要求 AI 想一些连代码作者没有想到过的边界条件。
# 3.我们希望 AI 能够利用好 pytest 这个测试包的特性。
# 4.希望测试用例清晰易读,测试的代码要干净。
# 5.我们要求测试代码的输出结果是确定的,要么通过,要么失败,不要有随机性。
def generate_a_test_plan(full_code_explaination, unit_test_package="pytest"):
    prompt_to_explain_a_plan = f"""
    
A good unit test suite should aim to:
- Test the function's behavior for a wide range of possible inputs
- Test edge cases that the author may not have foreseen
- Take advantage of the features of `{unit_test_package}` to make the tests easy to write and maintain
- Be easy to read and understand, with clean code and descriptive names
- Be deterministic, so that the tests always pass or fail in the same way

`{unit_test_package}` has many convenient features that make it easy to write and maintain unit tests. We'll use them to write unit tests for the function above.

For this particular function, we'll want our unit tests to handle the following diverse scenarios (and under each scenario, we include a few examples as sub-bullets):
-"""
    prompt = full_code_explaination + prompt_to_explain_a_plan
    response = gpt35(prompt)
    return response, prompt

test_plan, prompt_to_get_test_plan = generate_a_test_plan(prompt_to_explain_code + code_explaination)
print(test_plan)

结果:当然每次执行返回不一样,因为大模型的随机性。可以看到它能够考虑到异常情况,以及字符不符合会出现什么问题。

 Normal inputs
    - `format_time(0)` should return `"0s"`
    - `format_time(1)` should return `"1s"`
    - `format_time(59)` should return `"59s"`
    - `format_time(60)` should return `"1min0s"`
    - `format_time(61)` should return `"1min1s"`
    - `format_time(3599)` should return `"59min59s"`
    - `format_time(3600)` should return `"1h0min0s"`
    - `format_time(3601)` should return `"1h0min1s"`
    - `format_time(3660)` should return `"1h1min0s"`
    - `format_time(7199)` should return `"1h59min59s"`
    - `format_time(7200)` should return `"2h0min0s"`
- Invalid inputs
    - `format_time(None)` should raise a `TypeError`
    - `format_time("1")` should raise a `TypeError`
    - `format_time(-1)` should raise a `ValueError`

可以根据它提供的修改为可执行的单元测试:

import pytest

def test_format_time():
    assert format_time(0) == "0s"
    assert format_time(1) == "1s"
    assert format_time(59) == "59s"
    assert format_time(60) == "1min0s"
    assert format_time(61) == "1min1s"
    assert format_time(3600) == "1h0min0s"
    assert format_time(3661) == "1h1min1s"
    assert format_time(7200) == "2h0min0s"

    assert format_time(None) == "TypeError"
    assert format_time("1") == "TypeError"
    assert format_time(-1) == "ValueError"

没问题继续往下走,要是生成的测试计划数不满意,可以判断用例数是否小于指定的数,如果是那么就继续promot让其再生成按照如下的要求。

not_enough_test_plan = """The function is called with a valid number of seconds
    - `format_time(1)` should return `"1s"`
    - `format_time(59)` should return `"59s"`
    - `format_time(60)` should return `"1min"`
"""

approx_min_cases_to_cover = 7
# 上下文用例数是否小于指定数字
elaboration_needed = test_plan.count("\n-") +1 < approx_min_cases_to_cover 
# 是的话就提需求,在调用下AI
if elaboration_needed:
        prompt_to_elaborate_on_the_plan = f"""

In addition to the scenarios above, we'll also want to make sure we don't forget to test rare or unexpected edge cases (and under each edge case, we include a few examples as sub-bullets):
-"""
        more_test_plan, prompt_to_get_test_plan = generate_a_test_plan(prompt_to_explain_code + code_explaination + not_enough_test_plan + prompt_to_elaborate_on_the_plan)
        print(more_test_plan)

结果:

The function is called with a valid number of seconds
    - `format_time(1)` should return `"1s"`
    - `format_time(59)` should return `"59s"`
    - `format_time(60)` should return `"1min"`
- The function is called with an invalid number of seconds
    - `format_time(-1)` should raise a `ValueError`
    - `format_time("1")` should raise a `TypeError`
- The function is called with a valid number of minutes
    - `format_time(60)` should return `"1min"`
    - `format_time(119)` should return `"1min59s"`
- The function is called with an invalid number of minutes
    - `format_time(-1)` should raise a `ValueError`
    - `format_time("1")` should raise a `TypeError`
- The function is called with a valid number of hours
    - `format_time(3600)` should return `"1h"`
    - `format_time(7199)` should return `"1h59min"`
- The function is called with an invalid number of hours
    - `format_time(-1)` should raise a `ValueError`
    - `format_time("1")` should raise a `TypeError`

2.根据测试计划生成测试代码

我们根据上面给的需求以及AI给的答案拼装到新添加的prompt的给到AI,然后让它给我们一个测试单元代码

def generate_test_cases(function_to_test, unit_test_package="pytest"):
    
    # 将内容加载到prompt的{starter_comment}中
    starter_comment = "Below, each test case is represented by a tuple passed to the @pytest.mark.parametrize decorator"
    
    # prompt
    prompt_to_generate_the_unit_test = f"""
    Before going into the individual tests, let's first look at the complete suite                 of unit tests as a cohesive whole. We've added helpful comments to explain what      each line does.
   ```python
   import {unit_test_package}  # used for our unit tests

   {function_to_test}

   #{starter_comment}"""

    # 将所有的需求和ai给的结果拼接到prompt里,目的为了给的结果更准确
    full_unit_test_prompt = prompt_to_explain_code + code_explaination + test_plan + prompt_to_generate_the_unit_test
    return gpt35(model="text-davinci-003", prompt=full_unit_test_prompt, stop="```"), prompt_to_generate_the_unit_test

unit_test_response, prompt_to_generate_the_unit_test = generate_test_cases(code)
print(unit_test_response)

结果:可以拿过去直接执行

#The first element of the tuple is the name of the test case, and the second element is a dict
#containing the arguments to be passed to the function.
@pytest.mark.parametrize(
    "test_case_name, test_case_args",
    [
        ("positive_integer", {"seconds": 1}),
        ("positive_integer_60", {"seconds": 60}),
        ("positive_integer_3600", {"seconds": 3600}),
        ("positive_integer_3601", {"seconds": 3601}),
        ("negative_integer", {"seconds": -1}),
        ("negative_integer_60", {"seconds": -60}),
        ("negative_integer_3600", {"seconds": -3600}),
        ("negative_integer_3601", {"seconds": -3601}),
        ("float", {"seconds": 1.5}),
        ("float_60", {"seconds": 60.5}),
        ("float_3600", {"seconds": 3600.5}),
        ("string", {"seconds": "1"}),
        ("string_60", {"seconds": "60"}),
        ("string_3600", {"seconds": "3600"}),
        ("string_3601", {"seconds": "3601"}),
        ("decimal", {"seconds": Decimal("1")}),
        ("decimal_60", {"seconds": Decimal("60")}),
        ("decimal_3600", {"seconds": Decimal("3600")}),
        ("decimal_3601", {"seconds": Decimal("3601")}),
    ],
)
def test_format_time(test_case_name, test_case_args):
    # Here, we use the test case name to determine the expected output.
    # This allows us to DRY up our code and avoid repeating ourselves.
    if "positive_integer" in test_case_name:
        expected = f"{test_case_args['seconds']}s"
    elif "positive_integer_60" in test_case_name:
        expected = "1min"
    elif "positive_integer_3600" in test_case_name:
        expected = "1h"
    elif "positive_integer_3601" in test_case_name:
        expected = "1h0min1s"
    elif "negative_integer" in test_case_name:
        expected = f"-{test_case_args['seconds']}s"
    elif "negative_integer_60" in test_case_name:
        expected = "-1min"
    elif "negative_integer_3600" in test_case_name:
        expected = "-1h"
    elif "negative_integer_3601" in test_case_name:
        expected = "-1h0min1s"
    elif "float" in test_case_name:
        expected = f"{test_case_args['seconds']}s"
    elif "float_60" in test_case_name:
        expected = "1min0.5s"
    elif "float_3600" in test_case_name:
        expected = "1h0.5s"
    elif "string" in test_case_name:
        expected = f"{test_case_args['seconds']}s"
    elif "string_60" in test_case_name:
        expected = "1min"
    elif "string_3600" in test_case_name:
        expected = "1h"
    elif "string_3601" in test_case_name:
        expected = "1h0min1s"
    elif "decimal" in test_case_name:
        expected = f"{test_case_args['seconds']}s"
    elif "decimal_60" in test_case_name:
        expected = "1min"
    elif "decimal_3600" in test_case_name:
        expected = "1h"
    elif "decimal_3601" in test_case_name:
        expected = "1h0min1s"

    # Now that we have the expected output, we can call the function and assert that the output is

那么如果全程自动化的话,我并不知道是否给的代码是否是有语句错误等行为,所以我们可以借用AST 库进行语法检查。

3.通过AST 库进行语法检查

可以检测下AI生成的代码,用Python 的 AST 库来完成。代码也是很简单,我们找到代码片段,将代码传给ast.parse()进行校验,有问题则抛出异常

# 语义检查
import ast
# 找到代码的索引
code_start_index = prompt_to_generate_the_unit_test.find("```python\n") + len("```python\n")
# 找到prompt_to_generate_the_unit_test里从187到最后的内容,并拼接单元测试代码的内容
code_output = prompt_to_generate_the_unit_test[code_start_index:] + unit_test_response
print("code_output:",code_output)

# 进行语义检查
try:
    ast.parse(code_output)
except SyntaxError as e:
    print(f"Syntax error in generated code: {e}")

本节知识资料感谢徐文浩老师的《AI大模型之美》,让我感受它是真的美!文章来源地址https://www.toymoban.com/news/detail-678644.html

到了这里,关于AI大模型的使用-让AI帮你写单元测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • prompt提示词:影响力营销文案,让AI 帮你写营销文案

    1.我正在寻找一个有影响力的营销活动大纲,向我的[理想客户角色]展示我的[产品/服务],并说服他们在符合我们品牌价值的[有影响力的类型]的帮助下采取[期望的行动] 2.我需要一个有影响力的营销活动大纲,让我的[理想客户角色]与[有影响力的类型]的[特定类型的内容]互

    2024年04月27日
    浏览(41)
  • 一张网页截图,AI帮你写前端代码,前端窃喜,终于不用干体力活了

    简介 众所周知,作为一个前端开发来说,尤其是比较偏营销和页面频繁改版的项目,大部分的时间都在”套模板“,根本没有精力学习前端技术,那么这个项目可谓是让前端的小伙伴们看到了一丝丝的 曙光 。 将屏幕截图转换为代码(HTML/Tailwind CSS、React、Vue 或 Bootstrap)。它

    2024年04月29日
    浏览(44)
  • AI大模型【基础 01】智能AI开源模型与大模型接口整理(8个开源模型+7个大模型接口)

    数据主要来源于 【数据学习】的整理和汇总。 免费、本地部署安全性高 部分开源模型版本相对落后、硬件资源需求高、性能一般 技术门槛高、需要进行一定量的开发工作 更新维护成本较高 付费(按需收费)、非本地部署可能存在数据安全问题 模型较新、无需硬件资源、性

    2024年01月25日
    浏览(45)
  • Spring AI与大模型Ollama如何集成整合?

    Python 是进入人工智能领域(认为是机器学习或生成人工智能AIGC)的主要武器,Java 和 Spring 仍引领着大多数开发社区, Java 开发人员如何与 LLM大模型 一起工作?这就是 Spring AI 弥补差距的地方。 Spring AI在 Spring 应用程序和可以在本地运行的 LLM 之间创建集成,这为所有 Java 开

    2024年04月25日
    浏览(38)
  • AI大模型应用入门实战与进阶:图像识别与大模型:ViT解析

    随着深度学习技术的不断发展,大模型在图像识别领域取得了显著的成功。ViT(Vision Transformer)是Google Brain团队2020年推出的一种新颖的图像识别方法,它将传统的卷积神经网络(CNN)替换为Transformer架构,实现了在图像识别任务中的显著性能提升。 本文将从以下几个方面进行深入

    2024年02月20日
    浏览(49)
  • 大模型开发(一):GPT、ChatGPT与大模型,一次搞懂这些AI概念

    全文共5000余字,预计阅读时间约10~20分钟 | 满满干货,建议收藏! 本文目标:详细解释大型语言模型(LLM)和OpenAI的GPT系列的基本概念。 大型语言模型,也称大语言模型、大模型(Large Language Model,LLM;Large Language Models,LLMs) 。 大语言模型是一种深度学习模型,特别是属于

    2024年02月14日
    浏览(37)
  • 学习笔记|大模型优质Prompt开发与应用课(二)|第四节:大模型帮你写代码,小白也能做程序

    GT│飞桨开发者技术专家 研发资源持续投入是企业为了获取核心技术.提升竞争力而进行的必要投资,同时也是企业实现长期发展、保持核心竞争力的关键因素。 在大型企业当中,人力成本占研发投入通常超50%,互联网头部企业研发薪资通常在20k以上,可以看到技术性人才非

    2024年02月15日
    浏览(55)
  • 百度侯震宇:AI原生与大模型将从三个层面重构云计算

    12月20日,2023百度云智大会·智算大会在北京举办,大会以「大模型重构云计算,Cloud for AI」为主题,深度聚焦大模型引发的云计算变革。   百度智能云表示,为满足大模型落地需求,正在基于「云智一体」战略重构云计算服务,目前已完成从底层基础设施—大模型开发与应

    2024年02月04日
    浏览(52)
  • 共探AI大模型时代下的挑战与机遇,华为云HCDE与大模型专家面对面

    摘要: 近日,华为开发者大会2023(cloud)“开发者生态创新发展圆桌会议”在东莞华为溪流背坡村成功举办。 2023年7月8日,华为开发者大会2023(cloud)“开发者生态创新发展圆桌会议”在东莞华为溪流背坡村成功举办。以大模型为代表的的新一轮人工智能技术浪潮汹涌而来

    2024年02月13日
    浏览(69)
  • AI与大数据的结合(个人理解)

    随着互联网技术和计算机技术的发展,数据已经成为了当今社会的一种重要的资源。特别是在过去几年中,大数据技术的快速发展,让我们看到了数据对于社会和产业的重要性。而人工智能(AI)作为一项基于数据的技术,与大数据的结合更是让人们看到了前所未有的机遇和

    2024年02月08日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包