`
zhang_xzhi_xjtu
  • 浏览: 536590 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使用反射提高单元测试的质量

阅读更多
首先,单元测试以及单元测试覆盖率只是一个工具,很烂的代码一样可以有全套的单元测试和很高的单元测试覆盖率(这里只指代码覆盖率,不涉及分支覆盖等)。其次,单元测试和覆盖率是有用的,尤其是在我们想把一件事情搞好的时候。

单元测试顾名思义就是对单元进行测试,这里的单元就是方法。但是我们在类的设计中会设计方法的访问限定符,以此来更好的做到高内聚,低耦合。如果只是对public的方法做测试,那么为了验证一些private方法的正确性,我们就需要以public方法为入口,构造复杂的测试上下文,如此,增大开发测试的负担。那么,对不公开的方法如何测试呢。

1 采用java独特的包访问权限,这样的话,product code和test code可以放在不同的目录,但是可以有相同的包名。这样的缺点是test影响了product code的设计。

2 采用反射,采用反射可以访问product code的private方法,这样,test和product就完全隔离开了。这样的缺点是test中对方法名要进行hard code,不利于重构。但是权衡利弊,这个方法还是可行的。

在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。

比如我们有一个

private int getUserAge(String userId) 的方法,为了测试,在test中可以有如下结构。

//调用指定对象的指定方法。用java的反射机制实现。
private Object invokeMethod(String methodName, Class<?>[] parameterClasses, Object object,
                                Object[] parameters)

//转发调用。
private int invokeGetUserAge(String userId){
    调用invokeMethod,做适当的类型转换。
}

//真正的test方法,调用invokeGetUserAge。
public void testGetUserAge()


mock1234 写道
zhang_xzhi_xjtu 写道

在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。

比如我们有一个

private int getUserAge(String userId) 的方法,为了测试......


UT还private?更进一步地说,UT还纠结于单元测试?

如果你真的做UT,你在动手写代码之前就有关于用户行为(这里的用户不仅仅指最终用户,如果你是发布一组工具那么你的用户就是其它开发组中的程序员)的设计了,你可以将这种设计写为测试程序(而不是满足在可以随便忽悠着解释的文档),然后才开始开发。如果编译不通过,就让它编译通过;如果针对数据输入输出的断言不通过,就让断言通过!

你做UT时还纠结于private,甚至纠结于单元测试,咄咄怪事。(因为单元测试工具只是一个驱动测试开始执行的工具,而你要的是针对UT的对象而不是什么代码函数单元啊)。

更进一步说,好的测试是对重构提供支持的。你纠结于那些“单元”,还能重构吗?使用你的所谓单元测试代码维系垃圾代码,当作餐桌上的主菜,是不是本末倒置了?

我给你提供一个测试的“原则”作为参考。对于纯粹功能性的开发,我在写测试时保持大致1个半小时的开发时间(因为之前需要10~30分钟编写测试代码的时间),这就是我写测试的原则。

每当重构了,当然要回归运行那些测试代码。因此这些测试时为了支持重构这种高度灵活性的东西而准备的。

怎么可能像你那样,先写完了实现代码,然后才钻到垃圾堆底层private单元集合里边去翻最臭味道的代码单元来编织到“测试系统”里呢?


你说的这些我都是同意的,如果条件允许的话,我当然也是这么做,事实上,TDD的开发精髓就是测试驱动设计。

问题是我现在面临的场景中,业务逻辑很复杂,于是,为了方法的内聚性,一个public的方法往往需要调用拆分出去多个private方法,这是,如果坚持一套完整的测试的话,那么测试环境的搭建将变得复杂,或者说关注点不集中,因为测试的分支是成指数级别增长的,而为了系统的稳定性,我们需要覆盖掉所有的分支。我选择用反射来测试这些private方法可以分离测试的关注点。当然,这个对重构是有不好的影响的,权衡利弊,我只能采取一些措施降低这种影响,但是还是要保全一个test的完整性和专注性。

举个例子,
public Object f(Object input){
  根据input计算出s1,s2,s3,s4,flag
  if(flag){
    a=g(s1,s2);
    return a;
  }else{
    b=g(s3,s4);
    return b;
  }
}

public void f1(){
调用g.
}

private Object g(Object o1,Object o2){
}


flag有2种状态。
假设g方法的参数o1,o2各有3种状态。
如果采用先test后code的方法,为了完整的测试f的功能,那么我们需要控制input来生成所有的2*3*3=18个test才能完全覆盖到所有的分支。当然,也可以控制input生成flag为true的9种情况,以及1个flag为false的情况。

但是我觉得这样的测试关注点不够集中,我的思路是,可以先为f写两个test,来覆盖flag的两个分支,然后coding,保证f的两个分支都被测试到,即g都被调用过,至于g自己的方法约定,应该属于g自己的事情,可以用反射来测试。

我们在考虑一下如果f,f1都要调用g方法的情况,那么我们有必要为测试f,f1都建立g的9种状态吗?如果还有更多的f2,f3,...fn呢?

传统的test是一种黑盒测试,而用反射是白盒测试。我认为程序员是可以利用关于实现的知识进行测试的。利用反射,虽然一方面增加了重构的难度,但是,可以提高测试的关注点,同时,白盒测试也有利于重构出被多个public方法调用的private方法。

分享到:
评论
23 楼 piao_bo_yi 2010-11-30  
#ifdef _MY_TEST
#define private public 
#endif

爽吧?
22 楼 fflame 2010-07-12  
zhang_xzhi_xjtu 写道
skydream 写道
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性

一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.


不是多职责类,而是本身的业务就是很复杂。


没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。

实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。


这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。


内聚性不一定要通过把方法写在一个类里实现,可能还是对业务拆分的粒度不够,或许可以大概说说这个业务实现的功能详情?
个人经验,设计成多个类,短时间内可能复杂一点,但是问题多样化以后,对类的修改反倒会简单些。呃,代码效率就不好说了
21 楼 zhang_xzhi_xjtu 2010-07-09  
抛出异常的爱 写道
zhang_xzhi_xjtu 写道
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。

设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.

目的决定手段.


这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。

不相信.
很多人不理解自己写过的代码


当然很多人不理解自己写过的代码
但是并不是所有人都不理解
20 楼 抛出异常的爱 2010-07-09  
zhang_xzhi_xjtu 写道
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。

设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.

目的决定手段.


这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。

不相信.
很多人不理解自己写过的代码
19 楼 zhang_xzhi_xjtu 2010-07-09  
skydream 写道
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性

一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.


不是多职责类,而是本身的业务就是很复杂。


没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。

实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。


这个我是完全同意的。
但是这里讨论的是测试问题,即使分拆成多个类,还是没有解决如何测试的问题。
公开了这些小类的方法,不太符合设计的内聚性。
私有话了这些小类的方法,就不好测试。
18 楼 skydream 2010-07-07  
zhang_xzhi_xjtu 写道
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性

一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.


不是多职责类,而是本身的业务就是很复杂。


没有任何类是生来就有理由复杂的,如果业务的确很复杂,请考虑将这些复杂的业务拆分清洗,然后分解到若干个功能简单清洗的类上去。不必介意小类的出现,不必介意类数量的增加。

实现同样的功能,1个复杂的类肯定比10个清晰短小的类要“复杂”。
17 楼 zhang_xzhi_xjtu 2010-07-03  
scott.yao 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性

一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.


不是多职责类,而是本身的业务就是很复杂。
16 楼 scott.yao 2010-07-02  
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性

一个复杂到要单独测试的private方法,要考虑它所承担的职责,不是简单的提取作为帮助类.
内聚性不是设计复杂的多职责类的借口.
15 楼 icefire 2010-07-02  
太多的private说明此类承担太多责任或者过于复杂,无论怎样,说明抽象程度不够,拆分不够,所以测试难以覆盖,才会想到用反射来做测试。

所以测试多好,一下就帮你发现问题了。。
14 楼 gigix 2010-07-01  
引用
private int getUserAge(String userId)

这种空对空的代码是没有任何意义的
13 楼 zhang_xzhi_xjtu 2010-07-01  
抛出异常的爱 写道
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。

设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.

目的决定手段.


这里讨论的测试是开发程序员的测试,是建立在对代码熟悉基础上的。
12 楼 zhang_xzhi_xjtu 2010-07-01  
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。


前边例子已经举过,真实的代码当然是公司的,不能外泄。但是抽象出的示例代码已经可以说明问题了。
11 楼 抛出异常的爱 2010-07-01  
gigix 写道
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。

设计非常混乱的代码发给QA时
QA常常不能明白某些方法存在的目的
并且这些方法的覆盖直接影响到QA的成绩单.

目的决定手段.
10 楼 gigix 2010-07-01  
zhang_xzhi_xjtu 写道
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。

不要空对空。拿例子出来说。
9 楼 jiangduxi 2010-06-30  
gigix 写道

第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?

这个很有道理。不要滥用反射进行这种测试。如果利用反射进行对private方法进行测试。那么本质上就是忽略了private方法作用了。
8 楼 zhang_xzhi_xjtu 2010-06-30  
gigix 写道
不要测试private方法
如果private方法复杂到了需要被单独测试的程度,你需要把它抽取成一个单独的类


这种办法我也想过,问题是, 抽象成一个单独的类,也不过是只要让原来那个类调用,那么这个类只是一个帮助类,同时,同时,如果按照这种方法,有可能有大量的方法定义在这个帮助类中,方法的访问属性又变成了高于private的。如果高于private,那么还不如在原有的类中放宽方法的访问限制,那样还可以提高类的内聚性。
7 楼 gigix 2010-06-30  
tzm1984 写道
反射有时还有用的,
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。

第一,正常使用者怎么改变它的值;第二,改变它的值对使用者有什么影响。
你只要考虑这两个问题,那么很显然private变量的值必定是能通过某个外在行为来改变、并从而影响某个外在行为的,因此一定是能通过外在行为来测试的。
如果某个private变量的值不能通过外在行为来改变,那它的使用者就无法改变它;如果它的值改变不会影响外在行为,那它的使用者就不在乎它。如果它的使用者不能改变它或者不在乎它,你为什么要测试它?
6 楼 tzm1984 2010-06-30  
反射有时还有用的,
对于private的内部变量只有class内部用,不对外的。
但是UT一个方法是要改变private变量的值来实现UT覆盖就需要反射了。

反正具体情况具体对待 哈哈。
5 楼 berlou 2010-06-30  
这种情况与其用反射区牺牲重构方面的利益,不如干脆把private变成protected或者default。
4 楼 aws 2010-06-30  
只针对接口测试

相关推荐

    注解、反射、单元测试、lombok知识点总结笔记

    在Java编程中,注解(Annotation)、反射(Reflection)、单元测试(Unit Testing)以及Lombok是四个关键的知识点,它们各自扮演着不同的角色,对于提高代码的可维护性、动态性和测试覆盖率至关重要。 注解是一种元...

    折射-反射-枚举-单元测试综合案例

    单元测试有助于尽早发现和修复问题,提高代码质量,也有利于后期的维护和重构。 在"折射-反射-枚举-单元测试综合案例"中,可能涉及到的是如何将这些技术结合起来解决具体问题。例如,你可以使用反射来动态地创建和...

    轻松编写 C++ 单元测试(gtest)

    在实际的项目中,使用googletest框架编写单元测试能够极大地提高开发效率和代码质量。开发者只需要关注于测试的编写和逻辑的正确性验证,无需担心底层的测试运行机制,这可以大幅减少学习成本和维护成本。单元测试...

    Junit单元测试内部机制解析

    JUnit作为Java领域中最流行的单元测试框架之一,提供了强大的测试能力,帮助开发者编写高质量的代码。 #### 二、JUnit框架的内部工作机制 JUnit的核心设计理念是将测试逻辑与业务逻辑分离,通过一系列标准化的API...

    在.NET环境中使用单元测试工具NUnit

    在.NET环境中,单元测试工具NUnit是一个不可或缺的开发辅助工具,它主要用于确保代码的质量和可靠性。单元测试是一种软件开发过程中的关键实践,它允许开发者针对代码的最小可测试单元进行独立验证,通常是一个函数...

    怎样使用Junit Framework进行单元测试的编写.pdf

    ### 使用JUnit Framework进行单元测试编写的关键知识点 #### 单元测试的重要性及JUnit Framework的地位 ...开发者应当将单元测试视为软件开发不可或缺的一部分,不断迭代和完善测试用例,以此提高软件的质量和可靠性。

    基于Annotation的Java单元测试框架.pdf

    本文主要介绍了基于Annotation的Java单元测试框架,讨论了Annotation在Java EE中的应用、反射技术的使用和JUnit单元测试框架的结合,建立了一个自动化单元测试框架结构。 一、Annotation概述 Annotation是Java 5中...

    优化对Private方法进行单元测试Demo

    在软件开发过程中,单元测试是确保代码质量的重要环节。它允许开发者验证代码的各个部分是否按预期工作。然而,对于“优化对Private方法进行单元测试Demo”这一主题,我们需要理解一个核心原则:通常不应直接对...

    Unitils单元测试

    Unitils 是一个强大的Java测试框架,它旨在简化单元测试的过程并提高测试的可维护性。该框架基于DbUnit和EasyMock,并与JUnit和TestNG兼容,提供了对数据库测试、Mock对象管理和Spring集成的支持。 在数据库测试...

    基于Java反射的APP自动化混合测试框架的研究与实现.zip

    在自动化测试领域,利用反射可以实现对应用程序内部结构的灵活操控,提高测试的覆盖率和效率。 首先,我们要理解混合测试框架的概念。混合测试框架通常结合了单元测试和UI测试的优点,它可以覆盖从底层代码逻辑到...

    自动化单元测试框架NUnit的改进设计与实现.pdf

    总的来说,NUnit通过面向对象的方法,将测试案例、测试套件、测试结果、断言等概念抽象化,并利用.NET框架的反射、文件操作、接口等技术手段,实现了一个功能完备的单元测试框架。它极大地简化了.NET项目测试代码的...

    php单元测试phpunit入门实例教程

    整体而言,单元测试是确保代码质量和可靠性的关键实践。PHPunit作为一个强大的工具,其提供了一套完整的解决方案来支持PHP开发中的单元测试。为了更好地掌握PHPunit,建议开发者不仅要学习工具的基本使用,还应关注...

    电子功用-基于单元形函数的反射面天线机电集成设计方法

    《电子功用-基于单元形函数的反射面天线机电集成设计方法》是一份深入探讨反射面天线设计的专业文档,其核心内容围绕着利用单元形函数进行机电一体化设计的策略展开。在电子工程领域,反射面天线因其高效能、大覆盖...

    框架的概念及用反射技术开发框架的原理

    5. 测试与优化:进行严格的单元测试和性能优化,确保框架的稳定性和高效性。 通过学习和理解框架的概念,以及如何利用反射技术开发框架,开发者能够更好地掌握Java编程的高级技巧,提高软件开发的生产力。在实际...

    servlet反射注解例子

    这对于创建通用的代码、框架或者进行单元测试非常有用。 接着,我们来看看注解。注解是Java提供的一种元数据,它可以为编译器、JVM或者工具提供有关代码的额外信息。注解不会改变代码的行为,但可以被编译器或工具...

    ISO12233测试标板的使用和判读.pptx

    ### ISO12233测试标板的使用与判读详解 #### 1. ISO12233测试标板简介 ##### 1.1 ISO12233测试标板图样 ISO12233测试标板是一种标准化的测试工具,用于评估相机系统(特别是数字相机)的分辨率性能。这种标板包含...

    高效软件测试自动化软件测试自动化

    - **单元测试**:针对单个模块或函数进行测试。 - **集成测试**:验证不同模块之间的接口是否正常工作。 - **回归测试**:确保新版本没有引入新的错误或破坏旧功能。 #### 六、实例应用与练习 书中不仅提供了理论...

    net 自动化测试

    例如,NUnit是一个开源的单元测试框架,适用于.NET应用程序,可以编写控制台测试用例;xUnit则以其灵活性和扩展性著称,而MSTest是Microsoft官方提供的测试框架,与Visual Studio紧密集成,便于进行界面测试。 界面...

Global site tag (gtag.js) - Google Analytics