65.9K
CodeProject 正在变化。 阅读更多。
Home

展望未来 - 机器人源代码生成

starIconstarIconstarIconstarIconstarIcon

5.00/5 (33投票s)

2016年11月22日

MIT

15分钟阅读

viewsIcon

88180

downloadIcon

2722

通过两个简单的例子,展望了编写程序的机器人的前景。

运行代码前,请阅读“代码使用”

引言

软件开发技术不断发展,以满足日益增长的需求以及硬件和方法论的能力。自动化在软件开发中扮演着越来越重要的角色,以简化人工劳动。软件开发自动化的一些例子包括代码构建管理器、静态代码分析器、测试系统等。

另一方面,人工智能和机器人领域的研究也取得了显著进展。名为“机器人”的软件家族正在迅速增长。机器人实现预定义逻辑,其能力几乎仅受硬件限制。现代软件开发技术可以用于构建可以执行软件开发任务的机器人。

本文描述了创建软件开发机器人的通用概念,并试图从现代软件开发方法的角度展示这一概念。描述中附带了两个演示该想法的实际示例。

本文旨在启发读者学习现代编程技术并将其应用于实际生活。通过本文,作者只是展示了他的一些小想法,并希望读者通过提供反馈来帮助他改进文章。

如何阅读本文

为了方便读者,应注意文章的两个主要关键部分:

因此,想要通过运行示例来了解机器人如何工作的读者,可以先阅读“机器人”章节。读者也可以查看“目录”章节,找到他/她想要的章节。

缩写

ATDCG 自动化测试驱动代码生成
SDB 软件开发机器人
TDCG 测试驱动代码生成
TDD 测试驱动开发

目录

想法

软件开发演进

启发作者研究 SDB 领域最初的问题是“软件开发技术是如何发展的?”。理解软件开发技术演进的趋势很重要,因为这些知识有助于构建未来的愿景。之前的编程范例(编程技术)可以简要描述为以下几个阶段:

  1. 命令序列。编程时代的早期,硬件弱小,单个程序员开发单个程序。程序以非结构化的方式连续开发。
  2. 结构化编程。要解决的问题范围不断扩大,需要增加编程代码量并更好地管理它。代码被组合成块结构。
  3. 面向对象编程。代码块结构不断增长,最终被组合成一种名为“对象”的新结构。代码块之间的关系数量和复杂性也在增加。引入了特有于对象的新的关系类型(封装、继承、多态、访问级别等)。编程模型反映了复杂系统的特性,其中不同的独立单元具有状态,并且能够在同一个通用环境中执行特定操作,从而接近现实生活中的行为体和过程。

问题是:下一步是什么?编程方法在朝着什么方向发展?

简化的 TDD 流程

TDD 是一种发展的开发方法,它结合了先写测试后开发或重构生产代码的开发方式。TDD 不仅仅是一种简单的编程技术,它既是重要的敏捷需求,也是敏捷设计技术。TDD 的目标是编写可工作的整洁代码。

TDD 是解释文章主旨的便捷方式。以 TDD 为基础进行后续解释,为描述 TDCG 的方法论提供了一条清晰的路径。

完整的 TDD 流程包含代码重构的阶段,测试保证代码的正确运行。如果只需要创建新代码,而不需要重构,TDD 流程可以简化。考虑的简化 TDD 流程可以包含以下阶段:先创建测试,开发软件单元,并可能重复开发任务直到代码通过测试阶段。

下图展示了可能的简化 TDD 流程。

Test Driven Development

几乎所有信息来源在描述 TDD 任务时都强调某些过程可以自动化,从而减少人工工作。有一点很重要,需要强调。自动化任务由经过验证的算法运行,并且是稳定的,而手动执行的任务可能会引入错误。换句话说,测试和软件的开发者对其工作质量负责。因此,从责任的角度来描述考虑的简化 TDD 过程的主要任务:

  • 创建测试——这是影响整个开发软件单元质量的关键任务。
  • 运行测试——这是一个经过验证的自动过程,本身不会引入错误(实践中/我们假设它)。
  • 软件开发——由程序员执行,但测试保证了他/她工作质量,从而减轻了程序员对其工作的责任。

尽管文章考虑了减轻程序员对其工作的责任,但这意味着工作质量仅由测试保证。代码可读性、开发时间、代码性能等其他质量指标在本篇文章中为了保持解释的简单性而未予考虑。

测试驱动代码生成

Raphael Marvie 在其文章“测试驱动代码生成介绍”[Marvie. 2006] 中描述了测试驱动代码生成 (TDCG) 技术。他在 TDD 流程的上下文中描述了 TDCG。

本文将自动代码生成视为一项独立的技术,而不是 TDD 的一部分。但是,所考虑的技术与 TDD 和其他信息技术有着密切的关系。由于所考虑的自动代码生成也是基于先前编写的测试,因此可以称之为自动化测试驱动代码生成 ATDCG。

上述推理表明,在 TDD 中只有运行测试是自动化的,而创建测试和开发软件是手动任务(严格来说,这些任务可以/部分自动化,但并非完全自动化)。由于软件开发任务的质量(通过测试)是自动控制的,因此开发也可以完全自动化。

人类的角色可以仅限于创建测试。从业务角度来看,这意味着人类将为软件单元创建和描述需求,然后根据这些需求自动创建单元。

因此,自动软件开发可以看作是上面考虑的简化 TDD 流程的演进。

Test Driven Development / 2 Components

自动化测试

经典的自动化软件测试方法有一个称为“代码覆盖率”的特性。代码覆盖率是衡量特定测试套件运行时程序源代码被执行程度的指标。代码覆盖率值低表示存在未自动测试的代码。

ATDCG 技术可以创建完全由测试覆盖的代码,因为代码是从头开始创建的。换句话说,它具有 100% 的代码覆盖率。因此,如果代码覆盖率是经典测试方法的良好指标,那么它不能用于衡量 ATDCG 的成功。

需要引入一个新的指标来衡量测试对实际业务问题的覆盖程度。这一事实将衡量成功的重点从软件开发领域转移到了系统/业务分析。

为了保持阅读的简洁性并更密切地关注主题,本文将不讨论此度量。但需要强调的是,存在需要进一步研究的问题。

测试在 ATDCG 中的作用

在 ATDCG 中,创建测试是唯一的手动任务。测试是自动软件单元创建过程的主要驱动力,同时保证了过程的质量。因此,ATDCG 中的测试具有以下特性:

  • 整个 ATDCG 过程和结果质量取决于测试的创建方式
  • 创建测试是 ATDCG 中主要且敏感的任务
  • 创建测试与业务需求的关系更密切,与创建软件代码的关系比经典方法更远
  • 存在进行研究和开发 ATDCG 测试创建方法和规则的需求

机器学习

如前所述,ATDCG 开发的单元质量完全取决于测试。创建测试反过来在很大程度上与业务需求相关,而不是与编程相关。最有可能的是,测试将包含大量规则。从另一个角度来看,测试将以声明式的方式描述,并包含或引用大量数据。

由于测试创建过程与业务需求相关,因此这些数据应具有足够高的抽象级别,以便测试创建者能够方便地根据业务需求设计测试。与经典的测试方法相比,高抽象级别和大量的测试设计数据将导致复杂性增加。

因此,ATDCG 的测试创建和运行可以描述为:

  • 以声明式形式创建测试,并考虑真实物理数据的数量(例如,业务流程的索引)
  • 将创建的测试或其中的一部分作为自动创建软件单元的训练数据

这些观察表明 ATDCG 与监督机器学习有很强的关联。因此,监督机器学习的理论和技术可以用于 ATDCG。

社会影响

ATDCG 假设软件开发任务的自动化,让程序员从这个角色中解脱出来。同时,分析师和测试创建者的角色成为成功运行 ATDCG 的关键。但 ATDCG 需要自身的发展。此外,ATDCG 的发展显然会满足 Unix 编程的两条规则[Raymond. 2003]:

  • 经济原则:程序员的时间是宝贵的;宁愿节省程序员时间,也不要浪费机器时间
  • 生成原则:避免手工编写;在可能的情况下,编写程序来编写程序

因此,ATDCG 可以被视为一项开启额外机会的软件开发技术,而不是限制或颠覆。同时,它也为该领域未来的研究提供了机会和需求。

机器人

机器人是“软件机器人”(维基百科)。本节将介绍两个 SDB 的创建。

  • 机器人 1——一个演示 SDB 关键概念的最简单示例。此机器人的性能无法在合理时间内获得实际结果。
  • 机器人 2——性能改进的机器人,可在 5-10 分钟内产生结果(Intel I7 CPU)。

问题

本文力求以尽可能简单的方式解释该技术的一般概念。在此背景下,最小的软件单元可以只是一个用高级语言写成一行代码的简单函数。

这两个示例的目的是基于训练数据,在 C# 语言中创建一个 \(f(a,b)\) 类型的简单函数。测试将检查函数在每种情况下的输入输出值的等价性。

训练数据

输入参数(\((a)\)\((b)\))和输出值(\((f)\))如下表所示:

(a) (b) (f)
38 2 1463
4 11 80
51 7 2645
12 32 313
6 21 150
20 38 599
25 43 849
3 19 113
40 34 1779

实际上,这些数据是使用多项式函数 \(f = a^2 + 5b + 9\) 构建的。这个事实使得我们可以检查创建的 SDB 的正确操作。在现实世界中,目标函数和测试很可能未知,并且可能非常复杂。

机器人应该找到与上述多项式相等的函数。但结果可以是其各项的任何组合。请参阅“结果”章节,查看机器人发现的实现了训练数据计算的几个函数。

机器人 1

如上所述,机器人 1 是演示 SDB 关键概念的最简单示例。此机器人的性能无法在合理时间内获得实际结果。但代码是所有可能解决方案中最简单的。

该机器人创建一个 C# 语言的 \(f(a,b)\) 类型函数,其外观如下代码片段:

namespace Program
{
    public class WorkingClass
    {
        public static int F(int a, int b)
        {
            return XXXXXXXXXXXXXXXX;
        }
    }
}

此代码片段包含在标记为 XXXXXXXXXXXXXXXX 的位置实现函数公式的代码包含。机器人应该找到这行代码。所有其他文本都是已知的,并构成一个可以编译成库的完整 C# 程序。

代码包含由包含四种算术运算(-, +, *, /)、两个变量(ab)以及九个数字(1, 2, 3, 4, 5, 6, 7, 8, 9)的字母表构成。

机器人实现的算法也很简单:

  • 步骤 1。通过将从字母表中随机选择的符号插入 XXXXXXXXXXXXXXXX 位置来构建代码。
  • 步骤 2。将代码编译到 RAM。如果编译失败,请转到步骤 1。
  • 步骤 3。对训练数据集运行函数。
  • 步骤 4。比较实际函数输出和训练数据集的结果。如果任何情况下的值不同,请转到步骤 1。
  • 步骤 5。打印找到的函数。

该算法使用 C#、反射和动态代码生成来实现。

性能

简单算法的性能极其低下。来自字母表的符号的不同组合数量约为 4100 万(如果我们使用 4 种运算和 5 个变量)。简单的迭代需要巨大的计算量。如此大量的迭代无法在合理的时间内用现代个人计算机完成。作者通过运行 4 个机器人实例在 Intel I7 4 核 CPU 上花费 10 天时间找到了一种解决方案。

尽管机器人 1 的性能极差,但其源代码非常简单。源代码未包含在文章中,但可以下载(参见“代码使用”章节)。代码相当简单且有注释,作者希望它足够易读,能理解其工作原理。

机器人 2

机器人 1 可用于理解最简单的自动创建软件代码算法并学习所需的编程语言命令。但它不方便用于查看结果。作者包含了一个改进版本的同一机器人,并将其命名为机器人 2,以便在合理的时间内获得结果。

机器人 2 实现遗传算法,显著减少了查找解决方案的时间。它可以在 Intel I7 CPU 上运行一个线程,在 5-20 分钟内获得结果。机器人 2 是用稍微复杂一些的代码编写的。但代码也有注释,应该不难理解。

结果

下面几张图片展示了机器人 2 生成的几个结果。读者可以注意生成的 C# 代码和运行时间。读者可以下载源代码并自己运行示例(参见“代码使用”章节)。

机器人可以轻松升级,直接将创建的代码写入 *.cs 文件,甚至创建 Visual Studio 项目结构。作者为了保持源代码的简洁性而没有进行这样的升级。

Results 1
Results 2
Results 3
Results 4
Results 5

未来发展

本文展示了创建 SDB 的可能性。但目前还不能在实践中使用。它可以从相关技术中受益并从中获益,例如机器学习、数据挖掘、TDD、自动代码生成等。

ATDCG 的未来发展可以借鉴构建编译器和代码分析器的经验。成熟的机器人可以在不使用高级语言和编译阶段的情况下创建软件单元。它们可以创建由 Microsoft 中间语言(二进制表示)命令或 Java 字节码组成的单元。这可以显著加快代码生成过程。

目前,ATDCG 方法可以由爱好者研究和开发。也应该对此事进行研究。理论研究将为理解 ATDCG 的好处以及如何实际实现它们奠定基础。

Using the Code

代码包含机器人 1 和机器人 2,它们是在以下环境中创建和运行的:

  • 开发:Microsoft Visual Studio Community 2015
  • 编译:Microsoft .NET Framework 4.5,Any CPU
  • 平台:Microsoft Windows 8.1,64 位,CPU:Intel I7

读者可以在文章顶部或此处下载示例:

两个示例运行时都使用一个线程。可以同时运行多个实例,但这会将 CPU 置于最大功耗模式。这种负载可能会导致计算机过热,如果它未设计用于长时间进行密集 CPU 计算。机器人 2 很快就能产生结果,不应对硬件造成过载。但作者不建议长时间运行多个机器人 1 实例。

参考文献

  • [Marvie. 2006] R. Marvie. An Introduction to Test-Driven Code Generation. EuroPython 2006。
  • [Raymond. 2003] E. S. Raymond. The Art of Unix Programming. Addison-Wesley, 2003。

历史

  • 2018年12月15日:在“简化的 TDD 流程”章节中,更改了展示可能的简化 TDD 流程图的图片(感谢 @ciroBorrelli
  • 2016年11月22日:首次发布
© . All rights reserved.