public class MyTest {
private MyFixture myFixture = new ...
@Configurable(beforeTestClass=true)
public void setup() {
myFixture.setup();
}
@Configurable(afterTestClass=true)
public void teardown() {
myFixture.teardown();
}
...
}
But What I would really like to do is:
public class MyTest {
@Fixture
private MyFixture myFixture = new ...
...
}
Where the fixture's methods are annotated with the appropriate @Configurable.
I have yet to look at any of the testng source. Would such a thing be possible?
-barry
PS, Can I tag a code block in jive?
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33349#33349
Hi!
(pls check my previous answer about asking what is really a fixture). Than I cannot understand what
is the above scenario trying to do. Can you please detail?
As regards tagging code, I think you can use [ code ] [ / code ] (without spaces).
cheers,
./alex
--
.w( the_mindstorm )p.
So what I am trying to get is to not have to create @Configuration(befofe/after) methods in the test itself that do nothing other than delegate to the "fixture" methods. I'm looking for a more declarative style to say "please add this aspect of fixture to my test". I don't want to put this in a base test class, because then I'm back the old junit way of having a chain of base classes to add in all the test fixture aspects.
Ok, I think could support this myself using a single base class with before/after methods that scan the current test for variables annotated with @Fixture, and then scan that class for methods with @Configuration... But then I would be duplicating the code that already exists to detect these methods and add them to the ordered collection of configuration methods.
If I could find a way to get access to the test-result, then I could define a parameter-provider to poke in the test-result to the configuration method.
Well, since I'm just right now looking at the impl of testng, there may be lots of better ways that I will discover.
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33365#33365
Hmmm... I should probably re-read, but this smells pretty much of aop. Have you considered using
AspectJ for doing this? If you can provide some detailed example maybe we can look over it and see
what would be a solution for it. Also please let me know if AspectJ usage is not an option for you
or if I am seeing it used wrongly.
In Log4jTestFixture:
[code]
@Configuration(beforeSuite=true)
public void addAppender() {
LogManager.getRootLogger().removeAllAppenders();
LogManager.getRootLogger().addAppender(collectingAppender);
TestNG.getDefault().addListener(testListener);
}
@Configuration(beforeTestMethod=true)
public void redirectConsoleOutput() {
systemErr = System.err;
systemOut = System.out;
System.setErr(new PrintStream(new LoggingOutputStream(LogManager.getRootLogger(), Level.ERROR), true));
System.setOut(new PrintStream(new LoggingOutputStream(LogManager.getRootLogger(), Level.INFO), true));
}
@Configuration(afterTestMethod=true)
public void logFailedTests() {
System.setErr(systemErr);
System.setOut(systemOut);
if (testListener.isFailures() || alwaysPrintEvents) {
collectingAppender.printEvents();
}
collectingAppender.reset();
testListener.reset();
}
[/code]
And now in the concrete test:
[code]
@Test(groups="opentrader.samples")
public class SpringConfigurableTest {
...
private Log4jTestFixture log4jTestFixture = new Log4jTestFixture();
@Configuration(beforeSuite=true)
public void addAppender() {
log4jTestFixture.addAppender();
}
@Configuration(beforeTestMethod=true)
public void redirectConsoleOutput() {
log4jTestFixture.redirectConsoleOutput();
}
@Configuration(afterTestMethod=true)
public void logFailedTests() {
log4jTestFixture.logFailedTests();
}
...
}
[/code]
My test should not need to know about the details of how the log4j fixture works. And now as the fixture changes its implementation, each test will need to be updated.
I can create the base test class for all tests to implement, but really the annotations are there to remove that need.
Maybe I can inject the fixture as a parent of the test class, but I really don't use aspectj for unit tests -- I have 10k unit tests that currently run in about 30 seconds. I don't want to increase that to many minutes while aspectj weaves in the classes.
It would be much simpler and way faster for testng to recoginize something like @Fixture, and scan the objects methods for @Configurable and add them to the to the methods-to-run list.
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33376#33376
In Log4jTestFixture:
@Configuration(beforeSuite=true)
public void addAppender() {
LogManager.getRootLogger().removeAllAppenders();
LogManager.getRootLogger().addAppender(collectingAppender);
TestNG.getDefault().addListener(testListener);
}
@Configuration(beforeTestMethod=true)
public void redirectConsoleOutput() {
systemErr = System.err;
systemOut = System.out;
System.setErr(new PrintStream(new LoggingOutputStream(LogManager.getRootLogger(), Level.ERROR), true));
System.setOut(new PrintStream(new LoggingOutputStream(LogManager.getRootLogger(), Level.INFO), true));
}
@Configuration(afterTestMethod=true)
public void logFailedTests() {
System.setErr(systemErr);
System.setOut(systemOut);
if (testListener.isFailures() || alwaysPrintEvents) {
collectingAppender.printEvents();
}
collectingAppender.reset();
testListener.reset();
}
And now in the concrete test:
@Test(groups="opentrader.samples")
public class SpringConfigurableTest {
...
private Log4jTestFixture log4jTestFixture = new Log4jTestFixture();
@Configuration(beforeSuite=true)
public void addAppender() {
log4jTestFixture.addAppender();
}
@Configuration(beforeTestMethod=true)
public void redirectConsoleOutput() {
log4jTestFixture.redirectConsoleOutput();
}
@Configuration(afterTestMethod=true)
public void logFailedTests() {
log4jTestFixture.logFailedTests();
}
...
}
My test should not need to know about the details of how the log4j fixture works. And now as the fixture changes its implementation, each test will need to be updated.
I can create the base test class for all tests to implement, but really the annotations are there to remove that need.
Maybe I can inject the fixture as a parent of the test class, but I really don't use aspectj for unit tests -- I have 10k unit tests that currently run in about 30 seconds. I don't want to increase that to many minutes while aspectj weaves in the classes.
It would be much simpler and way faster for testng to recoginize something like @Fixture, and scan the objects methods for @Configurable and add them to the to the methods-to-run list.
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33377#33377
If I read it correctly, are you saying that you think runtime analysis/logic will be more rapid than
a compile time or even ltw aspectj step? This is making me really curious :-).
On the other hand your example would be extremely simple in AspectJ ;-).
1/ you declare the test as implementing a Log4jTestFixture interface
2/ you provide the default implementation of Log4jTestFixture
But the problem would be that the annotations are not inheritable, so this would probably not work :-).
Right now it's quite late, so I will think about this interesting problem tomorrow.
cheers,
I think I might have an idea of how to solve this, but I might as well be wrong :-)
What if you test class declares a @Configuration method that depends on a group. And this group
would be defined in your external fixture.
Would this solve your scenario?
Hmm, this sounds clean. If the @Test on the class can define a depends-on-group that would be even cooler. I'll give this a try and see how it works -- should be great.
thanks!
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33698#33698
I added enabled=false to each method, but the fixture methods are not being invoked. (Don't know why yet. I'm still experimenting.)
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33838#33838
One problem with the approach is that I cannot set @Configuration at the class level
requiring me to annotate the fixture with @Test. But that class has gobs of public helper methods which testng then wants to run.
I added enabled=false to each method, but the fixture methods are not being invoked. (Don't know why yet. I'm still experimenting.)
Yes, but if I could set @Configuration instead of @Test then at least I wouldn't have to specify @Test(enabled=false) for all non-configuration methods.
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=33882#33882
I am not sure I am following you. The @Configuration must be used at method level. And I don't see
the reason why you need to put @Test at class level. Can you detail why you need this?
>> > One problem with the approach is that I cannot set
> @Configuration at the
> > class level
>
> Correct, that wouldn't make a lot of sense since you
> still need to specify
> before/after attributes on each individual methods
> anyway.
Yes, but if I could set @Configuration instead of @Test then at least I wouldn't have to specify @Test(enabled=false) for all non-configuration methods.
@Target(java.lang.annotation.ElementType.METHOD)
public @interface Configuration {
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=34038#34038
That was exactly what I've said. Still I don't understand the need for @Test in your fixture. Or
maybe I just missed the meaning of the latest mails in the thread.
But, since I am trying to build a fixture that does some arbitrary configuration (for log4j in the current case) I would like to be able to specify the group once-and-only-once. And that would mean in the @Configuration at the class level. But if I need to repeat the group for method, no big deal.
-barry
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=34163#34163
Ah, I think I see now. I thought that testng would scan all files in the classpath for files marked with @Configuration/Test. But that is not the case, so as long as I add the class to the testng.xml then the methods will be scanned for annotations (no?).
But, since I am trying to build a fixture that does some arbitrary configuration (for log4j in the current case) I would like to be able to specify the group once-and-only-once. And that would mean in the @Configuration at the class level. But if I need to repeat the group for method, no big deal.
On getting the fixture the run by expliciting listing the test-class and fixture-class in using <classes> in the testng.xml:
The log4-jfixture has:
@Configuration(beforeSuite=true, groups="fixture.log4j")
public void addAppender() { ... }
@Configuration(beforeTestMethod=true, groups="fixture.log4j")
public void redirectConsoleOutput() { ... }
@Configuration(afterTestMethod=true, groups="fixture.log4j")
public void logFailedTests() { ... }
All of these methods are noops right now.
In the test-class I have:
@Test(groups="opentrader.samples", dependsOnGroups="fixture.log4j")
public class LingoSample { ...}
My test methods always get skipped, but even with logging set to 10 I can't seem to figure out why. Below is the output. Any clues would be appreciated.
----
[RunInfo] Adding method selector: org.testng.internal.XmlMethodSelector@cf2c80 priority: 10
[TestClass] Creating TestClass for [ClassImpl org.opentrader.platform.samples.lingo.clientserver.LingoSample]
[TestClass] Adding method org.opentrader.platform.samples.lingo.clientserver.LingoSample.runClient() on TestClass class org.opentrader.platform.samples.lingo.clientserver.LingoSample
[TestClass] Creating TestClass for [ClassImpl org.opentrader.itest.Log4jTestFixture]
[RunInfo] Adding method selector: org.testng.internal.XmlMethodSelector@b166b5 priority: 10
[TestClass] Creating TestClass for [ClassImpl org.opentrader.platform.samples.lingo.clientserver.LingoSample]
[TestClass] Adding method org.opentrader.platform.samples.lingo.clientserver.LingoSample.runClient() on TestClass class org.opentrader.platform.samples.lingo.clientserver.LingoSample
[Invoker 16416372] Invoking org.opentrader.itest.Log4jTestFixture.addAppender()
[Invoker 16416372] Invoking org.opentrader.platform.samples.lingo.clientserver.LingoSample.startServer(java.lang.String)
[TestRunner] Running test Single Service on 2 classes, included groups:[] excluded groups:[]
[TestClass]
======
TESTCLASS: org.opentrader.platform.samples.lingo.clientserver.LingoSample
[TestClass] Test : org.opentrader.platform.samples.lingo.clientserver.LingoSample.runClient()
[TestClass]
======
[TestClass]
======
TESTCLASS: org.opentrader.itest.Log4jTestFixture
[TestClass] BeforeMethod: org.opentrader.itest.Log4jTestFixture.redirectConsoleOutput()
[TestClass] AfterMethod : org.opentrader.itest.Log4jTestFixture.logFailedTests()
[TestClass]
======
[TestRunner] PARALLEL LIST:
[TestRunner] SEQUENTIAL LIST:
[TestRunner] org.opentrader.platform.samples.lingo.clientserver.LingoSample.runClient()
[TestRunner] ===
[TestRunner] Found 1 applicable methods
*********** INVOKED METHODS
***********
SKIPPED: runClient
===============================================
Single Service
Tests run: 1, Failures: 0, Skips: 1
===============================================
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=34315#34315
I don't fully understand the Runner control flow just yet, but...
By the time the Runner gets to Invoker.checkDependencies, which does
if (testMethod.getMissingGroup() != null) {
return false;
}
The group "fixture.log4j" is considered missing. Is this because the Log4jFixture class is not @Test, but only has @Configuration methods?
Message was edited by:
Barry Kaplan
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=34338#34338
As a quick test: can you include in the Fixture class a fake/empty @Test method and try it again?
Does <package> exists now? I don't see it in the docs or with any example.
On getting the fixture the run by expliciting listing the test-class and fixture-class in using <classes> in the testng.xml:
The log4-jfixture has:
@Configuration(beforeSuite=true, groups="fixture.log4j")
public void addAppender() { ... }
@Configuration(beforeTestMethod=true, groups=" fixture.log4j")
public void redirectConsoleOutput() { ... }
@Configuration(afterTestMethod=true, groups="fixture.log4j")
public void logFailedTests() { ... }
All of these methods are noops right now.
In the test-class I have:
@Test(groups="opentrader.samples", dependsOnGroups="fixture.log4j")
public class LingoSample { ...}
My test methods always get skipped, but even with logging set to 10 I can't seem to figure out why. Below is the output. Any clues would be appreciated.
@Test(groups={"opentrader.samples", "fixture.log4j"})
public class LingoSample { ... }
Thank you very much Alex and Cedric for all the help.
-barry
PS. If anybody else reading this thread does not understand what I've been trying to do (and would like understand) let me know and I will either create a standalone example and/or add this topic my pending blog topics.
---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=16977&messageID=34592#34592
PS. If anybody else reading this thread does not understand what I've been trying to do (and would like understand) let me know and I will either create a standalone example and/or add this topic my pending blog topics.