skinny85 / specnaz

Library for writing beautiful, RSpec/Jasmine/Mocha/Jest-style specifications in Java, Kotlin and Groovy
Other
34 stars 8 forks source link

Specnaz TestNG runner fails, by trying to run *describes lambdas as test (and failing at it) #10

Closed Stvad closed 5 years ago

Stvad commented 5 years ago

Examples of errors:

   [testng] 
   [testng] [Utils] [ERROR] [Error] org.testng.TestNGException: 
   [testng] Cannot inject @Test annotated Method [describes] with [class java.lang.String, interface kotlin.jvm.functions.Function1].
   [testng] For more information on native dependency injection please refer to http://testng.org/doc/documentation-main.html#native-dependency-injection
   [testng]     at org.testng.internal.Parameters.checkParameterTypes(Parameters.java:407)
   [testng]     at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:356)
   [testng]     at org.testng.internal.Parameters.createParameters(Parameters.java:635)
   [testng]     at org.testng.internal.Parameters.handleParameters(Parameters.java:769)
   [testng]     at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
   [testng]     at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
   [testng]     at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:923)
   [testng]     at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
   [testng]     at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
   [testng]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
   [testng]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
   [testng]     at java.lang.Thread.run(Thread.java:748)
   [testng] 
   [testng] [Utils] [ERROR] [Error] org.testng.TestNGException: 
   [testng] Cannot inject @Test annotated Method [xdescribes] with [class java.lang.String, interface kotlin.jvm.functions.Function1].
   [testng] For more information on native dependency injection please refer to http://testng.org/doc/documentation-main.html#native-dependency-injection
   [testng]     at org.testng.internal.Parameters.checkParameterTypes(Parameters.java:407)
   [testng]     at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:356)
   [testng]     at org.testng.internal.Parameters.createParameters(Parameters.java:635)
   [testng]     at org.testng.internal.Parameters.handleParameters(Parameters.java:769)
   [testng]     at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
   [testng]     at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
   [testng]     at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:923)
   [testng]     at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
   [testng]     at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
   [testng]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
   [testng]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
   [testng]     at java.lang.Thread.run(Thread.java:748)
   [testng] 
   [testng] PASSED: test should work
   [testng] FAILED: describes
   [testng] org.testng.TestNGException: 
   [testng] Cannot inject @Test annotated Method [describes] with [class java.lang.String, interface kotlin.jvm.functions.Function1].
   [testng] For more information on native dependency injection please refer to http://testng.org/doc/documentation-main.html#native-dependency-injection
   [testng]     at org.testng.internal.Parameters.checkParameterTypes(Parameters.java:407)
   [testng]     at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:356)
   [testng]     at org.testng.internal.Parameters.createParameters(Parameters.java:635)
   [testng]     at org.testng.internal.Parameters.handleParameters(Parameters.java:769)
   [testng]     at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
   [testng]     at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
   [testng]     at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:923)
   [testng]     at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
   [testng]     at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
   [testng]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
   [testng]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
   [testng]     at java.lang.Thread.run(Thread.java:748)
   [testng] 
   [testng] FAILED: xdescribes
   [testng] org.testng.TestNGException: 
   [testng] Cannot inject @Test annotated Method [xdescribes] with [class java.lang.String, interface kotlin.jvm.functions.Function1].
   [testng] For more information on native dependency injection please refer to http://testng.org/doc/documentation-main.html#native-dependency-injection
   [testng]     at org.testng.internal.Parameters.checkParameterTypes(Parameters.java:407)
   [testng]     at org.testng.internal.Parameters.createParametersForMethod(Parameters.java:356)
   [testng]     at org.testng.internal.Parameters.createParameters(Parameters.java:635)
   [testng]     at org.testng.internal.Parameters.handleParameters(Parameters.java:769)
   [testng]     at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:49)
   [testng]     at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:37)
   [testng]     at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:923)
   [testng]     at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
   [testng]     at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
   [testng]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
   [testng]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
   [testng]     at java.lang.Thread.run(Thread.java:748)

From @skinny85 investigation this happens only when you run TestNG, passing it a package name (but it works fine if you pass the class names directly).

The proposed workaround is to add another test listener for TestNG, with the following content:

package specnaz;

import org.specnaz.kotlin.SpecnazKotlin;
import org.specnaz.kotlin.params.SpecnazKotlinParams;
import org.testng.IAlterSuiteListener;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlPackage;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

import java.util.List;

import static java.util.stream.Collectors.toList;

public class SecondListener implements IAlterSuiteListener {
    @Override
    public void alter(List<XmlSuite> xmlSuites) {
        for (XmlSuite xmlSuite : xmlSuites) {
            alterXmlSuite(xmlSuite);
        }
    }

    private void alterXmlSuite(XmlSuite xmlSuite) {
        xmlSuite.setTests(xmlSuite.getTests().stream()
                .map(xmlTest -> alterXmlTest(xmlTest))
                .collect(toList())
        );
    }

    private XmlTest alterXmlTest(XmlTest xmlTest) {
        xmlTest.setPackages(xmlTest.getPackages().stream()
                .map(xmlPackage -> alterXmlPackage(xmlPackage))
                .collect(toList())
        );
        return xmlTest;
    }

    private XmlPackage alterXmlPackage(XmlPackage xmlPackage) {
        xmlPackage.getXmlClasses().forEach(xmlClass -> alterXmlClass(xmlClass));
        return xmlPackage;
    }

    private XmlClass alterXmlClass(XmlClass xmlClass) {
        if (isSpecnazKotlinClass(xmlClass))
            xmlClass.getExcludedMethods().add(".*describes");
        return xmlClass;
    }

    private boolean isSpecnazKotlinClass(XmlClass xmlClass) {
        return SpecnazKotlin.class.isAssignableFrom(xmlClass.getSupportClass()) ||
                SpecnazKotlinParams.class.isAssignableFrom(xmlClass.getSupportClass());
    }
}
skinny85 commented 5 years ago

Thanks for reporting @Stvad ! A fix is in the works, ETA: end of this wek :)

skinny85 commented 5 years ago

The issues is fixed in version 1.4.1 of Specnaz - just tested it on an example project. I'm resolving this one.

Stvad commented 5 years ago

Thank you @skinny85!