40

Does TestNG have something like @Rule? I am thinking specifically about:

@Rule public TemporaryFolder folder = ...

Or even

@Rule public MethodRule globalTimeout = new Timeout(20);

I am aware that I can manually implement these things using setUp() and tearDown() equivalents, but these don't give me the convenience that I get using @Rule.

Francisco
  • 3,980
  • 1
  • 23
  • 27
  • I found a discussion on the testng-dev google group and someone has implemented this feature. Here is the discussion: https://groups.google.com/forum/#!topic/testng-dev/RounLOTz_UU and the github repo with the feature: https://github.com/wolfs/testng-rules – Jaie Wilson Aug 01 '11 at 13:46

2 Answers2

6

Rules are pretty easy to emulate, for example with super classes:

public void Base {
  @BeforeMethod
  public void createTempDir() { ... }

  @AfterMethod
  public void deleteTempDir() { ... }
}

public void MyTest extends Base {
  @Test
  ...
}

If you extend Base, a temporary directory will always be automatically created and then deleted.

The advantage of this approach over Rules is that Rules are always class scoped, while with TestNG, you can implement them around methods, tests, classes, groups and even suites.

cheffe
  • 9,345
  • 2
  • 46
  • 57
Cedric Beust
  • 15,480
  • 2
  • 55
  • 55
  • 14
    Many thanks for the answer. But what I take from it is that _TestNG does not support an equivalent construction_. I know I can use _setUp()_-like and _tearDown()_-like methods to create a temporaryFolder or setting a timeout for every test in the class by annotating each method, but this misses the convenience of solving each of these issues with a single parameter declaration. – Francisco May 24 '11 at 09:05
  • 10
    ... not to mention that you can only have one super class in contrast to fields. Rules can be shared and composed, inheritence does not. – whiskeysierra Jul 26 '13 at 10:16
  • 15
    This is very naive. A popular test framework like TestNG should offer more! Problems come when you have many resources, and want them *all* to be closed cleanly. With @Rule, any exception thrown while closing a resource is automatically caught (tried it on JUnit 4.12) so that all of resource-closers can be executed. With @AfterMethod you need to do it by yourself, e.g with a chain of try/catch. See code example on gist http://git.io/vUNnM Conclusion: `@Rule` and `@AfterMethod` are NOT equivalent. BTW this is one of the reasons why I think that JUnit should be preferred over TestNG. – alb-i986 May 15 '15 at 14:08
  • 2
    In JUnit4 Rules can be class scope or method scope (with `@ClassRule`). A class rule can me used in a suite – NamshubWriter Jul 05 '15 at 16:11
  • 8
    The fun part here is that TestNG started as something to avoid having to subclass and just use annotations and now JUnit seems to be doing the better thing. – Wim Deblauwe Nov 23 '15 at 15:38
  • 1
    You have earned my down vote for the 'advantage over rules' part solely. It's just like saying 'prefer inheritance over composition'... – Artur Gajowy Jun 13 '16 at 10:03
0

BeforeClass/AfterClass of TestNG can simulate something like the rule/ruleClass of JUnit, but there are some functions and effects that these classes cannot replicate, such as: repeat, filter, etc.

However, there are some interfaces provided by TestNG that could be used to simulate these functions instead, e.g. IAnnotationTransformer, IMethodInterceptor.

Steve Lillis
  • 3,263
  • 5
  • 22
  • 41