@Factory and TestNG Eclipse plugin - discovering tests from package

75 views
Skip to first unread message

Grégory Pakosz

unread,
Mar 4, 2015, 12:54:52 PM3/4/15
to testng...@googlegroups.com
Hello,

I'm a new TestNG user.

In the following situation

public class SimpleTest
{
    private String name;

    public SimpleTest(String name) {
      this.name = name;
    }

    @Test
    public void test() {
        System.out.println("Simple Test Method. Instance:" + name);
    }
}
 
public class SimpleTestFactory
{
    @Factory
    public Object[] factoryMethod() {
        return new Object[] { new SimpleTest("foo"), new SimpleTest("bar") };
    }
}

When I right click SimpleTestFactory and do "Run as TestNG Test", TestNG uses the @Factory method to instantiate SimpleTest twice.

So far so good. If I right click the package and do "Run as TestNG Test", behavior is the same as right clicking SimpleTestFactory.

Now, I use Eclipse to duplicate SimpleTest into SimpleTest2 and right click the package again, and do "Run as TestNG Test". This time, I get "Default test name" in the output!
Somehow, TestNG decides when a test class as constructor that takes a single String parameter, it must be the test name... That's curious.

public class SimpleTest2
{
    private String name;

    public SimpleTest2(String name) {
      this.name = name;
    }

    @Test
    public void test() {
        System.out.println("Simple Test Method. Instance:" + name);
    }
}

Now, if I change SimpleTest2 so that the sole constructor takes an int parameter, right clicking the package and doing "Run as TestNG Test" causes an exception:

public class SimpleTest2
{
    private String name;

    public SimpleTest2(int i) {
      this.name = String.valueOf(i);
    }

    @Test
    public void simpleTest() {
        System.out.println("Simple Test Method. Instance:" + name);
    }
}

org.testng.TestNGException:
Can't invoke public test.SimpleTest2.test(): either make it static or add a no-args constructor to your class

So I thought, that's fine, I'm going to add another factory method

public class SimpleTestFactory
{
    @Factory
    public Object[] factoryMethod() {
        return new Object[] { new SimpleTest("foo"), new SimpleTest("bar") };
    }

  @Factory
  public Object[] factoryMethod2() {
      return new Object[] { new SimpleTest2(1), new SimpleTest2(2) };
  }
}

Except the second method annotated with "@Factory" is ignored by TestNG.

I had to create a SimpleTestFactory2 class

public class SimpleTestFactory2
{
    @Factory
  public Object[] factoryMethod() {
      return new Object[] { new SimpleTest2(1), new SimpleTest2(2) };
  }
}

All in all:

1. is this normal TestNG instantiate a test class that takes a single String as its constructor parameter with "Default test name" ?
2. is this normal one can't have 2 factory methods in the same factory class?
3. can you confirmed TestNG won't try to instantiate a test class as a standalone class when it's meant to be used (and is effectively used) by method annotated with @Factory ?

Thank you

Krishnan Mahadevan

unread,
Mar 7, 2015, 2:37:12 AM3/7/15
to testng...@googlegroups.com
Gregory

  1. is this normal TestNG instantiate a test class that takes a single String as its constructor parameter with "Default test name” ? [Krishnan ]- yes this is the expected behavior by TestNG. I don’t know the rationale behind why it is done this way, but looking at the codebase suggests that this is the expected behavior.
  2. is this normal one can't have 2 factory methods in the same factory class?  [Krishnan ]-- I don’t know of a rationale behind this but technically speaking, personally to me this makes sense. When TestNG inspects a class via reflection, it would work with the first factory method. So if there are two factory methods in a class and if its being executed via the plugin, how would TestNG know which one to use. So I guess from a technical standpoint this is working as expected.
  3. can you confirmed TestNG won't try to instantiate a test class as a standalone class when it's meant to be used (and is effectively used) by method annotated with @Factory ? [Krishnan ] - TestNG wouldn’t attempt to instantiate a standalone class meant to be used as a factory for producing test classes as long as you don’t attempt to right click it and execute it. Atleast this is my observation. If you right click a class and say Run as TestNG test, then you are basically instructing TestNG that the current class is what should be used by TestNG to be instantiated (via reflection of course) to decide on how to run it. 

Logically speaking if you would like to have a class not be instantiated via reflection and is meant to be just used as a place wherein all factory methods are to be housed, then you shouldn’t attempt at right clicking it and trying to run it.

Hope that helps .

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Technical Scribbings @ http://rationaleemotions.wordpress.com/


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to testng...@googlegroups.com.
Visit this group at http://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages