乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 176|回复: 7

让我们开始一个更深入的讨论,教人们(像我一样)如何应用TDD

[复制链接]

3

主题

10

帖子

1

银币

初来乍到

Rank: 1

铜币
22
发表于 2021-11-12 10:40:13 | 显示全部楼层 |阅读模式
我不是唯一一个看到或张贴论坛帖子寻求自动测试插件帮助的人。无论是单元测试还是集成测试,当开发AutoCAD的. NET插件时,期望的结果仍然是应用TDD的愿望。作为一个发表过这些帖子的人,我觉得它来自一个软件开发新手的地方,他不知道从哪里开始使用TDD。然后发现依赖AutoCAD运行测试有一层额外的困难。
现在,我已经阅读了Scott MacFarlane的《AutoCAD自动化测试》。NET API
https://forums . Autodesk . com/Autodesk/attachments/Autodesk/152/51134/1/讲义_ 2654 _ CP 2654 _ Automated _ testing . docx
虽然它很有帮助,但它也非常过时,依赖于Gallio,它似乎已经有一段时间没有更新了。
我还开始在自己的项目中使用CAD block的CADTest项目来测试
https://github . com/CAD block/CAD test
这是一个很棒的工具,尽管我在使用它时遇到过几次困难。但它只是一个工具,在一个没有经验的开发者手中只能做这么多。
我通常用例子来思考,所以我将使用一个我认为可能是很好的演示的个人例子。值得庆幸的是,这个工具已经开发出来了,但我现在在维护它:
假设我们想要一个工具来排列线条,以表示平面图上的托梁。该工具要求输入一条闭合多段线,然后输入托梁间距和托梁的方向(即EW或NS)。我可以看到手动运行一个测试,在那里我准备好了一条闭合折线,我输入我知道我要测试的间距和我要测试的方向,然后可以直观地检查它是否工作。但是如何通过自动化来实现呢?
我可以记录闭合折线的句柄,然后运行一个测试,将它输入到工具中,并对其他信息进行同样的操作。但是,如果不进行目视检查,我如何验证它的工作情况呢?
我认为这只是许多人试图克服困难的一个例子。我看到很多帖子,人们问如何对他们的插件进行单元测试,他们要么说这不太可行,要么只是简单地链接我已经提供的上面的一个链接。
我想我只是希望创建一个地方,让人们在谷歌“AutoCAD单元测试”时有希望得到一些答案。
感谢任何帮助,并阅读我的咆哮!

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

61

主题

792

帖子

35

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1015
发表于 2021-11-12 12:57:25 | 显示全部楼层
函数返回类型与测试有很大关系,所以你的单元测试本质上就是测试1 = 1。
在该文档的开始设置中,作者提到了他们所谓的“代码隔离”,这是正确的,但比他们演示的要复杂一些。
第7页的代码开始讨论构建“隔离代码”的任务,但作者并没有完全理解这个概念(在我看来,这是一个非常糟糕的例子,但我们现在就用它吧)。
这是文档中的例程。
  1. private void SetCircleColor(Circle circle) {
  2.         if (circle.Radius  10.0) {
  3.                 circle.ColorIndex = 1;
  4.         } else {
  5.                 circle.ColorIndex = 3;
  6.         }
  7. }

要进行测试,您需要在构建例程时记住返回类型,因为尝试对一堆空白进行单元测试实际上是不可能的/有用的,所以您应该像这样构建“孤立的”例程:
  1. public int drawcircle()...
  2. public int getcircle()...
  3. public int setcirclecolor()...

一个更好的例子是可以用几行代码编写的简单内容。
  1. public int square(int a){
  2.         return a*a;
  3. }
  4. public int add(int a, int b){
  5.         return a+b;
  6. }

您的测试应该是这样的:
  1. assert.isequal(square(2), 4);
  2. assert.isequal(add(1, 2) 3);
  3. ...

如您所见,这使得事情很容易跟踪。
我用C语言测试的代码非常简单(过分),但是完成了任务。
https://jera . com/tech info/jtns/jtn 002
这是一个更强大的版本,演示了自动化的过程。这实质上只是“返回类型”检查的扩展。如果您查看下面的示例文件“minunit_example.c ”,您应该能够看到MAIN将返回一个int。如果你查看“CI”文件夹,你会看到一个bat文件只是运行“minunit_example”并检查是否返回了一个传递的int。
https://github . com/siu/min unit
显然,随着您的运营变得更加复杂,您的回报也会变得更加复杂。也就是说,你开始为好的返回1,为坏的或其他类型的错误代码返回0,但是原则是成立的;在很大程度上,你需要对照预期结果来检查你的函数返回。
有些测试总是需要一些人工交互。例如,我正在构建一个“广度优先目录横向”的东西,我真的不能为此构建一个测试,所以我只是用一些样本文件构建了一个样本目录,并运行一个“测试程序”来查看目录是否以正确的顺序打印出来。它既不是自动化的,也不是精心制作的(只是一个把东西打印到命令行的程序),但是我真的不能为此建立一个验证。
回复

使用道具 举报

3

主题

10

帖子

1

银币

初来乍到

Rank: 1

铜币
22
发表于 2021-11-12 13:57:15 | 显示全部楼层

感谢您的回复,这是非常有用的信息。我没有过多地考虑返回类型,因为我认为如果某个东西有效,它就会有效,如果无效,它就会抛出一个错误。但我现在明白这可能过于简单了。我在工作,所以我不能完全考虑你的回复的含义,但我想到的第一件事是尝试与我的原始帖子联系起来,让放置“托梁”线的函数返回它绘制的线的数量。这可以根据给定的已知折线进行测试。
或者更好的方法是在测试期间传入一个新的rectangle对象,因为已知矩形的尺寸,所以将放置已知数量的“托梁”。
回复

使用道具 举报

61

主题

792

帖子

35

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1015
发表于 2021-11-12 14:26:48 | 显示全部楼层
我们正在讨论基础知识;对象测试有点复杂(MSDN有这方面的文档和教程)。但对于这一部分,您需要更好地了解回报。是的,你开始重新思考如何更好地开发你的例程是正确的(这是目标;重新思考你的程序的结构),创建一些行是一个伟大的步骤。或者,您可能还想尝试在成功时返回 1,在失败时返回 0。
Visual Studio,Microsoft,C#,Java等确实使整个测试过程复杂化,这并不一定是坏事,只是不同。在C#或Visual Studio中需要做的很多事情都会导致语言或工具努力简化编码体验(有点像“割掉鼻子以面对自己的脸”之类的事情)。-即,使用MSTest Unit测试方法的使用方式与我上面描述的不同,因为您将[TEST]方法添加到代码中,而不是像上面示例那样构建实际的测试文件。
但是,所有这些最终将导致您在函数设计中使用“断言”,“尝试”等路径。我一直坚持更传统的路线 - 即我现在每天用C / C++编程,我在文本编辑器中键入源代码,然后将这些文件发送到编译器。因此,当我处理一个函数或一系列函数时,我大部分时间都花在开发代码头(名称,描述,返回)上,然后是实际代码。这最终成为代码的规范。这种方法使我成为异端,大多数人做MSTest单元测试方法并将[TEST]方法添加到他们的代码中(这对我来说似乎更像是事后的想法),但我至少可以引导你进入这个兔子洞主题的正确洞。
回复

使用道具 举报

61

主题

792

帖子

35

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1015
发表于 2021-11-12 14:53:51 | 显示全部楼层
链接发布时间...
传统单元测试的基础知识本质上是函数返回,从而验证函数是否返回正确的数字,但在较新的代码设计中,这很快就会变得混乱!旧方法产生了这样的代码结构:
  1. if (!drawcircle()) {
  2.         // oops! get out now!
  3.         return;
  4. }

,但现在我们有一个新方法(微软做它最擅长的事情;改变东西)叫做“AAA方法模式的东西”,看起来更像:
  1. try{
  2.         drawcircle()
  3. } catch (system.overheat) {
  4.         assert.contains("some thing");
  5. }

这是一个指向MSDN教程的链接。
https://docs.microsoft.com/en-us/visualstudio/test/walkthrough-creating-and-running-unit-tests-for-managed-code?view=vs-2022
回复

使用道具 举报

3

主题

10

帖子

1

银币

初来乍到

Rank: 1

铜币
22
发表于 2021-11-12 15:19:31 | 显示全部楼层
因此,如果我在下面,您所描述的是两种不同的单元测试方法。人们或多或少地想知道在设计方法签名时他们打算使用哪种方法。不过,这两种方法都假设您正在为测试创建一个单独的文件/类。这个类可以说是实例化该类或使用被测方法的内容,并且可以记录旧方法的返回(比如零),或者记录在某种类型的尝试捕获中捕获的异常。
我在使用CADTest时有一些使用断言的经验,通过在测试中实例化一个类,并向构造函数提供某些输入,然后使用断言测试实例化对象的状态。
回复

使用道具 举报

61

主题

792

帖子

35

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1015
发表于 2021-11-12 15:48:34 | 显示全部楼层
如果您只使用基于AutoCAD的实用程序,您将使用MSTest单元测试方法,但一般来说,只编写“private void”类型的例程可以看出您有多马虎(在我看来)。如果您正在编写一个很好的银行注册例程(如MS教程),我认为您可以通过使用更传统的测试方法来获得
例如,给定以下函数:
  1. public void Withdraw(double amount) {
  2.     if(m_balance >= amount) {
  3.         m_balance -= amount;
  4.     } else {
  5.         throw new ArgumentException(nameof(amount), "Withdrawal exceeds balance!");
  6.     }
  7. }

在我看来,以下测试是在浪费每个人的时间。花时间设计一个有地板和天花板的好功能,比如“撤回”功能,你不需要测试
  1. [TestMethod]
  2. public void Withdraw_AmountMoreThanBalance_Throws()
  3. {
  4.     // arrange
  5.     var account = new CheckingAccount("John Doe", 10.0);
  6.     // act and assert
  7.     Assert.ThrowsException(() => account.Withdraw(20.0));
  8. }

如果我编写了“提取”函数,我会让它返回经常账户余额(一个盲函数调用/返回除了抛出异常之外没有其他好处),并在主调用函数中处理-也就是说,我不会让异常一开始就发生。不同的学派。
回复

使用道具 举报

3

主题

10

帖子

1

银币

初来乍到

Rank: 1

铜币
22
发表于 2021-11-12 16:32:42 | 显示全部楼层
这是一个很好的细分和例子。在考虑测试时,我也有这种感觉。在 AutoDesk 大学的讲义中,当您编写已知会失败的测试时,他们会解释 TDD,然后编写代码以使其通过,并且在编写测试之前不要编写任何代码。那么在这种情况下,你怎么能开始编写一个类来容纳你想要的函数作为我的托梁示例。然后,如果你确实写了一个因为该类不存在而失败的测试,那么你让它通过现有的类,这又有什么用呢?
所以我喜欢你编写一个返回有用东西的函数的思维方式,它是调用函数的责任来处理它返回的内容。我们如何将其应用于AutoCAD测试?
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-4 03:45 , Processed in 0.233326 second(s), 68 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表