zoukankan      html  css  js  c++  java
  • TestNG 与 Junit的比较(转)

    转自 http://www.blogjava.net/fanscial/archive/2005/12/14/23780.html


    1.         JDK 5 Annotations (JDK 1.4 可以用JavaDoc代替).

    一个典型的Junit的测试类

    import junit.framework.TestCase;

    public class Jtest extends TestCase {

           protected void setUp() throws Exception {

                  super.setUp();

                         //some initial code

        }

        protected void tearDown() throws Exception {

            super.tearDown ();

            //release resource and rollback

    }

    public void testFunction {

           //test code

    }

    }

    对应的TestNG的测试类,我们写最简单的情况。

    public class NGtest{

        @Configuration(beforeTestClass=true)

        public void setUp() {

            //some initial code

    }

    @Configuration(afterTestClass = true)

        public void tearDown (){

           //release resource and rollback

        }

        @Test( )

        public void testFunction (){

           //test code

        }

    }

    这样写可以比较明显的看到两者的对应关系(注意TestNG的方法的名字是可以随便取的,取一样的名字只是为了让你容易找到对应的关系)

    这说明TestNG是从Junit发展而来的,至少借鉴了很多Junit的思想(实际上TestNG的作者本身就是Junit的小组成员之一)。

    我们从最表面的现象来看看吧

    l         TestNG没有继承任何类,甚至接口!!

    l         JDK 5 Annotations

    这2者是息息相关的,为什么我们不用继承任何类,因为信息都在注释里面,这样会带来很多好处(绝不仅仅是命名的方便)。

    2.         灵活的test configuration

    先看一下Junit的执行顺序

    Setup( )   test1( )    tearDown( )      Setup( )     test2( )      tearDown( )…………

    下面是TestNG的

    testng.JPG

    实际上外面还有一个beforeSuite和afterSuite的方法,是在测试项目开始的时候就运行了,实际上如果我的每个方法都要用到的初始化的代 码,为什么要运行那么多次,如果其中有EJB这种重量级的容器要初始化,效率差可想而知。事实上TestNG可以做到更加的灵活,就是分组。


    3.         TestNG 的灵魂

    配置文件(testng.xml)

    Junit中要定义测试任务是要写TestSuit的,居然要写硬编码,而TestNG全部写在testng.xml(名字可以自定义的)中的,然后可以通过ant来调用。

    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

    <suite name="my suite">

    <test name="test1">

           <groups>

           <run name="group1">

           </run>

           </groups>

    <classes>

    <class name="ClassA"  />

    </classes>

    </test>

    <test name="test2"  >

           <groups>

           <run name="group2">

           </run>

           </groups>

    <classes>

    <class name="ClassB"/>

    <class name="ClassC"/>

    </classes>

    </test>

    </suite>

    上面包含了配置文件的基本的主干,一个配置文件只有一个Suite,基本上一个项目写一个配置文件就可以了,当然如果你的项目足够大,可能需要几个 配置文件。测试是按照从大到小的顺序进行的,先执行suite,test,class,其中的group和class是平级的,在讲group的时候再详 细的解释。有了这个文件,我们就可以很清楚的理解@configuration里面的类型

    public boolean beforeSuite() default false;

    public boolean afterSuite() default false;

    public boolean beforeTest() default false;

    public boolean afterTest() default false;

    public boolean beforeTestClass() default false;

    public boolean afterTestClass() default false;

    public boolean beforeTestMethod() default false;

    public boolean afterTestMethod() default false;

    从字面意思可以看出方法的执行顺序,唯一的疑惑是执行的次数,官方的文档的解释是相当让人疑惑的,好在我们可以自己测 试,beforeTestMethod是当类中任何方法调用都要执行的,beforeTest和beforeTestClass在一个Test中是只执行 一次的(没试过把2个相同的类写到一个Test里面),而beforeSuite在一个配置文件中只执行一次。上面都没有考虑分组的情况,分组会更加的复 杂,似乎灵活过头了,但是考虑到项目的复杂性,每个测试方法的初始化都可能不同,现在我们做的项目要求每天要将单元测试写进daily build的build文件里面自动执行,似乎只有用TestNG这样灵活的配置才能达到。

    4.         分组

    将一个测试方法或者配置方法分组是很容易的。

    @Configuration(beforeTestClass=true,groups=“group1”)

    @Test(groups=”group1”)

    只要象上面写就可以了,名字随便取,而且不需要预先定义。

    我们在一个类做2个组,看看效果

    @Configuration(beforeTestClass=true,groups=“group1”)

    Public void C1(){}

    @Test(groups=”group1”)

    Public void T1(){}

    @Configuration(beforeTestClass=true,groups=“group2”)

    Public void C2(){}

    @Test(groups=”group2”)

    Public void T2(){}

    只选group1

    …………………

           <groups>

           <run name="group1">

           </run>

           </groups>

    …………

           执行C1        T1

    只选group2

    …………………

           <groups>

           <run name="group2">

           </run>

           </groups>

    …………

    执行C2        T2

    2个都选

    …………………

           <groups>

    <run name="group1">

           <run name="group2">

           </run>

           </groups>

    …………

    我最先以为的顺序是C1        T1       C2        T2  (A)

    然而实际上是  C1        C2        T1        C1        C2        T2 (B)

    要想达到(A)的效果,只能把2个group分开了放在不同的Test里面,其实只要知道一点,TestNG是先找Class,然后才去找Group的。


    4.         参数

    Junit是不带任何参数的,不论是测试方法还是配置方法,而TestNG都是可以添加参数的,有2种方法。

    (1)       使用Parameter参数

            @Parameters({ "first-name" })
            @Test
            public void testSingleString(String firstName) {
            System.out.println("Invoked testString " + firstName);
            assert "Cedric".equals(firstName);
            }
            参数的值放到配置文件中
            <suite name="My suite">
            <parameter name="first-name"  value="Cedric"/>
            <test name="Simple example">

       这种方法偶尔用之还可以,但是很遗憾的是第一只能传String(可能可以其他的基本数据类型??但至少不能传复杂对象),第二数据写在配置文件中,不能所见即所得。

    但是下面的方法真的给我们惊喜。

    (2)       DataProvider

      这是从4.0以后增加的功能,看看怎么实现。

    // This method will provide data to any test method that declares that its Data Provider
    // is named "test1"
    @DataProvider(name = "test1")
    public Object[][] createData1() {
    return new Object[][] {
    new Object[] { "Cedric", new Integer(36) },
    new Object[] { "Anne", new Integer(37)},
     };
    }

    // This test method declares that its data should be supplied by the Data Provider
    // named "test1"
    @Test(dataProvider = "test1")
    public void verifyData1(String n1, Integer n2) {
    System.out.println(n1 + " " + n2);
    }

    执行的结果

    Cedric 36

    Anne 37

    DataProvider返回的是个2维数组的对象,什么数据都可以提供了吧,而且可以让你的测试方法执行多次。而且最重要的是和测试方法写在一起,所见即所得。

    5.         Ant的集成和Daily Build

    TestNG对Ant提供了很好的支持,这是我写得测试用的Ant脚本

    <project default="testng">

           <property file="build.properties" />

           <path id="cpath">

                  <fileset dir="lib">

                         <include name="*.jar"/>

                  </fileset>

           </path>

    //定义testng的任务

           <taskdef resource="testngtasks" classpath="lib/testng-4.4-jdk15.jar" />

           <target name="compile">

                  <mkdir dir="test/classes"/>

                   <javac destdir="test/classes"

                                srcdir="${testng.dir}"

                                             debug="true"

                                             encoding="GBK" >

                        <classpath refid="cpath"/>

                  </javac>

           </target>

           //执行testng的任务

           <target name="testng" depends="compile">

                  <testng classpath="test/classes">

                         <xmlfileset dir="${configure.dir}" includes="testing.xml" />

                  </testng>

           </target>

    </project>

    简单的不能在简单了,你只要告诉ant来调用,然后告诉ant配置文件在哪里,剩下的事都交给testng自己的配置文件去做就行了,然后ant以后都不用修改了。不建议将任务的细节写在ant里面,首先功能不如testng自己的配置文件强大,而且ant需要维护。


    下面基本上是TestNG才有的特点了,和Junit没有什么关系,但为了延续,还是用了上面的题目。
    7 .依赖关系
    先给个例子

    @Test

    public void serverStartedOk() {}

    @Test(dependsOnMethods = { "serverStartedOk" })

    public void method1() {}

    在这个例子中,method1()必须在serverStartedOk()执行后才能执行,而且serverStartedOk()不能fail,否则method1()会被skip掉

    基本上类似于ant的依赖关系,也很容易理解,只是分为强依靠和弱依靠,区别是弱依靠只管执行的顺序,强依靠除了顺序,还要正确,否则后面的不执行,上面的例子是强依靠,下面是弱依靠,加上alwaysrun=”true”

    @Test

    public void serverStartedOk() {}

    @Test(dependsOnMethods = { "serverStartedOk" },alwaysrun=”true”)

    public void method1() {}

    如果有兴趣,可以看看下面的文章,里面有有趣的争论

    http://beust.com/weblog/archives/000171.html

     8.其他特性
       还有很多,工厂模式,并行运行(Parallel running ),BeanShell 等等,感觉不是特别重要,而且写了那么多感觉好累啊,就不写了,有兴趣的可以去看看官方的文档。
    http://testng.org/doc/documentation-main.html

  • 相关阅读:
    部分源码:Visual Studio 2019 C运行时库(CRT)部分源码
    反思:中国歌手和欧美歌手的比较
    lol:lol 10分钟前上路到线小兵107只
    OS:RPM包的通用命名规则(转载)
    OS: kali linux的安装和配置
    OS_linux:Systemd 文档
    visual studio 2019 插件安装(插件扩展名vsix)
    解决git合并冲突问题
    nodejs封装的MongoDB的增删改查方法
    vue项目中购物车的全选功能的实现
  • 原文地址:https://www.cnblogs.com/digod/p/5763633.html
Copyright © 2011-2022 走看看