gpt4 book ai didi

c# - 从单元测试自动生成类?

转载 作者:IT王子 更新时间:2023-10-29 04:44:54 28 4
gpt4 key购买 nike

我正在寻找可以进行单元测试的工具,例如

IPerson p = new Person();
p.Name = "Sklivvz";
Assert.AreEqual("Sklivvz", p.Name);

并自动生成相应的存根类和接口(interface)
interface IPerson         // inferred from IPerson p = new Person();
{
string Name
{
get; // inferred from Assert.AreEqual("Sklivvz", p.Name);
set; // inferred from p.Name = "Sklivvz";
}
}

class Person: IPerson // inferred from IPerson p = new Person();
{
private string name; // inferred from p.Name = "Sklivvz";

public string Name // inferred from p.Name = "Sklivvz";
{
get
{
return name; // inferred from Assert.AreEqual("Sklivvz", p.Name);
}
set
{
name = value; // inferred from p.Name = "Sklivvz";
}
}

public Person() // inferred from IPerson p = new Person();
{
}
}

我知道ReSharper和Visual Studio会执行其中的一些操作,但是我需要一个完整的工具(命令行或其他工具)来自动推断需要完成的工作。
如果没有这样的工具,您将如何编写(例如,使用哪些库从头开始扩展ReSharper)?

最佳答案

您似乎需要的是一种针对您的语言(Java)的解析器,以及一个名称和类型解析器。 (“符号表生成器”)。

解析源文本之后,编译器通常具有一个名称解析器和一个类型检查器,名称解析器尝试记录名称及其对应类型的定义,该类型检查器验证每个表达式是否具有有效的类型。

通常,名称/类型解析器在找不到定义时会提示。您要执行的操作是找到导致问题的“未定义”内容,并为其推断类型。

为了

 IPerson p = new Person();

名称解析器知道未定义“Person”和“IPerson”。如果是
 Foo  p =  new Bar();

没有任何线索表明您需要接口(interface),只是Foo是Bar的某种抽象父级(例如,类或接口(interface))。因此,工具必须知道该决定是什么(“只要找到这样的构造,就假定Foo是接口(interface)...”)。您可以使用试探法:IFoo和Foo表示IFoo应该是一个接口(interface),并且在某些地方必须将Foo定义为实现该接口(interface)的类。一旦
工具已做出此决定,则需要更新其符号表,以便可以
继续其他陈述:

为了
 p.Name = "Sklivvz";

假定p必须是一个接口(interface)(根据前面的推论),那么Name必须是一个字段成员,并且从赋值中来看,其类型为String。

这样,语句:
 Assert.AreEqual("Sklivvz", p.Name);

名称和类型无需进一步解决即可解决。

IFoo和Foo实体的内容取决于您自己;您不必使用get和set,但这是个人喜好。

当您在同一条语句中有多个实体时,这将无法很好地工作:
 x = p.a + p.b ;

我们知道a和b可能是字段,但是如果它们确实是数字,或者它们是字符串,则无法猜测是哪种数字类型(这对于Java中的字符串是合法的,关于C#而言是不合法的)。
对于C++,您甚至都不知道“+”是什么意思。它可能是Bar类的运算符。
因此,您要做的就是收集约束,例如“a是某个不确定的数字或字符串”等,并且当该工具收集证据时,它会缩小可能的约束的范围。 (这就像那些单词问题一样起作用:“乔有七个儿子。杰夫比山姆高。哈利不能躲在萨姆后面。...杰夫的双胞胎是谁?”,您必须收集证据并消除可能性。)您还必须担心最终会出现矛盾的情况。

您可以排除p.a + p.b的情况,但是这样就不能不受惩罚地编写单元测试。如果您想不受惩罚,可以使用标准约束求解器。 (什么概念)。

好的,我们有了想法,现在可以以实际的方式做到吗?

这的第一部分需要一个解析器和一个可弯曲的名称和类型解析器。您需要一个约束求解器或至少一个“定义的值流到未定义的值”操作(平凡的约束求解器)。

我们的 DMS Software Reengineering Toolkit及其 Java Front End可以做到这一点。 DMS是工具构建器的工具,适用于希望构建以任意方式处理计算机语言的工具的人员。 (考虑“用程序片段而不是数字进行计算”)。

DMS提供了通用的解析机制,并且可以为所提供的任何前端(例如Java和C#前端)构建一棵树。
我选择Java的原因是我们的Java前端具有所有名称和类型解析机制,并且以源代码形式提供,因此可以弯曲。如果坚持使用琐碎的约束求解器,则可能会弯曲Java名称解析器以找出类型。 DMS使您可以组装与代码片段相对应的树,并将它们合并为更大的树;当您的工具为符号表收集事实时,它可以构建原始树。

在某个地方,您必须确定已完成。该工具必须查看多少个单元测试
才知道整个界面? (我想它会吃掉您提供的所有食物?)。
完成后,它将为各个成员组装片段,并为接口(interface)构建AST。 DMS可以使用其prettyprinter将AST转换回您所显示的源代码。

我在这里建议使用Java,因为我们的Java前端具有名称和类型解析。我们的C#前端没有。这只是一个雄心壮志。有人必须写一个,但这需要做很多工作(至少是针对Java的,我无法想象C#确实有所不同)。

但是这个想法原则上使用DMS可以很好地工作。

您可以使用其他一些基础结构来执行此操作,这些基础结构使您可以访问解析器以及可更改的名称和类型解析器。对于C#来说,这可能并不容易。我怀疑MS可能会为您提供解析器,并提供名称和类型解析的访问权限,但没有任何更改方式。也许Mono是答案?

您仍然需要一个was来生成代码片段并将其汇编。您可以尝试通过字符串黑客来做到这一点;我将程序位粘合在一起的(长期)经验是,如果使用字符串进行操作,最终会造成困惑。您确实想要代表已知类型的代码片段的片段,这些片段只能以语法允许的方式进行组合;因此,DMS不会造成困惑。

关于c# - 从单元测试自动生成类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/91617/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com