指定dependsOnMethods时,TestNG不保留顺序

时间:2017-03-22 17:45:39

标签: java testng

如果我们想要在类级别保留执行的顺序,另一方面我们想要使用选项" dependsOnMethods"并且" parallel =" false"",事情出乎意料。使用TestNG 6.8.8至6.11进行测试。此处描述了类似的行为:

https://github.com/cbeust/testng/issues/1291

我已经尝试过TestNG提供的所有可用选项,唯一有用的是将所有测试类(包含" dependsOnGroups")放在testng.xml中自己的标记中配置。但这导致了另一个问题。我们也在使用" dependsOnGroups"这在单独定义的测试(即不同的标签)之间是不可见的。我在TestNG侦听器中使用" ignoreMissingDependencies = true",通过检查依赖链是否存在依赖组的任何故障。

注意:我已尝试过"逐个实例=" true""和其他TestNG调整优先级和threadCount,forkCount等没有任何成功。

这是我们所拥有的片段,目前正在发挥作用。当然,我可以提供任何有用的建议。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite verbose="0" name="Regretion Suite" parallel="false"
    preserve-order="true">
    <test name="Tests without dependsOnMethods" preserve-order="true">
        <classes>
            <class name="com.demo.testng.TestSetup" />
            <class name="com.demo.testng.TestOne" />
            <class name="com.demo.testng.TestTwo" />
        </classes>
    </test>
    <test name="TestThree with dependsOnMethods">
        <classes>
            <class
                name="com.demo.testng.TestThree" />
        </classes>
    </test>
    <test name="TestFour with dependsOnMethods">
        <classes>
            <class
                name="com.demo.testng.TestFour" />
        </classes>
    </test>
</suite> <!-- Command line suite -->

package com.demo.testng;


import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


/**
 * @author a.kolev
 */
@Listeners(StateVerifierTestNGWatcher.class)
@Test(groups = {"Setup"})
public class TestSetup
{
    private static final Logger log = Logger.getLogger(TestSetup.class);


    @BeforeClass
    public void oneTimeSetUp()
    {
        log.info("TestSetup:oneTimeSetUp");
    }


    @AfterClass(alwaysRun = true)
    public void oneTimeCleanUp()
    {
        log.info("TestSetup::oneTimeCleanUp");
    }


    @Test
    public void testOne()
    {
        log.info("TestSetup::testOne");
    }


    @Test
    public void testTwo()
    {
        log.info("TestSetup::testTwo");
    }


    @Test
    public void testThree()
    {
        log.info("TestSetup::testThree");
    }
}

package com.demo.testng;


import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


/**
 * @author a.kolev
 */
@Listeners(StateVerifierTestNGWatcher.class)
@Test(groups = {"Execution"}, dependsOnGroups = {"Setup"}, ignoreMissingDependencies = true)
public class TestOne
{
    private static final Logger log = Logger.getLogger(TestOne.class);


    @BeforeClass
    public void oneTimeSetUp()
    {
        log.info("TestOne::oneTimeSetUp");
    }


    @AfterClass(alwaysRun = true)
    public void oneTimeCleanUp()
    {
        log.info("TestOne::oneTimeCleanUp");
    }


    @Test
    public void testOne()
    {
        log.info("TestOne::testOne");
    }


    @Test
    public void testTwo()
    {
        log.info("TestOne::testTwo");
    }


    @Test
    public void testThree()
    {
        log.info("TestOne::testThree");
    }
}

package com.demo.testng;


import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


/**
 * @author a.kolev
 */
@Listeners(StateVerifierTestNGWatcher.class)
@Test(groups = {"Execution"}, dependsOnGroups = {"Setup"}, ignoreMissingDependencies = true)
public class TestTwo
{
    private static final Logger log = Logger.getLogger(TestTwo.class);


    @BeforeClass
    public void oneTimeSetUp()
    {
        log.info("TestTwo::oneTimeSetUp");
    }


    @AfterClass(alwaysRun = true)
    public void oneTimeCleanUp()
    {
        log.info("TestTwo::oneTimeCleanUp");
    }


    @Test
    public void testOne()
    {
        log.info("TestTwo::testOne");
    }


    @Test
    public void testTwo()
    {
        log.info("TestTwo::testTwo");
    }


    @Test
    public void testThree()
    {
        log.info("TestTwo::testThree");
    }
}

package com.demo.testng;


import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


/**
 * @author a.kolev
 */
@Listeners(StateVerifierTestNGWatcher.class)
@Test(groups = {"Execution"}, dependsOnGroups = {"Setup"}, ignoreMissingDependencies = true)
public class TestThree
{
    private static final Logger log = Logger.getLogger(TestThree.class);


    @BeforeClass
    public void oneTimeSetUp()
    {
        log.info("TestThree::oneTimeSetUp");
    }


    @AfterClass(alwaysRun = true)
    public void oneTimeCleanUp()
    {
        log.info("TestThree::oneTimeCleanUp");
    }


    @Test(ignoreMissingDependencies = true)
    public void testOne() throws InterruptedException
    {
        log.info("TestThree::testOne");
        Thread.sleep(10000);
    }


    @Test(dependsOnMethods = "testOne", ignoreMissingDependencies = true)
    public void testTwo()
    {
        log.info("TestThree::testTwo");
    }


    @Test(dependsOnMethods = "testTwo", ignoreMissingDependencies = true)
    public void testThree()
    {
        log.info("TestThree::testThree");
    }
}

package com.demo.testng;


import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


/**
 * @author a.kolev
 */
@Listeners(StateVerifierTestNGWatcher.class)
@Test(groups = {"Execution"}, dependsOnGroups = {"Setup"}, ignoreMissingDependencies = true)
public class TestFour
{
    private static final Logger log = Logger.getLogger(TestFour.class);


    @BeforeClass
    public void oneTimeSetUp()
    {
        log.info("TestFour::oneTimeSetUp");
    }


    @AfterClass(alwaysRun = true)
    public void oneTimeCleanUp()
    {
        log.info("TestFour::oneTimeCleanUp");
    }


    @Test(ignoreMissingDependencies = true)
    public void testOne()
    {
        log.info("TestFour::testOne");
    }


    @Test(dependsOnMethods = "testOne", ignoreMissingDependencies = true)
    public void testTwo() throws InterruptedException
    {
        log.info("TestFour::testTwo");
        Thread.sleep(10000);
    }


    @Test(dependsOnMethods = "testTwo", ignoreMissingDependencies = true)
    public void testThree()
    {
        log.info("TestFour::testThree");
    }
}

package com.demo.testng;


import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;
import org.testng.IConfigurationListener2;
import org.testng.ITestResult;
import org.testng.SkipException;
import org.testng.annotations.Test;

import com.seeburger.test.api.util.TestNGWatcher;


/**
 * @author a.kolev
 */
public class StateVerifierTestNGWatcher extends TestNGWatcher implements IConfigurationListener2
{
    private static Logger log = Logger.getLogger(StateVerifierTestNGWatcher.class);

    private static final String CONFIGURATION_METHOD = "oneTimeSetUp";
    private static final String CLEANUP_METHOD = "oneTimeCleanUp";
    private static Set<String> failedGroups = new HashSet<>();


    @Override
    public void onTestStart(ITestResult result)
    {
        checkDependencyConditions(result);
    }


    /**
     * @param result
     */
    private void checkDependencyConditions(ITestResult result)
    {
        String[] groupsDependedUpon = result.getMethod().getGroupsDependedUpon();
        for (String groupDependedUpon : groupsDependedUpon)
        {
            skipIfDependencyFound(groupDependedUpon);
        }

        super.onTestStart(result);
    }


    /**
     * @param groupDependedUpon
     */
    private void skipIfDependencyFound(String groupDependedUpon)
    {
        if (failedGroups.contains(groupDependedUpon))
        {
            throw new SkipException("Setup phase failed!");
        }
    }


    @Override
    public void onTestFailure(ITestResult result)
    {
        String[] groups = result.getMethod().getGroups();

        for (int i = failedGroups.size(); i < groups.length; i++)
        {
            failedGroups.add(groups[i]);
        }

        super.onTestFailure(result);
    }


    @Override
    public void onConfigurationSuccess(ITestResult itr)
    {
        // TODO Auto-generated method stub

    }


    @Override
    public void onConfigurationFailure(ITestResult itr)
    {
        // TODO Auto-generated method stub

    }


    @Override
    public void onConfigurationSkip(ITestResult itr)
    {
        // TODO Auto-generated method stub

    }


    @Override
    public void beforeConfiguration(ITestResult tr)
    {
        if (tr.getMethod().getMethodName().equals(CONFIGURATION_METHOD) || tr.getMethod().getMethodName().equals(CLEANUP_METHOD))
        {
            checkConfigMethodDependencyConditions(tr);
        }
        else
        {
            checkDependencyConditions(tr);
        }
    }


    /**
     * @param tr
     */
    private void checkConfigMethodDependencyConditions(ITestResult tr)
    {
        Class< ? extends Object> instanceClass = tr.getInstance().getClass();
        if (instanceClass != null)
        {
            Test[] annotationsByType = instanceClass.getAnnotationsByType(Test.class);
            if (annotationsByType.length > 0)
            {
                String[] dependsOnGroups = annotationsByType[0].dependsOnGroups();
                for (String groupDependedUpon : dependsOnGroups)
                {
                    skipIfDependencyFound(groupDependedUpon);
                }
            }
        }
        else
        {
            log.warn(String.format("Configuration method %s instance class is null! Configuration method is not checked for failed dependency groups!", CONFIGURATION_METHOD));
        }

    }
}

这是预期的结果,真正的结果是什么:

没有变通方法结果:

TestSetup:oneTimeSetUp
TestSetup::testOne
TestSetup::testThree
TestSetup::testTwo
TestSetup::oneTimeCleanUp

TestOne::oneTimeSetUp
TestOne::testOne
TestOne::testThree
TestOne::testTwo
TestOne::oneTimeCleanUp

TestTwo::oneTimeSetUp
TestTwo::testOne
TestTwo::testThree
TestTwo::testTwo
TestTwo::oneTimeCleanUp

TestThree::oneTimeSetUp
TestThree::testOne
TestThree::testTwo
TestFour::oneTimeSetUp
TestFour::testOne
TestThree::testThree
TestThree::oneTimeCleanUp
TestFour::testTwo
TestFour::testThree
TestFour::oneTimeCleanUp

预期结果:

TestSetup:oneTimeSetUp
TestSetup::testOne
TestSetup::testThree
TestSetup::testTwo
TestSetup::oneTimeCleanUp

TestOne::oneTimeSetUp
TestOne::testOne
TestOne::testThree
TestOne::testTwo
TestOne::oneTimeCleanUp

TestTwo::oneTimeSetUp
TestTwo::testOne
TestTwo::testThree
TestTwo::testTwo
TestTwo::oneTimeCleanUp

TestThree::oneTimeSetUp
TestThree::testOne
TestThree::testTwo
TestThree::testThree
TestThree::oneTimeCleanUp

TestFour::oneTimeSetUp
TestFour::testOne
TestFour::testTwo
TestFour::testThree
TestFour::oneTimeCleanUp

0 个答案:

没有答案